blob: e993eb903054f7e640ccc08b2b12e41421937bc4 [file] [log] [blame]
brians343bc112013-02-10 01:53:46 +00001class MessageElementStmt < QStmt
2 attr_accessor :name
3 def initialize(type,name,length = nil) #lengths are for arrays
4 @type = type
5 @name = name
6 @length = length
7 end
8 CommonMistakes = {"short" => "int16_t","int" => "int32_t","long" => "int64_t"}
9 def check_type_error()
10 if(!(Sizes[@type] || (@length != nil && @type == "char")) )
11 if(correction = CommonMistakes[@type])
12 raise QError.new(<<ERROR_MSG)
13Hey! you have a \"#{@type}\" in your message statement.
14\tplease use #{correction} instead. Your type is not supported because we
15\twant to guarantee that the sizes of the messages stay the same across platforms.
16\tWot. Wot.
17ERROR_MSG
18 elsif(@type == "char")
19 raise QError.new(<<ERROR_MSG)
20Hey! you have a \"#{@type}\" in your message statement.
21\tyou need your declaration to be a char array like: char[10].
22\tor, please use int8_t or uint8_t.
23\tWot. Wot.
24ERROR_MSG
25 else
26 raise QError.new(<<ERROR_MSG)
27Hey! you have a \"#{@type}\" in your message statement.
28\tThat is not in the list of supported types.
29\there is the list of supported types:
30\tint{8,16,32,64}_t,uint{8,16,32,64}_t,bool,float,double#{len_comment}
31\tWot. Wot.
32ERROR_MSG
33 end
34 end
35 end
36
37 PrintFormat = {"bool" => "%c",
38 "float" => "%f",
39 "char" => "%c",
40 "double" => "%f",
Brian Silverman8efe23e2013-07-07 23:31:37 -070041 "uint8_t" => "%\" PRIu8 \"",
42 "uint16_t" => "%\" PRIu16 \"",
43 "uint32_t" => "%\" PRIu32 \"",
44 "uint64_t" => "%\" PRIu64 \"",
45 "int8_t" => "%\" PRId8 \"",
46 "int16_t" => "%\" PRId16 \"",
47 "int32_t" => "%\" PRId32 \"",
48 "int64_t" => "%\" PRId64 \""}
brians343bc112013-02-10 01:53:46 +000049 def toPrintFormat()
50 if(format = PrintFormat[@type])
51 return format;
52 end
53 raise QError.new(<<ERROR_MSG)
54Somehow this slipped past me, but
55\tI couldn't find the print format of #{@type}. Really, my bad.
56\tWot. Wot.
57ERROR_MSG
58 end
59
60 Sizes = {"bool" => 1, "float" => 4,"double" => 8}
61 [8,16,32,64].each do |len|
62 Sizes["int#{len}_t"] = len / 8
63 Sizes["uint#{len}_t"] = len / 8
64 end
65 Zero = {"float" => "0.0f","double" => "0.0","bool" => "false"}
66 def size()
67 if(size = Sizes[@type]); return size; end
68 return 1 if(@type == "char")
69 raise QError.new(<<ERROR_MSG)
70Somehow this slipped past me, but
71\tI couldn't find the size of #{@type}. Really, my bad.
72\tWot. Wot.
73ERROR_MSG
74 end
75 def q_eval(locals)
76 check_type_error()
77 if(@length == nil)
78 member = Target::MessageElement.new(@type,@name)
79 else
80 member = Target::MessageArrayElement.new(@type,@name,@length)
81 end
82 member.size = size()
83 member.zero = Zero[@type] || "0";
84 member.printformat = toPrintFormat()
85 locals.local.add_member(member)
86 end
87 def self.parse(tokens)
88 line = tokens.pos
89 type = tokens.expect(:tWord).data
90 len = nil
91 if(tokens.peak == :tOpenB)
92 tokens.expect(:tOpenB)
93 len = tokens.expect(:tNumber).data
94 tokens.expect(:tCloseB)
95 end
96 name = tokens.expect(:tWord).data
97 tokens.expect(:tSemi)
98 return self.new(type,name,len).set_line(line)
99 end
100end
101class MessageStmt < QStmt
102 def initialize(name,suite)
103 @name = name
104 @suite = suite
105 end
106 def q_eval(locals)
107 group = Target::MessageDec.new(@name)
108 locals.register(group)
109 @suite.each do |stmt|
110 stmt.q_eval(locals.bind(group))
111 end
112 return group
113 end
114 def self.parse(tokens)
115 name = tokens.expect(:tWord).data
116 values = []
117 tokens.expect(:tOpenB)
118 while(tokens.peak != :tCloseB)
119 values << MessageElementStmt.parse(tokens)
120 end
121 names = {}
122 values.each do |val|
123 if(names[val.name])
124 raise QSyntaxError.new(<<ERROR_MSG)
125Hey! duplicate name #{val.name.inspect} in your message declaration statement (message #{name}).
126\tI found them at: #{names[val.name].q_stack_name()} and #{val.q_stack_name()}.
127\tWot. Wot.
128ERROR_MSG
129 end
130 names[val.name] = val
131 end
132 tokens.expect(:tCloseB)
133 tokens.expect(:tSemi)
134 self.new(name,values)
135 end
136end
137class QueueStmt < QStmt
138 def initialize(type,name)
139 @type,@name = type,name
140 end
141 def q_eval(locals)
142 queue = Target::QueueDec.new(@type.lookup(locals),@name)
143 locals.register(queue)
144 locals.local.add_queue(queue) if(locals.local.respond_to?(:add_queue))
145 return queue
146 end
147 def self.parse(tokens)
148 line = tokens.pos
149 type_name = QualifiedName.parse(tokens)
150 name = tokens.expect(:tWord).data
151 tokens.expect(:tSemi)
152 return self.new(type_name,name).set_line(line)
153 end
154end