added support for structures in q syntax.
diff --git a/aos/build/queues/compiler.rb b/aos/build/queues/compiler.rb
index 28e206b..ffee5d3 100644
--- a/aos/build/queues/compiler.rb
+++ b/aos/build/queues/compiler.rb
@@ -1,12 +1,13 @@
+$LOAD_PATH.unshift(".")
 ["tokenizer.rb","q_file.rb","queue_group.rb","queue.rb","namespaces.rb",
-"interface.rb","errors.rb"].each do |name|
+"interface.rb","errors.rb", "q_struct.rb"].each do |name|
 	require File.dirname(__FILE__) + "/objects/" + name
 end
 ["standard_types.rb","auto_gen.rb","file_pair_types.rb",
 "dep_file_pair.rb","swig.rb"].each do |name|
 	require File.dirname(__FILE__) + "/cpp_pretty_print/" + name
 end
-["q_file.rb","message_dec.rb","queue_dec.rb"].each do |name|
+["q_file.rb","message_dec.rb","queue_dec.rb", "q_struct.rb"].each do |name|
 	require File.dirname(__FILE__) + "/output/" + name
 end
 require "fileutils"
diff --git a/aos/build/queues/objects/namespaces.rb b/aos/build/queues/objects/namespaces.rb
index b799d36..74f7197 100644
--- a/aos/build/queues/objects/namespaces.rb
+++ b/aos/build/queues/objects/namespaces.rb
@@ -43,7 +43,7 @@
 end
 class BoundSituation < LocalSituation
 	def initialize(locals,bind_to)
-		@globals = globals
+		@globals = locals.globals
 		@local = bind_to
 	end
 end
diff --git a/aos/build/queues/objects/q_file.rb b/aos/build/queues/objects/q_file.rb
index f683dda..beaf8f0 100644
--- a/aos/build/queues/objects/q_file.rb
+++ b/aos/build/queues/objects/q_file.rb
@@ -134,6 +134,8 @@
 				suite << QueueStmt.parse(tokens)
 			when "interface"
 				suite << InterfaceStmt.parse(tokens)
+			when "struct"
+				suite << StructStmt.parse(tokens)
 			else
 				tokens.qError(<<ERROR_MSG)
 expected a "package","import","queue","queue_group", or "message" statement rather
diff --git a/aos/build/queues/objects/q_struct.rb b/aos/build/queues/objects/q_struct.rb
new file mode 100644
index 0000000..cd47fe6
--- /dev/null
+++ b/aos/build/queues/objects/q_struct.rb
@@ -0,0 +1,37 @@
+
+class StructStmt 
+	def initialize(name,suite)
+		@name = name
+		@suite = suite
+	end
+	def q_eval(locals)
+		group = Target::StructDec.new(@name)
+		locals.register(group)
+		@suite.each do |stmt|
+			stmt.q_eval(locals.bind(group))
+		end 
+		return group
+	end
+	def self.parse(tokens)
+		name = tokens.expect(:tWord).data
+		values = []
+		tokens.expect(:tOpenB)
+		while(tokens.peak != :tCloseB)
+			values << MessageElementStmt.parse(tokens)
+		end
+		names = {}
+		values.each do |val|
+			if(names[val.name])
+				raise QSyntaxError.new(<<ERROR_MSG)
+Hey! duplicate name #{val.name.inspect} in your message declaration statement (message #{name}).
+\tI found them at: #{names[val.name].q_stack_name()} and #{val.q_stack_name()}.
+\tWot. Wot.
+ERROR_MSG
+			end
+			names[val.name] = val
+		end
+		tokens.expect(:tCloseB)
+		tokens.expect(:tSemi)
+		self.new(name,values)
+	end
+end
diff --git a/aos/build/queues/objects/queue.rb b/aos/build/queues/objects/queue.rb
index e993eb9..1199cc2 100644
--- a/aos/build/queues/objects/queue.rb
+++ b/aos/build/queues/objects/queue.rb
@@ -1,12 +1,13 @@
 class MessageElementStmt < QStmt
 	attr_accessor :name
-	def initialize(type,name,length = nil) #lengths are for arrays
-		@type = type
+	def initialize(type_name,name,length = nil) #lengths are for arrays
+		@type_name = type_name
+		@type = type_name.to_s
 		@name = name
 		@length = length
 	end
 	CommonMistakes = {"short" => "int16_t","int" => "int32_t","long" => "int64_t"}
-	def check_type_error()
+	def check_type_error(locals)
 		if(!(Sizes[@type] || (@length != nil && @type == "char")) )
 			if(correction = CommonMistakes[@type])
 				raise QError.new(<<ERROR_MSG)
@@ -23,11 +24,13 @@
 \tWot. Wot.
 ERROR_MSG
 			else
+				@is_struct_type = true
+				return if(lookup_type(locals))
 				raise QError.new(<<ERROR_MSG)
 Hey! you have a \"#{@type}\" in your message statement.
 \tThat is not in the list of supported types.
 \there is the list of supported types:
-\tint{8,16,32,64}_t,uint{8,16,32,64}_t,bool,float,double#{len_comment}
+\tint{8,16,32,64}_t,uint{8,16,32,64}_t,bool,float,double
 \tWot. Wot.
 ERROR_MSG
 			end
@@ -72,21 +75,30 @@
 \tWot. Wot.
 ERROR_MSG
 	end
+	def lookup_type(locals)
+		return @type_name.lookup(locals)
+	end
 	def q_eval(locals)
-		check_type_error()
-		if(@length == nil)
-			member = Target::MessageElement.new(@type,@name)
+		check_type_error(locals)
+		if(@is_struct_type)
+			tval = lookup_type(locals)
+			member = Target::MessageStructElement.new(tval, name)
 		else
-			member = Target::MessageArrayElement.new(@type,@name,@length)
+			if(@length == nil)
+				member = Target::MessageElement.new(@type,@name)
+			else
+				member = Target::MessageArrayElement.new(@type,@name,@length)
+			end
+			member.size = size()
+			member.zero = Zero[@type] || "0";
+			member.printformat = toPrintFormat()
 		end
-		member.size = size()
-		member.zero = Zero[@type] || "0";
-		member.printformat = toPrintFormat()
 		locals.local.add_member(member)
 	end
 	def self.parse(tokens)
 		line = tokens.pos
-		type = tokens.expect(:tWord).data
+		#type = tokens.expect(:tWord).data
+		type_name = QualifiedName.parse(tokens)
 		len = nil
 		if(tokens.peak == :tOpenB)
 			tokens.expect(:tOpenB)
@@ -95,7 +107,7 @@
 		end
 		name = tokens.expect(:tWord).data
 		tokens.expect(:tSemi)
-		return self.new(type,name,len).set_line(line)
+		return self.new(type_name,name,len).set_line(line)
 	end
 end
 class MessageStmt < QStmt
diff --git a/aos/build/queues/output/message_dec.rb b/aos/build/queues/output/message_dec.rb
index 3b89149..579ce0c 100644
--- a/aos/build/queues/output/message_dec.rb
+++ b/aos/build/queues/output/message_dec.rb
@@ -34,17 +34,13 @@
 		@members.each do |elem|
 			format += ", "
 			format += elem.toPrintFormat()
-			if (elem.type == 'bool')
-				args.push("#{elem.name} ? 'T' : 'f'")
-			else
-				args.push(elem.name)
-			end
+			elem.fetchPrintArgs(args)
 		end
-                format += "\""
-                member_func.suite << "size_t super_size = ::aos::Message::Print(buffer, length)"
-                member_func.suite << "buffer += super_size"
-                member_func.suite << "length -= super_size"
-                member_func.suite << "return super_size + snprintf(buffer, length, " + ([format] + args).join(", ") + ")";
+    format += "\""
+    member_func.suite << "size_t super_size = ::aos::Message::Print(buffer, length)"
+    member_func.suite << "buffer += super_size"
+    member_func.suite << "length -= super_size"
+    member_func.suite << "return super_size + snprintf(buffer, length, " + ([format] + args).join(", ") + ")";
 	end
 	def create_Serialize(type_class,cpp_tree)
 		member_func = CPP::MemberFunc.new(type_class,"size_t","Serialize")
@@ -221,26 +217,33 @@
 	def create_usage(cpp_tree)
 		"#{@type} #{@name}"
 	end
-	def toNetwork(offset,suite)
+	def toNetwork(offset,suite, parent = "")
 		offset = (offset == 0) ? "" : "#{offset} + "
 		suite << f_call = CPP::FuncCall.build("to_network",
-									 "&#{@name}",
+									 "&#{parent}#{@name}",
 									 "&buffer[#{offset}::aos::Message::Size()]")
 		f_call.args.dont_wrap = true
 	end
-	def toHost(offset,suite)
+	def toHost(offset,suite, parent = "")
 		offset = (offset == 0) ? "" : "#{offset} + "
 		suite << f_call = CPP::FuncCall.build("to_host",
 									 "&buffer[#{offset}::aos::Message::Size()]",
-									 "&#{@name}")
+									 "&#{parent}#{@name}")
 		f_call.args.dont_wrap = true
 	end
 	def set_message_builder(suite)
 		suite << "msg_ptr_->#{@name} = #{@name}"
 	end
 
-	def zeroCall(suite)
-		suite << CPP::Assign.new(@name,@zero)
+	def zeroCall(suite, parent = "")
+		suite << CPP::Assign.new(parent + @name,@zero)
+	end
+	def fetchPrintArgs(args, parent = "")
+		if (self.type == 'bool')
+			args.push("#{parent}#{self.name} ? 'T' : 'f'")
+		else
+			args.push("#{parent}#{self.name}")
+		end
 	end
 end
 class Target::MessageArrayElement < Target::Node
diff --git a/aos/build/queues/output/q_file.rb b/aos/build/queues/output/q_file.rb
index 5e016c0..1ef47a4 100644
--- a/aos/build/queues/output/q_file.rb
+++ b/aos/build/queues/output/q_file.rb
@@ -8,6 +8,13 @@
 end
 class Target::Node
 	attr_accessor :created_by
+	def get_name()
+		if(@parent)
+			return "#{@parent.get_name}.#{@name}"
+		else
+			return "#{@name}"
+		end 
+	end
 end
 class Target::QFile < Target::Node
 	def initialize() #needs to know repo_path, 
diff --git a/aos/build/queues/output/q_struct.rb b/aos/build/queues/output/q_struct.rb
new file mode 100644
index 0000000..12276ad
--- /dev/null
+++ b/aos/build/queues/output/q_struct.rb
@@ -0,0 +1,104 @@
+class Target::StructDec < Target::Node
+	attr_accessor :name,:loc,:parent, :extern
+	def initialize(name)
+		@name = name
+		@members = []
+	end
+	def [](key)
+		return nil
+	end
+	def add_member(member)
+		@members << member
+	end
+	def create(cpp_tree)
+		return self if(@extern)
+		orig_namespace = namespace = cpp_tree.get(@loc)
+		name = ""
+		if(namespace.class < Types::Type) #is nested
+			name = namespace.name + "_" + name
+			namespace = namespace.space
+		end
+		type_class = namespace.add_struct(name + @name)
+
+		@members.each do |elem|
+			type_class.add_member(elem.create_usage(cpp_tree))
+		end
+		return type_class
+	end
+	def size()
+		return @size if(@size)
+		@size = 0
+		@members.each do |elem|
+			@size += elem.size
+		end
+		return @size
+	end
+	def getPrintFormat()
+		return "{" + @members.collect { |elem| elem.toPrintFormat() }.join(", ") + "}"
+	end
+	def fetchPrintArgs(args, parent = "")
+		@members.each do |elem|
+			elem.fetchPrintArgs(args, parent)
+		end
+	end
+	def toHost(offset, suite, parent)
+		@members.each do |elem|
+			elem.toHost(offset, suite, parent)
+			offset += elem.size()
+		end
+	end
+	def toNetwork(offset, suite, parent)
+		@members.each do |elem|
+			elem.toNetwork(offset, suite, parent)
+			offset += elem.size()
+		end
+	end
+	def zeroCall(suite, parent)
+		@members.each do |elem|
+			elem.zeroCall(suite, parent)
+		end
+	end
+end
+class Target::MessageStructElement < Target::Node
+	attr_accessor :name,:loc
+	def initialize(type,name)
+		@type, @name = type, name
+	end
+	def type()
+		return @type.get_name
+	end
+	def type_name(cpp_tree)
+		type = cpp_tree.get(@type)
+		if(@type.loc == @loc) #use relative name
+			return type.name
+		else #use full name
+			return @type.loc.to_cpp_id(type.name)
+		end 
+	end
+	def size()
+		return @type.size()
+	end
+	def toPrintFormat()
+		@type.getPrintFormat()
+	end
+	def create_usage(cpp_tree)
+		return "#{type_name(cpp_tree)} #{@name}"
+	end
+	def fetchPrintArgs(args, parent = "")
+		@type.fetchPrintArgs(args, parent + "#{@name}.")
+	end
+	def toNetwork(offset,suite, parent = "")
+		@type.toNetwork(offset, suite, parent + "#{@name}.")
+	end
+	def toHost(offset,suite, parent = "")
+		@type.toHost(offset, suite, parent + "#{@name}.")
+	end
+	def set_message_builder(suite)
+		suite << "msg_ptr_->#{@name} = #{@name}"
+	end
+
+	def zeroCall(suite, parent = "")
+		@type.zeroCall(suite, parent + "#{@name}.")
+	end
+	
+end
diff --git a/aos/build/queues/q_specs/nested_structs.q b/aos/build/queues/q_specs/nested_structs.q
new file mode 100644
index 0000000..7162620
--- /dev/null
+++ b/aos/build/queues/q_specs/nested_structs.q
@@ -0,0 +1,12 @@
+package aos.test;
+
+import "q_specs/struct_test.q";
+
+
+message Position {
+	int32_t a;
+	int32_t[2] b;
+	.aos.test2.ClawHalfPosition top;
+	.aos.test2.ClawHalfPosition bottom;
+	bool c;
+};
diff --git a/aos/build/queues/q_specs/struct_test.q b/aos/build/queues/q_specs/struct_test.q
new file mode 100644
index 0000000..afb22ac
--- /dev/null
+++ b/aos/build/queues/q_specs/struct_test.q
@@ -0,0 +1,12 @@
+package aos.test2;
+
+struct SubStruct {
+	int32_t g;
+};
+
+struct ClawHalfPosition {
+	double position; 
+	bool hall_effect;
+	SubStruct clampy;
+};
+