[270] | 1 | # -*- coding: utf-8 -*-
|
---|
| 2 | #
|
---|
| 3 | # TECS Generator
|
---|
| 4 | # Generator for TOPPERS Embedded Component System
|
---|
| 5 | #
|
---|
| 6 | # Copyright (C) 2008-2016 by TOPPERS Project
|
---|
| 7 | #--
|
---|
| 8 | # ä¸è¨èä½æ¨©è
|
---|
| 9 | ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
|
---|
| 10 | # ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ã使ç¨ã»è¤è£½ã»æ¹
|
---|
| 11 | # å¤ã»åé
|
---|
| 12 | å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
|
---|
| 13 | # (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
|
---|
| 14 | # 権表示ï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
|
---|
| 15 | # ã¹ã³ã¼ãä¸ã«å«ã¾ãã¦ãããã¨ï¼
|
---|
| 16 | # (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
|
---|
| 17 | # ç¨ã§ããå½¢ã§åé
|
---|
| 18 | å¸ããå ´åã«ã¯ï¼åé
|
---|
| 19 | å¸ã«ä¼´ãããã¥ã¡ã³ãï¼å©ç¨
|
---|
| 20 | # è
|
---|
| 21 | ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
|
---|
| 22 | # ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
|
---|
| 23 | # (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
|
---|
| 24 | # ç¨ã§ããªãå½¢ã§åé
|
---|
| 25 | å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
|
---|
| 26 | # ã¨ï¼
|
---|
| 27 | # (a) åé
|
---|
| 28 | å¸ã«ä¼´ãããã¥ã¡ã³ãï¼å©ç¨è
|
---|
| 29 | ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
|
---|
| 30 | # ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
|
---|
| 31 | # (b) åé
|
---|
| 32 | å¸ã®å½¢æ
|
---|
| 33 | ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSããã¸ã§ã¯ãã«
|
---|
| 34 | # å ±åãããã¨ï¼
|
---|
| 35 | # (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
|
---|
| 36 | # 害ãããï¼ä¸è¨èä½æ¨©è
|
---|
| 37 | ããã³TOPPERSããã¸ã§ã¯ããå
|
---|
| 38 | 責ãããã¨ï¼
|
---|
| 39 | # ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
|
---|
| 40 | # ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
|
---|
| 41 | ããã³TOPPERSããã¸ã§ã¯ãã
|
---|
| 42 | # å
|
---|
| 43 | 責ãããã¨ï¼
|
---|
| 44 | #
|
---|
| 45 | # æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
|
---|
| 46 | ã
|
---|
| 47 | # ãã³TOPPERSããã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
|
---|
| 48 | # ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
|
---|
| 49 | # ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ害ã«é¢ãã¦ãï¼ã
|
---|
| 50 | # ã®è²¬ä»»ãè² ããªãï¼
|
---|
| 51 | #
|
---|
| 52 | # $Id: syntaxobj.rb 1011 2016-07-11 02:20:01Z coas-nagasima $
|
---|
| 53 | #++
|
---|
| 54 |
|
---|
| 55 | # mikan ruby ã® symbol ã¨æååã®ä½¿ãåããã©ããã¦ããã¾ããããªããã¨ãæã
|
---|
| 56 | ããã®ã§ name.to_sym ãå
|
---|
| 57 | ¥ãããã¨ã«ãã
|
---|
| 58 |
|
---|
| 59 | #== Node
|
---|
| 60 | #
|
---|
| 61 | # Node ã®ç´æ¥ã®åã¯ã©ã¹ï¼ C_EXP, Type, BaseVal, BDNode(ã»ã¨ãã©ã®ãã®ã¯ BDNode ã®åã¯ã©ã¹)
|
---|
| 62 | # Node ã« (BDNodeã«ã) å
|
---|
| 63 | ¥ããªããã®: Token, Import, Import_C, Generate
|
---|
| 64 | #
|
---|
| 65 | # owner ãæããªããã®ã Node ã¨ãªã
|
---|
| 66 | # ã¨ã©ã¼ã¯ãcdl_error ãéãã¦å ±åãã (æå³è§£æãæ§æ解æå¾ã«è¡ãããå ´åã«ã¯ãè¡çªå·ãæ£ããåºåã§ãã
|
---|
| 67 | #
|
---|
| 68 |
|
---|
| 69 | class Node
|
---|
| 70 | #@locale:: [@file, @lineno, @col]
|
---|
| 71 |
|
---|
| 72 | def initialize
|
---|
| 73 | @locale = Generator.current_locale
|
---|
| 74 | end
|
---|
| 75 |
|
---|
| 76 | #=== ã¨ã©ã¼ãåºåãã
|
---|
| 77 | def cdl_error( message, *arg )
|
---|
| 78 | Generator.error2( @locale, message, *arg )
|
---|
| 79 | end
|
---|
| 80 |
|
---|
| 81 | #=== ã¨ã©ã¼ãåºåãã
|
---|
| 82 | #locale:: Array(locale info) : æ§æ解æä¸ã¯ç¡è¦ããã
|
---|
| 83 | def cdl_error2( locale, message, *arg )
|
---|
| 84 | Generator.error2( locale, message, *arg )
|
---|
| 85 | end
|
---|
| 86 |
|
---|
| 87 | #=== ã¨ã©ã¼ãåºåãã
|
---|
| 88 | #locale:: Array(locale info)
|
---|
| 89 | # æ§æ解æä¸ cdl_error2 ã§ã¯ locale ãç¡è¦ããããããå¥ã« locale ãåºåãã
|
---|
| 90 | def cdl_error3( locale, message, *arg )
|
---|
| 91 | Generator.error( message, *arg )
|
---|
| 92 | Console.puts "check: #{locale[0]}: line #{locale[1]} for above error"
|
---|
| 93 | end
|
---|
| 94 |
|
---|
| 95 | #=== ã¦ã©ã¼ãã³ã°åºåãã
|
---|
| 96 | def cdl_warning( message, *arg )
|
---|
| 97 | Generator.warning2( @locale, message, *arg )
|
---|
| 98 | end
|
---|
| 99 |
|
---|
| 100 | #=== ã¦ã©ã¼ãã³ã°åºåãã
|
---|
| 101 | def cdl_warning2( locale, message, *arg )
|
---|
| 102 | Generator.warning2( locale, message, *arg )
|
---|
| 103 | end
|
---|
| 104 |
|
---|
| 105 | #=== æ
|
---|
| 106 | å ±ã表示ãã
|
---|
| 107 | def cdl_info( message )
|
---|
| 108 | Console.puts "info: #{message}"
|
---|
| 109 | end
|
---|
| 110 |
|
---|
| 111 | def get_locale
|
---|
| 112 | @locale
|
---|
| 113 | end
|
---|
| 114 |
|
---|
| 115 | def set_locale locale
|
---|
| 116 | @locale = locale
|
---|
| 117 | end
|
---|
| 118 |
|
---|
| 119 | def locale_str
|
---|
| 120 | "locale=( #{@locale[0]}, #{@locale[1]} )"
|
---|
| 121 | end
|
---|
| 122 | end
|
---|
| 123 |
|
---|
| 124 | #== åæ¹å Node (Bi Direction Node)
|
---|
| 125 | #
|
---|
| 126 | # Node ã®åã¯ã©ã¹
|
---|
| 127 | # owner Node ããåç
|
---|
| 128 | §ããã¦ãããã® (owner ã¸ã®ãªã³ã¯ãåãåºãã)
|
---|
| 129 | #
|
---|
| 130 | # get_owner ã§å¾ããããã®
|
---|
| 131 | # FuncHead => Signature
|
---|
| 132 | # Decl => Namespace(const), Typedef(typedef),
|
---|
| 133 | # Celltype, CompositeCelltype(attr,var)
|
---|
| 134 | # Struct(member), ParamDecl(parameter), FuncHead(funchead)
|
---|
| 135 | # Signature, Celltype, CompositeCelltype, Typedef => Namespace
|
---|
| 136 | #, Namespace => Namespace, Generator.class (root Namespace ã®å ´å)
|
---|
| 137 | # Cell => Region, CompositeCelltype(in_composite)
|
---|
| 138 | # Port => Celltype, Composite
|
---|
| 139 | # Factory => Celltype
|
---|
| 140 | # Join => Cell
|
---|
| 141 | # CompositeCelltypeJoin => CompositeCelltype
|
---|
| 142 | # Region => Region,
|
---|
| 143 | # ParamDecl => ParamList
|
---|
| 144 | # ParamList => FuncHead
|
---|
| 145 | # Expression => Namespace
|
---|
| 146 | # 大åã®ãã®ã¯ new_* ã¡ã½ãã㧠owner Node ã«ä¼éããã
|
---|
| 147 | # ãã®ã¡ã½ãããå¼ã³åºãããã¨ãã« owner Node ãè¨é²ããã
|
---|
| 148 | # new_* ããªããã®ï¼
|
---|
| 149 | # Decl(parameter), ParamDecl, ParamList, FuncHead, Expression
|
---|
| 150 | #
|
---|
| 151 | # Expression ã¯ãowner Node ã¨ãªããã®ãå¤ãããããæ¹é ãå°é£ã§ãããã
|
---|
| 152 | # Expression ãå®ç¾©ãããã¨ãã® Namespace ã owner Node ã¨ãã
|
---|
| 153 | # StructType 㯠Type ã®ä¸ç¨®ãªã®ã§ owner ãæããªã
|
---|
| 154 | #
|
---|
| 155 | class BDNode < Node
|
---|
| 156 | #@owner::Node
|
---|
| 157 | #@NamespacePath:: NamespacePath
|
---|
| 158 | #@Generator::
|
---|
| 159 | #@import::Import :
|
---|
| 160 |
|
---|
| 161 | def initialize
|
---|
| 162 | super
|
---|
| 163 | @owner = nil
|
---|
| 164 | @NamespacePath = nil
|
---|
| 165 | @import = Import.get_current
|
---|
| 166 |
|
---|
| 167 | end
|
---|
| 168 |
|
---|
| 169 | #=== owner ãè¨å®ãã
|
---|
| 170 | def set_owner owner
|
---|
| 171 | dbgPrint "set_owner: #{owner.class.name}\n"
|
---|
| 172 | @owner = owner
|
---|
| 173 | end
|
---|
| 174 |
|
---|
| 175 | #=== owner ãå¾ã
|
---|
| 176 | # class ã®èª¬æãåç
|
---|
| 177 | §
|
---|
| 178 | def get_owner
|
---|
| 179 | if @owner == nil
|
---|
| 180 | raise "Node have no owner #{self.class.name} #{get_name}"
|
---|
| 181 | end
|
---|
| 182 | @owner
|
---|
| 183 | end
|
---|
| 184 | end
|
---|
| 185 |
|
---|
| 186 | #== Namespace åãæ㤠BDNode
|
---|
| 187 | # Namespace(Region), Signature, Celltype, CompositeCelltype, Cell
|
---|
| 188 | class NSBDNode < BDNode
|
---|
| 189 |
|
---|
| 190 | def initialize
|
---|
| 191 | super
|
---|
| 192 | end
|
---|
| 193 |
|
---|
| 194 | #=== å±ãã namespace ãå¾ã
|
---|
| 195 | # owner ã namespace ã«ãã©ãçãã¾ã§ä¸ã«ãã©ã
|
---|
| 196 | def get_namespace
|
---|
| 197 | if @owner.kind_of? Namespace
|
---|
| 198 | return @owner
|
---|
| 199 | elsif @owner != nil then
|
---|
| 200 | return @owner.get_namespace
|
---|
| 201 | else
|
---|
| 202 | # @owner == nil ãªã "::"
|
---|
| 203 | if @name != "::" then
|
---|
| 204 | raise "non-root namespace has no owner #{self.class.name}##{@name} #{self}"
|
---|
| 205 | end
|
---|
| 206 | return nil
|
---|
| 207 | end
|
---|
| 208 | end
|
---|
| 209 |
|
---|
| 210 | def set_namespace_path
|
---|
| 211 | ns = get_namespace
|
---|
| 212 | if ns then
|
---|
| 213 | @NamespacePath = ns.get_namespace_path.append( get_name )
|
---|
| 214 | else
|
---|
| 215 | raise "get_namespace_path: no namespace found"
|
---|
| 216 | end
|
---|
| 217 | end
|
---|
| 218 |
|
---|
| 219 | #=== NamespacePath ãå¾ã
|
---|
| 220 | def get_namespace_path
|
---|
| 221 | return @NamespacePath
|
---|
| 222 | end
|
---|
| 223 |
|
---|
| 224 | def is_imported?
|
---|
| 225 | if @import then
|
---|
| 226 | return @import.is_imported?
|
---|
| 227 | else
|
---|
| 228 | return false # mikan: ä»® @import ã nil ã«ãªãã±ã¼ã¹ã追æ±ã§ãã¦ããªã
|
---|
| 229 | end
|
---|
| 230 | end
|
---|
| 231 | end
|
---|
| 232 |
|
---|
| 233 | class NamedList
|
---|
| 234 | # @names:: {} of items
|
---|
| 235 | # @items:: [] of items : item ã® CLASS 㯠get_name ã¡ã½ãããæã¤ã㨠get_name ã®æ»ãå¤ã¯ Symbol ã§ãªãã¦ã¯ãªããªã
|
---|
| 236 | # NamedList ã clone_for_composite ããå ´åã¯ãitem ã«ãã¡ã½ãããå¿
|
---|
| 237 | è¦
|
---|
| 238 | # @type:: string ã¨ã©ã¼ã¡ãã»ã¼ã¸
|
---|
| 239 |
|
---|
| 240 | def initialize( item, type )
|
---|
| 241 | @names = {}
|
---|
| 242 | @items = []
|
---|
| 243 | @type = type
|
---|
| 244 | add_item( item )
|
---|
| 245 | end
|
---|
| 246 |
|
---|
| 247 | #=== è¦ç´ ãå ãã
|
---|
| 248 | # parse ããæç¹ã§å ãããã¨(å ´æãè¨æ¶ãã)
|
---|
| 249 | def add_item( item )
|
---|
| 250 |
|
---|
| 251 | if item then
|
---|
| 252 | assert_name item
|
---|
| 253 | name = item.get_name
|
---|
| 254 | prev = @names[name]
|
---|
| 255 | if prev then
|
---|
| 256 | Generator.error( "S2001 \'$1\' duplicate $2" , name, @type )
|
---|
| 257 | prev_locale = prev.get_locale
|
---|
| 258 | puts "previous: #{prev_locale[0]}: line #{prev_locale[1]} \'#{name}\' defined here"
|
---|
| 259 | return self
|
---|
| 260 | end
|
---|
| 261 |
|
---|
| 262 | @names[name]=item
|
---|
| 263 | @items << item
|
---|
| 264 | end
|
---|
| 265 |
|
---|
| 266 | return self
|
---|
| 267 | end
|
---|
| 268 |
|
---|
| 269 | def change_item( item )
|
---|
| 270 | assert_name item
|
---|
| 271 | name = item.get_name
|
---|
| 272 |
|
---|
| 273 | prev_one = @names[name]
|
---|
| 274 | @names[name]=item
|
---|
| 275 |
|
---|
| 276 | @items = @items - [ prev_one ]
|
---|
| 277 | @items << item
|
---|
| 278 | end
|
---|
| 279 |
|
---|
| 280 | def del_item( item )
|
---|
| 281 | assert_name item
|
---|
| 282 | name = item.get_name
|
---|
| 283 | @names.delete name
|
---|
| 284 |
|
---|
| 285 | @items = @items - [ item ]
|
---|
| 286 | end
|
---|
| 287 |
|
---|
| 288 | def get_item( name )
|
---|
| 289 | if ! name.kind_of? Symbol
|
---|
| 290 | print "get_item: '#{name}', items are below\n"
|
---|
| 291 | @names.each{ |nm,item|
|
---|
| 292 | p nm
|
---|
| 293 | }
|
---|
| 294 | raise "get_item: #{name}: not Symbol"
|
---|
| 295 | end
|
---|
| 296 | if name then
|
---|
| 297 | return @names[name.to_sym]
|
---|
| 298 | else
|
---|
| 299 | return nil
|
---|
| 300 | end
|
---|
| 301 | end
|
---|
| 302 |
|
---|
| 303 | def get_items
|
---|
| 304 | return @items
|
---|
| 305 | end
|
---|
| 306 |
|
---|
| 307 | #=== composite cell ã clone ããæã«è¦ç´ (JOIN) ã® clone ãã
|
---|
| 308 | #
|
---|
| 309 | # mikan ãã®ã¡ã½ãã㯠Join ã«ç¹åããã¦ããã®ã§ NamedList ããåé¢ãã¹ã
|
---|
| 310 | def clone_for_composite( ct_name, cell_name, locale )
|
---|
| 311 | cl = self.clone
|
---|
| 312 | cl.set_cloned( ct_name, cell_name, locale )
|
---|
| 313 | return cl
|
---|
| 314 | end
|
---|
| 315 |
|
---|
| 316 | #=== clone ããã NamedList ã¤ã³ã¹ã¿ã³ã¹ã®åç
|
---|
| 317 | §ãããã®(item)ã clone
|
---|
| 318 | #
|
---|
| 319 | # mikan ãã®ã¡ã½ãã㯠Join ã«ç¹åããã¦ããã®ã§ NamedList ããåé¢ãã¹ã
|
---|
| 320 | def set_cloned( ct_name, cell_name, locale )
|
---|
| 321 | items = []
|
---|
| 322 | names = {}
|
---|
| 323 | @items.each { |i|
|
---|
| 324 | dbgPrint "NamedList clone #{ct_name}, #{cell_name}, #{i.get_name}\n"
|
---|
| 325 |
|
---|
| 326 | cl = i.clone_for_composite( ct_name, cell_name, locale )
|
---|
| 327 | names[cl.get_name] = cl
|
---|
| 328 | items << cl
|
---|
| 329 | }
|
---|
| 330 | @items = items
|
---|
| 331 | @names = names
|
---|
| 332 | end
|
---|
| 333 |
|
---|
| 334 | def assert_name item
|
---|
| 335 | if ! item.get_name.kind_of? Symbol
|
---|
| 336 | raise "Not symbol for NamedList item"
|
---|
| 337 | end
|
---|
| 338 | end
|
---|
| 339 |
|
---|
| 340 | def show_tree( indent )
|
---|
| 341 | @items.each { |i|
|
---|
| 342 | i.show_tree( indent )
|
---|
| 343 | }
|
---|
| 344 | end
|
---|
| 345 |
|
---|
| 346 | end
|
---|
| 347 |
|
---|
| 348 | class Typedef < BDNode
|
---|
| 349 | # @declarator:: Decl
|
---|
| 350 |
|
---|
| 351 | def self.new_decl_list( type_spec_qual_list, decl_list )
|
---|
| 352 | decl_list.each { |decl|
|
---|
| 353 | Typedef.new( type_spec_qual_list, decl )
|
---|
| 354 | }
|
---|
| 355 | end
|
---|
| 356 |
|
---|
| 357 | def initialize( type_spec_qual_list, decl )
|
---|
| 358 | super()
|
---|
| 359 | decl.set_type( type_spec_qual_list )
|
---|
| 360 | @declarator = decl
|
---|
| 361 | decl.set_owner self # Decl(Typedef)
|
---|
| 362 |
|
---|
| 363 | Namespace.new_typedef( self )
|
---|
| 364 | end
|
---|
| 365 |
|
---|
| 366 | def get_name
|
---|
| 367 | @declarator.get_name
|
---|
| 368 | end
|
---|
| 369 |
|
---|
| 370 | def get_declarator
|
---|
| 371 | @declarator
|
---|
| 372 | end
|
---|
| 373 |
|
---|
| 374 | def show_tree( indent )
|
---|
| 375 | indent.times { print " " }
|
---|
| 376 | puts "Typedef: #{locale_str}"
|
---|
| 377 | @declarator.show_tree( indent + 1 )
|
---|
| 378 | end
|
---|
| 379 | end
|
---|
| 380 |
|
---|
| 381 | #== é¢æ°é é¨
|
---|
| 382 | # signature ã«ç»é²ãããé¢æ°
|
---|
| 383 | class FuncHead <BDNode
|
---|
| 384 | # @declarator:: Decl
|
---|
| 385 |
|
---|
| 386 | def initialize( declarator, type, b_oneway )
|
---|
| 387 | super()
|
---|
| 388 | declarator.set_type( type )
|
---|
| 389 | @declarator = declarator
|
---|
| 390 | @declarator.set_owner self # Decl (FuncHead)
|
---|
| 391 |
|
---|
| 392 | if @declarator.get_type.kind_of?( FuncType ) then
|
---|
| 393 | if b_oneway then
|
---|
| 394 | @declarator.get_type.set_oneway( b_oneway )
|
---|
| 395 | end
|
---|
| 396 | end
|
---|
| 397 | @declarator.get_type.check_struct_tag :FUNCHEAD
|
---|
| 398 |
|
---|
| 399 | # check if return type is pointer
|
---|
| 400 | if declarator.get_type.kind_of? FuncType then
|
---|
| 401 | if declarator.get_type.get_type.get_original_type.kind_of?( PtrType ) &&
|
---|
| 402 | Signature.get_current.is_deviate? == false then
|
---|
| 403 | cdl_warning( "W3004 $1 pointer type has returned. specify deviate or stop return pointer" , @declarator.get_identifier )
|
---|
| 404 | end
|
---|
| 405 | end
|
---|
| 406 | end
|
---|
| 407 |
|
---|
| 408 | def get_name
|
---|
| 409 | @declarator.get_name
|
---|
| 410 | end
|
---|
| 411 |
|
---|
| 412 | def get_declarator
|
---|
| 413 | @declarator
|
---|
| 414 | end
|
---|
| 415 |
|
---|
| 416 | def is_oneway?
|
---|
| 417 | if @declarator.is_function? then
|
---|
| 418 | return @declarator.get_type.is_oneway?
|
---|
| 419 | end
|
---|
| 420 | return false
|
---|
| 421 | end
|
---|
| 422 |
|
---|
| 423 | def is_function?
|
---|
| 424 | @declarator.is_function?
|
---|
| 425 | end
|
---|
| 426 |
|
---|
| 427 | #=== FuncHead# é¢æ°ã®ååãè¿ã
|
---|
| 428 | def get_name
|
---|
| 429 | return @declarator.get_name
|
---|
| 430 | end
|
---|
| 431 |
|
---|
| 432 | #=== FuncHead# é¢æ°ã®æ»ãå¤ã®åãè¿ã
|
---|
| 433 | # types.rb ã«å®ç¾©ããã¦ããå
|
---|
| 434 | # é¢æ°ãããã®å®ç¾©ã¨ãã¦ä¸å®å
|
---|
| 435 | ¨ãªå ´å nil ãè¿ã
|
---|
| 436 | def get_return_type
|
---|
| 437 | if is_function? then
|
---|
| 438 | return @declarator.get_type.get_type
|
---|
| 439 | end
|
---|
| 440 | end
|
---|
| 441 |
|
---|
| 442 | #=== FuncHead# é¢æ°ã®å¼æ°ã®ãªã¹ããè¿ã
|
---|
| 443 | # ParamList ãè¿ã
|
---|
| 444 | # é¢æ°ãããã®å®ç¾©ã¨ãã¦ä¸å®å
|
---|
| 445 | ¨ãªå ´å nil ãè¿ã
|
---|
| 446 | def get_paramlist
|
---|
| 447 | if is_function? then
|
---|
| 448 | return @declarator.get_type.get_paramlist
|
---|
| 449 | end
|
---|
| 450 | end
|
---|
| 451 |
|
---|
| 452 | def show_tree( indent )
|
---|
| 453 | indent.times { print " " }
|
---|
| 454 | puts "FuncHead: #{locale_str}"
|
---|
| 455 | @declarator.show_tree( indent + 1 )
|
---|
| 456 | end
|
---|
| 457 | end
|
---|
| 458 |
|
---|
| 459 | #=== 宣è¨
|
---|
| 460 | # @kind ã§ç¤ºãããå種ã®å®£è¨
|
---|
| 461 | class Decl < BDNode
|
---|
| 462 |
|
---|
| 463 | # @identifer:: String
|
---|
| 464 | # @global_name:: String | nil : String(@kind=TYPEDEF||:CONSTANT), nil(@kind=ãã®ä»)
|
---|
| 465 | # set_kind ã«ã¦è¨å®ããã
|
---|
| 466 | # @type:: ArrayType, FuncType, PtrType, IntType, StructType
|
---|
| 467 | # VoidType, FloatType, DefinedType, BoolType
|
---|
| 468 | # @initializer:: constant_expression, mikan { initlist }
|
---|
| 469 | # @kind:: :VAR, :ATTRIBUTE, :PARAMETER, :TYPEDEF, :CONSTANT, :MEMBER, :FUNCHEAD(signatureã®é¢æ°å®ç¾©)
|
---|
| 470 | # @b_referenced:: bool
|
---|
| 471 | #
|
---|
| 472 | # 以ä¸ã¯ã@kind ã :VAR, :ATTRIBUTE ã®ã¨ãã«æå¹
|
---|
| 473 | # @rw:: bool # å¤ãææ³ã§ã¯ attr ã«æå®å¯è½ã ã£ãï¼æ¶ãã«ã¯ generate ã®ä¿®æ£ãå¿
|
---|
| 474 | è¦ï¼
|
---|
| 475 | # @omit:: bool
|
---|
| 476 | # @choice_list:: [String] attr åæå¤ã®é¸æè¢
|
---|
| 477 | # 以ä¸ã¯ã@kind ã :VAR, :ATTRIBUTE, :MEMBER ã®ã¨ãã«æå¹
|
---|
| 478 | # @size_is:: Expression or nil unless specified
|
---|
| 479 | # 以ä¸ã¯ã@kind ã :MEMBER ã®ã¨ãã«æå¹
|
---|
| 480 | # @count_is:: Expression or nil unless specified
|
---|
| 481 | # attr, var ã®å ´åãcount_is ã¯æå®ã§ããªã
|
---|
| 482 | # @string:: Expression, -1 (length not specified) or nil (not specified)
|
---|
| 483 | #
|
---|
| 484 | # mikan ParamDecl ã ãå¥ã«è¨ããããMemberDecl, AttrDecl ãªã©ãåããã¹ãã(ï¼)
|
---|
| 485 |
|
---|
| 486 | def initialize( identifier )
|
---|
| 487 | super()
|
---|
| 488 | @identifier = identifier
|
---|
| 489 | @rw = false
|
---|
| 490 | @omit = false
|
---|
| 491 | @size_is = nil
|
---|
| 492 | @count_is = nil
|
---|
| 493 | @string = nil
|
---|
| 494 | @choice_list = nil
|
---|
| 495 | @b_referenced = false
|
---|
| 496 | end
|
---|
| 497 |
|
---|
| 498 | def set_initializer( initializer )
|
---|
| 499 | @initializer = initializer
|
---|
| 500 | end
|
---|
| 501 |
|
---|
| 502 | def get_initializer
|
---|
| 503 | @initializer
|
---|
| 504 | end
|
---|
| 505 |
|
---|
| 506 | def is_function?
|
---|
| 507 | if @type.class == FuncType then
|
---|
| 508 | return true
|
---|
| 509 | else
|
---|
| 510 | return false
|
---|
| 511 | end
|
---|
| 512 | end
|
---|
| 513 |
|
---|
| 514 | #== Decl ã®æå³ç誤ãããã§ãã¯ãã
|
---|
| 515 | def check
|
---|
| 516 | # return nil if @type == nil
|
---|
| 517 |
|
---|
| 518 | # æ§é ä½ã¿ã°ãã§ãã¯ï¼ãã¤ã³ã¿åããæ§é ä½ãåç
|
---|
| 519 | §ããã¦ããå ´åã¯ãã¿ã°ã®åå¨ããã§ãã¯ããªãï¼
|
---|
| 520 | @type.check_struct_tag @kind
|
---|
| 521 |
|
---|
| 522 | # åã®ãã§ãã¯ãè¡ã
|
---|
| 523 | res = @type.check
|
---|
| 524 | if res then
|
---|
| 525 | cdl_error( "S2002 $1: $2" , @identifier, res )
|
---|
| 526 | end
|
---|
| 527 |
|
---|
| 528 | # ä¸è¦ã®åæååããã§ãã¯ãã
|
---|
| 529 | if @initializer then
|
---|
| 530 | case @kind
|
---|
| 531 | when :PARAMETER, :TYPEDEF, :MEMBER, :FUNCHEAD
|
---|
| 532 | cdl_error( "S2003 $1: $2 cannot have initializer" , @identifier, @kind.to_s.downcase )
|
---|
| 533 | when :VAR, :ATTRIBUTE, :CONSTANT
|
---|
| 534 | # p @initializer ããã§ã¯ä»£å
|
---|
| 535 | ¥å¯è½ãã©ããããã§ãã¯ããªã
|
---|
| 536 | # :VAR, :ATTRIBUTE, :CONSTANT ã¯ããããã§ãã§ãã¯ãã
|
---|
| 537 | # return @type.check_init( @identifier, @initializer, @kind )
|
---|
| 538 | else
|
---|
| 539 | raise "unknown kind in Delc::check"
|
---|
| 540 | end
|
---|
| 541 | end
|
---|
| 542 |
|
---|
| 543 | if( @type.kind_of? ArrayType ) && ( @type.get_subscript == nil ) && ( @omit == false ) then
|
---|
| 544 | if @kind == :ATTRIBUTE then
|
---|
| 545 | cdl_error( "S2004 $1: array subscript must be specified or omit" , @identifier )
|
---|
| 546 | elsif @kind == :VAR || @kind == :MEMBER then
|
---|
| 547 | cdl_error( "S2005 $1: array subscript must be specified" , @identifier )
|
---|
| 548 | end
|
---|
| 549 | end
|
---|
| 550 |
|
---|
| 551 | return nil
|
---|
| 552 | end
|
---|
| 553 |
|
---|
| 554 | #== ãã¤ã³ã¿ã¬ãã«ãå¾ã
|
---|
| 555 | # æ»ãå¤ï¼
|
---|
| 556 | # éãã¤ã³ã¿å¤æ° = 0
|
---|
| 557 | # ãã¤ã³ã¿å¤æ° = 1
|
---|
| 558 | # äºéãã¤ã³ã¿å¤æ° = 2
|
---|
| 559 | def get_ptr_level
|
---|
| 560 | level = 0
|
---|
| 561 | type = @type
|
---|
| 562 | while 1
|
---|
| 563 | if type.kind_of?( PtrType ) then
|
---|
| 564 | level += 1
|
---|
| 565 | type = type.get_referto
|
---|
| 566 | # elsif type.kind_of?( ArrayType ) then # æ·»æ°ãªãé
|
---|
| 567 | åã¯ãã¤ã³ã¿ã¨ã¿ãªã
|
---|
| 568 | # if type.get_subscript == nil then
|
---|
| 569 | # level += 1
|
---|
| 570 | # type = type.get_type
|
---|
| 571 | # else
|
---|
| 572 | # break
|
---|
| 573 | # end
|
---|
| 574 | # mikan ãã¤ã³ã¿ã®æ·»æ°ããé
|
---|
| 575 | åã®ãã¤ã³ã¿ã¬ãã«ã¯ï¼ã§ããï¼
|
---|
| 576 | elsif type.kind_of?( DefinedType ) then
|
---|
| 577 | type = type.get_type
|
---|
| 578 | # p "DefinedType: #{type} #{type.class}"
|
---|
| 579 | else
|
---|
| 580 | break
|
---|
| 581 | end
|
---|
| 582 | end
|
---|
| 583 | return level
|
---|
| 584 | end
|
---|
| 585 |
|
---|
| 586 | def get_name
|
---|
| 587 | @identifier
|
---|
| 588 | end
|
---|
| 589 |
|
---|
| 590 | def get_global_name
|
---|
| 591 | @global_name
|
---|
| 592 | end
|
---|
| 593 |
|
---|
| 594 | def set_type( type )
|
---|
| 595 | unless @type then
|
---|
| 596 | @type = type
|
---|
| 597 | else
|
---|
| 598 | @type.set_type( type ) # èã«è¨å®
|
---|
| 599 | end
|
---|
| 600 | end
|
---|
| 601 |
|
---|
| 602 | def get_type
|
---|
| 603 | @type
|
---|
| 604 | end
|
---|
| 605 |
|
---|
| 606 | def get_identifier
|
---|
| 607 | @identifier
|
---|
| 608 | end
|
---|
| 609 |
|
---|
| 610 | # STAGE: B
|
---|
| 611 | def set_kind( kind )
|
---|
| 612 | @kind = kind
|
---|
| 613 | case kind
|
---|
| 614 | when :TYPEDEF, :CONSTANT
|
---|
| 615 | if Namespace.get_global_name.to_s == "" then
|
---|
| 616 | @global_name = @identifier
|
---|
| 617 | else
|
---|
| 618 | @global_name = :"#{Namespace.get_global_name}_#{@identifier}"
|
---|
| 619 | end
|
---|
| 620 | else
|
---|
| 621 | @global_name = nil
|
---|
| 622 | end
|
---|
| 623 | end
|
---|
| 624 |
|
---|
| 625 | def get_kind
|
---|
| 626 | @kind
|
---|
| 627 | end
|
---|
| 628 |
|
---|
| 629 | def set_specifier_list( spec_list )
|
---|
| 630 | spec_list.each{ |spec|
|
---|
| 631 | case spec[0]
|
---|
| 632 | when :RW
|
---|
| 633 | @rw = true
|
---|
| 634 | when :OMIT
|
---|
| 635 | @omit = true
|
---|
| 636 | when :SIZE_IS
|
---|
| 637 | @size_is = spec[1]
|
---|
| 638 | when :COUNT_IS
|
---|
| 639 | @count_is = spec[1]
|
---|
| 640 | when :STRING
|
---|
| 641 | @string = spec[1]
|
---|
| 642 | when :CHOICE
|
---|
| 643 | @choice_list = spec[1]
|
---|
| 644 | else
|
---|
| 645 | raise "Unknown specifier #{spec[0]}"
|
---|
| 646 | end
|
---|
| 647 | }
|
---|
| 648 |
|
---|
| 649 | if @size_is || @count_is || @string
|
---|
| 650 | @type.set_scs( @size_is, @count_is, @string, nil, false )
|
---|
| 651 | end
|
---|
| 652 | end
|
---|
| 653 |
|
---|
| 654 | def is_rw?
|
---|
| 655 | @rw
|
---|
| 656 | end
|
---|
| 657 |
|
---|
| 658 | def is_omit?
|
---|
| 659 | @omit
|
---|
| 660 | end
|
---|
| 661 |
|
---|
| 662 | def get_size_is
|
---|
| 663 | @size_is
|
---|
| 664 | end
|
---|
| 665 |
|
---|
| 666 | def get_count_is
|
---|
| 667 | @count_is
|
---|
| 668 | end
|
---|
| 669 |
|
---|
| 670 | def get_string
|
---|
| 671 | @string
|
---|
| 672 | end
|
---|
| 673 |
|
---|
| 674 | def get_choice_list
|
---|
| 675 | @choice_list
|
---|
| 676 | end
|
---|
| 677 |
|
---|
| 678 | def referenced
|
---|
| 679 | @b_referenced = true
|
---|
| 680 | end
|
---|
| 681 |
|
---|
| 682 | def is_referenced?
|
---|
| 683 | @b_referenced
|
---|
| 684 | end
|
---|
| 685 |
|
---|
| 686 | def is_type?( type )
|
---|
| 687 | t = @type
|
---|
| 688 | while 1
|
---|
| 689 | if t.kind_of?( type ) then
|
---|
| 690 | return true
|
---|
| 691 | elsif t.kind_of?( DefinedType ) then
|
---|
| 692 | t = t.get_type
|
---|
| 693 | else
|
---|
| 694 | return false
|
---|
| 695 | end
|
---|
| 696 | end
|
---|
| 697 | end
|
---|
| 698 |
|
---|
| 699 | def is_const?
|
---|
| 700 | type = @type
|
---|
| 701 | while 1
|
---|
| 702 | if type.is_const? then
|
---|
| 703 | return true
|
---|
| 704 | elsif type.kind_of?( DefinedType ) then
|
---|
| 705 | type = type.get_type
|
---|
| 706 | else
|
---|
| 707 | return false
|
---|
| 708 | end
|
---|
| 709 | end
|
---|
| 710 | end
|
---|
| 711 |
|
---|
| 712 | def show_tree( indent )
|
---|
| 713 | indent.times { print " " }
|
---|
| 714 | puts "Declarator: name: #{@identifier} kind: #{@kind} global_name: #{@global_name} #{locale_str}"
|
---|
| 715 | (indent+1).times { print " " }
|
---|
| 716 | puts "type:"
|
---|
| 717 | @type.show_tree( indent + 2 )
|
---|
| 718 | if @initializer then
|
---|
| 719 | (indent+1).times { print " " }
|
---|
| 720 | puts "initializer:"
|
---|
| 721 | @initializer.show_tree( indent + 2 )
|
---|
| 722 | else
|
---|
| 723 | (indent+1).times { print " " }
|
---|
| 724 | puts "initializer: no"
|
---|
| 725 | end
|
---|
| 726 | (indent+1).times { print " " }
|
---|
| 727 | puts "size_is: #{@size_is.to_s}, count_is: #{@count_is.to_s}, string: #{@string.to_s} referenced: #{@b_referenced} "
|
---|
| 728 |
|
---|
| 729 | end
|
---|
| 730 |
|
---|
| 731 | end
|
---|
| 732 |
|
---|
| 733 | # é¢æ°ãã©ã¡ã¼ã¿ã®å®£è¨
|
---|
| 734 | class ParamDecl < BDNode
|
---|
| 735 |
|
---|
| 736 | # @declarator:: Decl: Token, ArrayType, FuncType, PtrType
|
---|
| 737 | # @direction:: :IN, :OUT, :INOUT, :SEND, :RECEIVE
|
---|
| 738 | # @size:: Expr (size_is å¼æ°)
|
---|
| 739 | # @count:: Expr (count_is å¼æ°)
|
---|
| 740 | # @max:: Expr (size_is ã®ç¬¬äºå¼æ°)
|
---|
| 741 | # @b_nullable:: Bool : nullable
|
---|
| 742 | # @string:: Expr or -1(if size not specified) ï¼string å¼æ°ï¼
|
---|
| 743 | # @allocator:: Signature of allocator
|
---|
| 744 | # @b_ref:: bool : size_is, count_is, string_is å¼æ°ã¨ãã¦åç
|
---|
| 745 | §ããã¦ãã
|
---|
| 746 | #
|
---|
| 747 | # 1. é¢æ°åã§ãªããã¨
|
---|
| 748 | # 2. ï¼æ¬¡å
|
---|
| 749 | 以ä¸ã®é
|
---|
| 750 | åã§ãã£ã¦æãå
|
---|
| 751 | å´ä»¥å¤ã®æ·»æ°ããããã¨
|
---|
| 752 | # 3. in, out, ..., size_is, count_is, ... ã®éè¤æå®ããªããã¨
|
---|
| 753 | # 4. ãã¤ã³ã¿ã¬ãã«ãé©åãªãã¨
|
---|
| 754 |
|
---|
| 755 | def initialize( declarator, specifier, param_specifier )
|
---|
| 756 | super()
|
---|
| 757 | @declarator = declarator
|
---|
| 758 | @declarator.set_owner self # Decl (ParamDecl)
|
---|
| 759 | @declarator.set_type( specifier )
|
---|
| 760 | @param_specifier = param_specifier
|
---|
| 761 | @b_ref = false
|
---|
| 762 | @b_nullable = false
|
---|
| 763 |
|
---|
| 764 | if @declarator.is_function? then # (1)
|
---|
| 765 | cdl_error( "S2006 \'$1\' function" , get_name )
|
---|
| 766 | return
|
---|
| 767 | end
|
---|
| 768 |
|
---|
| 769 | res = @declarator.check
|
---|
| 770 | if res then # (2)
|
---|
| 771 | cdl_error( "S2007 \'$1\' $2" , get_name, res )
|
---|
| 772 | return
|
---|
| 773 | end
|
---|
| 774 |
|
---|
| 775 | @param_specifier.each { |i|
|
---|
| 776 | case i[0] # (3)
|
---|
| 777 | when :IN, :OUT, :INOUT, :SEND, :RECEIVE
|
---|
| 778 | if @direction == nil then
|
---|
| 779 | @direction = i[0]
|
---|
| 780 | elsif i[0] == @direction then
|
---|
| 781 | cdl_warning( "W3001 $1: duplicate" , i[0] )
|
---|
| 782 | next
|
---|
| 783 | else
|
---|
| 784 | cdl_error( "S2008 $1: inconsitent with previous one" , i[0] )
|
---|
| 785 | next
|
---|
| 786 | end
|
---|
| 787 |
|
---|
| 788 | case i[0]
|
---|
| 789 | when :SEND, :RECEIVE
|
---|
| 790 | @allocator = Namespace.find( i[1] ) #1
|
---|
| 791 | if ! @allocator.instance_of?( Signature ) then
|
---|
| 792 | cdl_error( "S2009 $1: not found or not signature" , i[1] )
|
---|
| 793 | next
|
---|
| 794 | elsif ! @allocator.is_allocator? then
|
---|
| 795 | # cdl_error( "S2010 $1: not allocator signature" , i[1] )
|
---|
| 796 | end
|
---|
| 797 | end
|
---|
| 798 |
|
---|
| 799 | when :SIZE_IS
|
---|
| 800 | if @size then
|
---|
| 801 | cdl_error( "S2011 size_is duplicate" )
|
---|
| 802 | else
|
---|
| 803 | @size = i[1]
|
---|
| 804 | end
|
---|
| 805 | when :COUNT_IS
|
---|
| 806 | if @count then
|
---|
| 807 | cdl_error( "S2012 count_is duplicate" )
|
---|
| 808 | else
|
---|
| 809 | @count = i[1]
|
---|
| 810 | end
|
---|
| 811 | when :STRING
|
---|
| 812 | if @string then
|
---|
| 813 | cdl_error( "S2013 string duplicate" )
|
---|
| 814 | elsif i[1] then
|
---|
| 815 | @string = i[1]
|
---|
| 816 | else
|
---|
| 817 | @string = -1
|
---|
| 818 | end
|
---|
| 819 | when :MAX_IS
|
---|
| 820 | # max_is ã¯ãå
|
---|
| 821 | é¨çãªãã® bnf.y.rb åç
|
---|
| 822 | §
|
---|
| 823 | # size_is ã§éè¤ãã§ãã¯ããã
|
---|
| 824 | @max = i[1]
|
---|
| 825 | when :NULLABLE
|
---|
| 826 | # if ! @declarator.get_type.kind_of?( PtrType ) then
|
---|
| 827 | # cdl_error( "S2026 '$1' nullable specified for non-pointer type", @declarator.get_name )
|
---|
| 828 | # else
|
---|
| 829 | @b_nullable = true
|
---|
| 830 | # end
|
---|
| 831 | end
|
---|
| 832 |
|
---|
| 833 | }
|
---|
| 834 |
|
---|
| 835 | if @direction == nil then
|
---|
| 836 | cdl_error( "S2014 No direction specified. [in/out/inout/send/receive]" )
|
---|
| 837 | end
|
---|
| 838 |
|
---|
| 839 | if ( @direction == :OUT || @direction == :INOUT ) && @string == -1 then
|
---|
| 840 | cdl_warning( "W3002 $1: this string might cause buffer over run" , get_name )
|
---|
| 841 | end
|
---|
| 842 |
|
---|
| 843 | # mikan ãã¤ã³ã¿ã®é
|
---|
| 844 | åï¼æ·»æ°æï¼ã®ã¬ãã«ãï¼
|
---|
| 845 | ptr_level = @declarator.get_ptr_level
|
---|
| 846 |
|
---|
| 847 | # p "ptr_level: #{@declarator.get_identifier} #{ptr_level}"
|
---|
| 848 | # p @declarator
|
---|
| 849 |
|
---|
| 850 | #---- set req_level, min_level & max_level ----#
|
---|
| 851 | if !(@size||@count||@string) then # (4)
|
---|
| 852 | req_level = 1
|
---|
| 853 | elsif (@size||@count)&&@string then
|
---|
| 854 | req_level = 2
|
---|
| 855 | else
|
---|
| 856 | req_level = 1
|
---|
| 857 | end
|
---|
| 858 |
|
---|
| 859 | if @direction == :RECEIVE then
|
---|
| 860 | req_level += 1
|
---|
| 861 | end
|
---|
| 862 | min_level = req_level
|
---|
| 863 | max_level = req_level
|
---|
| 864 |
|
---|
| 865 | # IN without pointer specifier can be non-pointer type
|
---|
| 866 | if @direction == :IN && !(@size||@count||@string) then
|
---|
| 867 | min_level = 0
|
---|
| 868 | end
|
---|
| 869 |
|
---|
| 870 | # if size_is specified and pointer refer to struct, max_level increase
|
---|
| 871 | if @size then
|
---|
| 872 | type = @declarator.get_type.get_original_type
|
---|
| 873 | while type.kind_of? PtrType
|
---|
| 874 | type = type.get_referto.get_original_type
|
---|
| 875 | end
|
---|
| 876 | if type.kind_of? StructType then
|
---|
| 877 | max_level += 1
|
---|
| 878 | end
|
---|
| 879 | end
|
---|
| 880 | #---- end req_level & max_level ----#
|
---|
| 881 |
|
---|
| 882 | # p "req_level: #{req_level} ptr_level: #{ptr_level}"
|
---|
| 883 | #if ptr_level < req_level && ! ( @direction == :IN && req_level == 1 && ptr_level == 0) then
|
---|
| 884 | if ptr_level < min_level then
|
---|
| 885 | cdl_error( "S2014 $1 need pointer or more pointer" , @declarator.get_identifier )
|
---|
| 886 | elsif ptr_level > max_level then
|
---|
| 887 | # note: æ§æ解æ段éã§å®è¡ã®ãã get_current å¯
|
---|
| 888 | if Signature.get_current == nil || Signature.get_current.is_deviate? == false then
|
---|
| 889 | cdl_warning( "W3003 $1 pointer level mismatch" , @declarator.get_identifier )
|
---|
| 890 | end
|
---|
| 891 | end
|
---|
| 892 |
|
---|
| 893 | type = @declarator.get_type
|
---|
| 894 | while type.kind_of?( DefinedType )
|
---|
| 895 | type = type.get_original_type
|
---|
| 896 | end
|
---|
| 897 |
|
---|
| 898 | if ptr_level > 0 then
|
---|
| 899 | # size_is, count_is, string ãã»ãã
|
---|
| 900 | if @direction == :RECEIVE && ptr_level > 1 then
|
---|
| 901 | type.get_type.set_scs( @size, @count, @string, @max, @b_nullable )
|
---|
| 902 | else
|
---|
| 903 | type.set_scs( @size, @count, @string, @max, @b_nullable )
|
---|
| 904 | end
|
---|
| 905 |
|
---|
| 906 | #p ptr_level
|
---|
| 907 | #type.show_tree 1
|
---|
| 908 |
|
---|
| 909 | # ãã¤ã³ã¿ãæãã¦ããå
|
---|
| 910 | ã®ãã¼ã¿åãå¾ã
|
---|
| 911 | i = 0
|
---|
| 912 | t2 = type
|
---|
| 913 | while i < ptr_level
|
---|
| 914 | t2 = t2.get_referto
|
---|
| 915 | while t2.kind_of?( DefinedType )
|
---|
| 916 | t2 = t2.get_original_type
|
---|
| 917 | end
|
---|
| 918 | i += 1
|
---|
| 919 | end
|
---|
| 920 |
|
---|
| 921 | # p @declarator.get_name
|
---|
| 922 | # t2.show_tree 1
|
---|
| 923 | # p t2.is_const?
|
---|
| 924 |
|
---|
| 925 | # const 修飾ãé©åããã§ãã¯
|
---|
| 926 | if @direction == :IN then
|
---|
| 927 | if ! t2.is_const? then
|
---|
| 928 | cdl_error( "S2015 '$1' must be const for \'in\' parameter $2" , get_name, type.class )
|
---|
| 929 | end
|
---|
| 930 | else
|
---|
| 931 | if t2.is_const? then
|
---|
| 932 | cdl_error( "S2016 '$1' can not be const for $2 parameter" , get_name, @direction )
|
---|
| 933 | end
|
---|
| 934 | end
|
---|
| 935 | else
|
---|
| 936 | # éãã¤ã³ã¿ã¿ã¤ã
|
---|
| 937 | if @size != nil || @count != nil || @string != nil || @max != nil || @b_nullable then
|
---|
| 938 | type.set_scs( @size, @count, @string, @max, @b_nullable )
|
---|
| 939 | end
|
---|
| 940 | end
|
---|
| 941 |
|
---|
| 942 | # if ptr_level > 0 && @direction == :IN then
|
---|
| 943 | # if type.is_const != :CONST
|
---|
| 944 | # end
|
---|
| 945 |
|
---|
| 946 | # p self
|
---|
| 947 |
|
---|
| 948 | end
|
---|
| 949 |
|
---|
| 950 | def check_struct_tag kind
|
---|
| 951 | @declarator.get_type.check_struct_tag :PARAMETER
|
---|
| 952 | end
|
---|
| 953 |
|
---|
| 954 | def get_name
|
---|
| 955 | @declarator.get_name
|
---|
| 956 | end
|
---|
| 957 |
|
---|
| 958 | def get_size
|
---|
| 959 | @size
|
---|
| 960 | end
|
---|
| 961 |
|
---|
| 962 | def get_count
|
---|
| 963 | @count
|
---|
| 964 | end
|
---|
| 965 |
|
---|
| 966 | def get_string
|
---|
| 967 | @string
|
---|
| 968 | end
|
---|
| 969 |
|
---|
| 970 | def get_max
|
---|
| 971 | @max
|
---|
| 972 | end
|
---|
| 973 |
|
---|
| 974 | def clear_max
|
---|
| 975 | # p "clear_max: #{@declarator.get_name} #{@max.to_s}"
|
---|
| 976 | @max = nil
|
---|
| 977 | @declarator.get_type.clear_max
|
---|
| 978 | end
|
---|
| 979 |
|
---|
| 980 | def is_nullable?
|
---|
| 981 | @b_nullable
|
---|
| 982 | end
|
---|
| 983 |
|
---|
| 984 | def get_type
|
---|
| 985 | @declarator.get_type
|
---|
| 986 | end
|
---|
| 987 |
|
---|
| 988 | def get_direction
|
---|
| 989 | @direction
|
---|
| 990 | end
|
---|
| 991 |
|
---|
| 992 | def get_declarator
|
---|
| 993 | @declarator
|
---|
| 994 | end
|
---|
| 995 |
|
---|
| 996 | def get_allocator
|
---|
| 997 | @allocator
|
---|
| 998 | end
|
---|
| 999 |
|
---|
| 1000 | def referenced
|
---|
| 1001 | @b_ref = true
|
---|
| 1002 | end
|
---|
| 1003 |
|
---|
| 1004 | def is_referenced?
|
---|
| 1005 | @b_ref
|
---|
| 1006 | end
|
---|
| 1007 |
|
---|
| 1008 | #=== PPAllocator ãå¿
|
---|
| 1009 | è¦ã
|
---|
| 1010 | # Transparent RPC ã®å ´å in 㧠size_is, count_is, string ã®ãããããæå®ããã¦ããå ´å oneway ã§ã¯ PPAllocator ãå¿
|
---|
| 1011 | è¦
|
---|
| 1012 | # Transparent PC 㧠oneway ãã©ããã¯ãããã§ã¯å¤æããªãã®ã§å¥éå¤æãå¿
|
---|
| 1013 | è¦
|
---|
| 1014 | # Opaque RPC ã®å ´å size_is, count_is, string ã®ãããããæå®ããã¦ããå ´åãPPAllocator ãå¿
|
---|
| 1015 | è¦
|
---|
| 1016 | def need_PPAllocator?( b_opaque = false )
|
---|
| 1017 | if ! b_opaque then
|
---|
| 1018 | # if @direction == :IN && ( @size || @count || @string ) then
|
---|
| 1019 | if @direction == :IN && @declarator.get_type.get_original_type.kind_of?( PtrType ) then
|
---|
| 1020 | return true
|
---|
| 1021 | end
|
---|
| 1022 | else
|
---|
| 1023 | if (@direction == :IN || @direction == :OUT || @direction == :INOUT ) &&
|
---|
| 1024 | @declarator.get_type.get_original_type.kind_of?( PtrType ) then
|
---|
| 1025 | return true
|
---|
| 1026 | end
|
---|
| 1027 | end
|
---|
| 1028 | return false
|
---|
| 1029 | end
|
---|
| 1030 |
|
---|
| 1031 | def show_tree( indent )
|
---|
| 1032 | indent.times { print " " }
|
---|
| 1033 | puts "ParamDecl: direction: #{@direction} #{locale_str}"
|
---|
| 1034 | @declarator.show_tree( indent + 1 )
|
---|
| 1035 | if @size then
|
---|
| 1036 | (indent+1).times { print " " }
|
---|
| 1037 | puts "size:"
|
---|
| 1038 | @size.show_tree( indent + 2 )
|
---|
| 1039 | end
|
---|
| 1040 | if @count then
|
---|
| 1041 | (indent+1).times { print " " }
|
---|
| 1042 | puts "count:"
|
---|
| 1043 | @count.show_tree( indent + 2 )
|
---|
| 1044 | end
|
---|
| 1045 | if @string then
|
---|
| 1046 | (indent+1).times { print " " }
|
---|
| 1047 | puts "string:"
|
---|
| 1048 | if @string == -1 then
|
---|
| 1049 | (indent+2).times { print " " }
|
---|
| 1050 | puts "size is not specified"
|
---|
| 1051 | else
|
---|
| 1052 | @string.show_tree( indent + 2 )
|
---|
| 1053 | end
|
---|
| 1054 | end
|
---|
| 1055 | if @allocator then
|
---|
| 1056 | (indent+1).times { print " " }
|
---|
| 1057 | puts "allocator: signature: #{@allocator.get_name}"
|
---|
| 1058 | end
|
---|
| 1059 | end
|
---|
| 1060 | end
|
---|
| 1061 |
|
---|
| 1062 | # é¢æ°ãã©ã¡ã¼ã¿ãªã¹ã
|
---|
| 1063 | class ParamList < BDNode
|
---|
| 1064 | # @param_list:: NamedList : item: ParamDecl
|
---|
| 1065 |
|
---|
| 1066 | def initialize( paramdecl )
|
---|
| 1067 | super()
|
---|
| 1068 | @param_list = NamedList.new( paramdecl, "parameter" )
|
---|
| 1069 | @param_list.get_items.each { |paramdecl|
|
---|
| 1070 | paramdecl.set_owner self # ParamDecl
|
---|
| 1071 | }
|
---|
| 1072 | end
|
---|
| 1073 |
|
---|
| 1074 | def add_param( paramdecl )
|
---|
| 1075 | return if paramdecl == nil # æ¢ã«ã¨ã©ã¼
|
---|
| 1076 |
|
---|
| 1077 | @param_list.add_item( paramdecl )
|
---|
| 1078 | paramdecl.set_owner self # ParamDecl
|
---|
| 1079 | end
|
---|
| 1080 |
|
---|
| 1081 | def get_items
|
---|
| 1082 | @param_list.get_items
|
---|
| 1083 | end
|
---|
| 1084 |
|
---|
| 1085 | #=== size_is, count_is, string ã®å¼æ°ã®å¼ããã§ãã¯
|
---|
| 1086 | # å¤æ°ã¯åæ¹åç
|
---|
| 1087 | §å¯è½ãªãããé¢æ°é é¨ã®æ§æ解éãçµãã£ãå¾ã«ãã§ãã¯ãã
|
---|
| 1088 | def check_param
|
---|
| 1089 | @param_list.get_items.each { |i|
|
---|
| 1090 | next if i == nil # i == nil : ã¨ã©ã¼æ
|
---|
| 1091 |
|
---|
| 1092 | if i.get_type.class == VoidType then
|
---|
| 1093 | # åä¸ã® void åã¯ããã«ã¯ããªã
|
---|
| 1094 | cdl_error( "S2027 '$1' parameter cannot be void type", i.get_name )
|
---|
| 1095 | end
|
---|
| 1096 |
|
---|
| 1097 | size = i.get_size # Expression
|
---|
| 1098 | if size then
|
---|
| 1099 | val = size.eval_const( @param_list )
|
---|
| 1100 | if val == nil then # å®æ°å¼ã§ãªããï¼
|
---|
| 1101 | # mikan å¤æ°ãå«ãå¼ï¼åä¸ã®å¤æ°ã®ã¿ OK
|
---|
| 1102 | type = size.get_type( @param_list )
|
---|
| 1103 | unless type.kind_of?( IntType ) then
|
---|
| 1104 | cdl_error( "S2017 size_is argument is not integer type" )
|
---|
| 1105 | else
|
---|
| 1106 | size.check_dir_for_param( @param_list, i.get_direction, "size_is" )
|
---|
| 1107 | end
|
---|
| 1108 | else
|
---|
| 1109 | if val != Integer( val ) then
|
---|
| 1110 | cdl_error( "S2018 \'$1\' size_is parameter not integer" , i.get_declarator.get_identifier )
|
---|
| 1111 | elsif val <= 0 then
|
---|
| 1112 | cdl_error( "S2019 \'$1\' size_is parameter negative or zero" , i.get_declarator.get_identifier )
|
---|
| 1113 | end
|
---|
| 1114 | end
|
---|
| 1115 | end
|
---|
| 1116 |
|
---|
| 1117 | max = i.get_max
|
---|
| 1118 | if max then
|
---|
| 1119 | val2 = max.eval_const( @param_list )
|
---|
| 1120 | if val2 == nil then
|
---|
| 1121 | cdl_error( "S2028 '$1' max (size_is 2nd parameter) not constant", i.get_name )
|
---|
| 1122 | elsif val2 != Integer( val2 ) || val2 <= 0 then
|
---|
| 1123 | cdl_error( "S2029 '$1' max (size_is 2nd parameter) negative or zero, or not integer", i.get_name )
|
---|
| 1124 | end
|
---|
| 1125 | end
|
---|
| 1126 |
|
---|
| 1127 | if val != nil && val2 != nil then
|
---|
| 1128 | if val < val2 then
|
---|
| 1129 | cdl_warning( "W3005 '$1' size_is always lower than max. max is ignored", i.get_name )
|
---|
| 1130 | i.clear_max
|
---|
| 1131 | else
|
---|
| 1132 | cdl_error( "S2030 '$1' both size_is and max are const. size_is larger than max", i.get_name )
|
---|
| 1133 | end
|
---|
| 1134 | end
|
---|
| 1135 |
|
---|
| 1136 | count = i.get_count # Expression
|
---|
| 1137 | if count then
|
---|
| 1138 | val = count.eval_const( @param_list )
|
---|
| 1139 | if val == nil then # å®æ°å¼ã§ãªããï¼
|
---|
| 1140 | # mikan å¤æ°ãå«ãå¼ï¼åä¸ã®å¤æ°ã®ã¿ OK
|
---|
| 1141 | type = count.get_type( @param_list )
|
---|
| 1142 | unless type.kind_of?( IntType ) then
|
---|
| 1143 | cdl_error( "S2020 count_is argument is not integer type" )
|
---|
| 1144 | else
|
---|
| 1145 | count.check_dir_for_param( @param_list, i.get_direction, "count_is" )
|
---|
| 1146 | end
|
---|
| 1147 | else
|
---|
| 1148 | if val != Integer( val ) then
|
---|
| 1149 | cdl_error( "S2021 \'$1\' count_is parameter not integer" , i.get_declarator.get_identifier )
|
---|
| 1150 | elsif val <= 0 then
|
---|
| 1151 | cdl_error( "S2022 \'$1\' count_is parameter negative or zero" , i.get_declarator.get_identifier )
|
---|
| 1152 | end
|
---|
| 1153 | end
|
---|
| 1154 | end
|
---|
| 1155 |
|
---|
| 1156 | string = i.get_string # Expression
|
---|
| 1157 | if string != -1 && string then
|
---|
| 1158 | val = string.eval_const( @param_list )
|
---|
| 1159 | if val == nil then # å®æ°å¼ã§ãªããï¼
|
---|
| 1160 | # mikan å¤æ°ãå«ãå¼ï¼åä¸ã®å¤æ°ã®ã¿ OK
|
---|
| 1161 | type = string.get_type( @param_list )
|
---|
| 1162 | unless type.kind_of?( IntType ) then
|
---|
| 1163 | cdl_error( "S2023 string argument is not integer type" )
|
---|
| 1164 | else
|
---|
| 1165 | string.check_dir_for_param( @param_list, i.get_direction, "string" )
|
---|
| 1166 | end
|
---|
| 1167 | else
|
---|
| 1168 | if val != Integer( val ) then
|
---|
| 1169 | cdl_error( "S2024 \'$1\' string parameter not integer" , i.get_declarator.get_identifier )
|
---|
| 1170 | elsif val <= 0 then
|
---|
| 1171 | cdl_error( "S2025 \'$1\' string parameter negative or zero" , i.get_declarator.get_identifier )
|
---|
| 1172 | end
|
---|
| 1173 | end
|
---|
| 1174 | end
|
---|
| 1175 | }
|
---|
| 1176 | end
|
---|
| 1177 |
|
---|
| 1178 | def check_struct_tag kind
|
---|
| 1179 | @param_list.get_items.each{ |p|
|
---|
| 1180 | p.check_struct_tag kind
|
---|
| 1181 | }
|
---|
| 1182 | end
|
---|
| 1183 |
|
---|
| 1184 | #=== Push Pop Allocator ãå¿
|
---|
| 1185 | è¦ãï¼
|
---|
| 1186 | # Transparent RPC ã®å ´å (oneway ãã¤) in ã®é
|
---|
| 1187 | å(size_is, count_is, string ã®ããããã§ä¿®é£¾ï¼ããã
|
---|
| 1188 | def need_PPAllocator?( b_opaque = false )
|
---|
| 1189 | @param_list.get_items.each { |i|
|
---|
| 1190 | if i.need_PPAllocator?( b_opaque ) then
|
---|
| 1191 | return true
|
---|
| 1192 | end
|
---|
| 1193 | }
|
---|
| 1194 | false
|
---|
| 1195 | end
|
---|
| 1196 |
|
---|
| 1197 | def find( name )
|
---|
| 1198 | @param_list.get_item( name )
|
---|
| 1199 | end
|
---|
| 1200 |
|
---|
| 1201 | #== ParamList# æååå
|
---|
| 1202 | #b_name:: Bool: ãã©ã¡ã¼ã¿åãå«ãã
|
---|
| 1203 | def to_str( b_name )
|
---|
| 1204 | str = "("
|
---|
| 1205 | delim = ""
|
---|
| 1206 | @param_list.get_items.each{ |paramdecl|
|
---|
| 1207 | decl = paramdecl.get_declarator
|
---|
| 1208 | str += delim + decl.get_type
|
---|
| 1209 | if b_name then
|
---|
| 1210 | str += " " + decl.get_name
|
---|
| 1211 | end
|
---|
| 1212 | str += decl.get_type_post
|
---|
| 1213 | delim = ", "
|
---|
| 1214 | }
|
---|
| 1215 | str += ")"
|
---|
| 1216 | end
|
---|
| 1217 |
|
---|
| 1218 | def show_tree( indent )
|
---|
| 1219 | indent.times { print " " }
|
---|
| 1220 | puts "ParamList: #{locale_str}"
|
---|
| 1221 | @param_list.show_tree( indent + 1 )
|
---|
| 1222 | end
|
---|
| 1223 | end
|
---|
| 1224 |
|
---|
| 1225 | #== CDL ã®æååãªãã©ã«ãæ±ãããã®ã¯ã©ã¹
|
---|
| 1226 | # CDL ã®æååãªãã©ã«ãã®ãã®ã§ã¯ãªã
|
---|
| 1227 | class CDLString
|
---|
| 1228 | # ã¨ã¹ã±ã¼ãæåãå¤æ
|
---|
| 1229 | def self.escape str
|
---|
| 1230 | str = str.dup
|
---|
| 1231 | str.gsub!( /\\a/, "\x07" )
|
---|
| 1232 | str.gsub!( /\\b/, "\x08" )
|
---|
| 1233 | str.gsub!( /\\f/, "\x0c" )
|
---|
| 1234 | str.gsub!( /\\n/, "\x0a" )
|
---|
| 1235 | str.gsub!( /\\r/, "\x0d" )
|
---|
| 1236 | str.gsub!( /\\t/, "\x08" )
|
---|
| 1237 | str.gsub!( /\\v/, "\x0b" )
|
---|
| 1238 | str.gsub!( /(\\[Xx][0-9A-Fa-f]{1,2})/, '{printf \"\\1\"}' )
|
---|
| 1239 | str.gsub!( /(\\[0-7]{1,3})/, '{printf \"\\1\"}' )
|
---|
| 1240 | str.gsub!( /\\(.)/, "\\1" ) # mikan æªå®ç¾©ã®ã¨ã¹ã±ã¼ãã·ã¼ã±ã³ã¹ãå¤æãã¦ãã¾ã (gcc V3.4.4 ã§ã¯è¦åãåºããã)
|
---|
| 1241 | return str
|
---|
| 1242 | end
|
---|
| 1243 |
|
---|
| 1244 | #=== CDLString#åå¾ã® " ãåãé¤ã
|
---|
| 1245 | def self.remove_dquote str
|
---|
| 1246 | s = str.sub( /\A"/, "" )
|
---|
| 1247 | s.sub!( /"\z/, "" )
|
---|
| 1248 | return s
|
---|
| 1249 | end
|
---|
| 1250 | end
|
---|
| 1251 |
|
---|
| 1252 | #== CDL ã®åæååãæ±ãããã®ã¯ã©ã¹
|
---|
| 1253 | # CDL ã®åæååãã®ãã®ã§ã¯ãªã
|
---|
| 1254 | class CDLInitializer
|
---|
| 1255 | #=== åæååã®ã¯ãã¼ã³
|
---|
| 1256 | # åæåå㯠Expression, C_EXP, Array ã®ãããã
|
---|
| 1257 | def self.clone_for_composite( rhs, ct_name, cell_name, locale )
|
---|
| 1258 | if rhs.instance_of? C_EXP then
|
---|
| 1259 | # C_EXP ã® clone ãä½ãã¨ã¨ãã«ç½®æ
|
---|
| 1260 | rhs = rhs.clone_for_composite( ct_name, cell_name, locale )
|
---|
| 1261 | elsif rhs.instance_of? Expression then
|
---|
| 1262 | rhs = rhs.clone_for_composite
|
---|
| 1263 | elsif rhs.instance_of? Array then
|
---|
| 1264 | rhs = clone_for_compoiste_array( rhs, ct_name, cell_name, locale )
|
---|
| 1265 | else
|
---|
| 1266 | raise "unknown rhs for join"
|
---|
| 1267 | end
|
---|
| 1268 | return rhs
|
---|
| 1269 | end
|
---|
| 1270 |
|
---|
| 1271 | #=== åæååï¼é
|
---|
| 1272 | åï¼ã®ã¯ãã¼ã³
|
---|
| 1273 | # è¦ç´ 㯠clone_for_composite ãæã¤ãã®ã ã
|
---|
| 1274 | def self.clone_for_compoiste_array( array, ct_name, cell_name, locale )
|
---|
| 1275 | # "compoiste.identifier" ã®å ´å (CDL ã¨ãã¦ã¯èª¤ã)
|
---|
| 1276 | if array[0] == :COMPOSITE then
|
---|
| 1277 | return array.clone
|
---|
| 1278 | end
|
---|
| 1279 |
|
---|
| 1280 | new_array = array.map{ |m|
|
---|
| 1281 | clone_for_composite( m, ct_name, cell_name, locale )
|
---|
| 1282 | }
|
---|
| 1283 | return new_array
|
---|
| 1284 | end
|
---|
| 1285 | end
|
---|