tecscde 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rubocop.yml +125 -0
- data/.rubocop_todo.yml +188 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +6 -0
- data/LICENSE +46 -0
- data/LICENSE.ja +32 -0
- data/README.ja.md +200 -0
- data/README.md +35 -0
- data/Rakefile +27 -0
- data/bin/tecscde +64 -0
- data/glade/tecscde-cell-property.glade +205 -0
- data/glade/tecscde-celltype-property.glade +172 -0
- data/glade/tecscde-celltype.glade +414 -0
- data/glade/tecscde-export.glade +161 -0
- data/glade/test-cell-plugin.rb +51 -0
- data/glade/test-cell-property.rb +35 -0
- data/glade/test-export.rb +35 -0
- data/glade/test-palette.rb +26 -0
- data/lib/tcflow.rb +148 -0
- data/lib/tecscde.rb +65 -0
- data/lib/tecscde/NewCell.png +0 -0
- data/lib/tecscde/SelectArrow.png +0 -0
- data/lib/tecscde/attr_tree_view.rb +253 -0
- data/lib/tecscde/cell_plugin_dialog.glade +294 -0
- data/lib/tecscde/cell_plugin_dialog.rb +89 -0
- data/lib/tecscde/celltype_tree_view.rb +105 -0
- data/lib/tecscde/change_set_control.rb +35 -0
- data/lib/tecscde/change_set_control/change_set.rb +32 -0
- data/lib/tecscde/change_set_control/change_set_manager.rb +62 -0
- data/lib/tecscde/command.rb +35 -0
- data/lib/tecscde/control.rb +491 -0
- data/lib/tecscde/highlighted_objects.rb +180 -0
- data/lib/tecscde/logger.rb +74 -0
- data/lib/tecscde/main_view_and_model.rb +80 -0
- data/lib/tecscde/palette.glade +553 -0
- data/lib/tecscde/palette.rb +174 -0
- data/lib/tecscde/preferences.glade +117 -0
- data/lib/tecscde/preferences.rb +44 -0
- data/lib/tecscde/tecs_model.rb +1137 -0
- data/lib/tecscde/tecs_model/hbar.rb +68 -0
- data/lib/tecscde/tecs_model/tm_c_port.rb +122 -0
- data/lib/tecscde/tecs_model/tm_c_port_array.rb +98 -0
- data/lib/tecscde/tecs_model/tm_cell.rb +496 -0
- data/lib/tecscde/tecs_model/tm_e_port.rb +126 -0
- data/lib/tecscde/tecs_model/tm_e_port_array.rb +78 -0
- data/lib/tecscde/tecs_model/tm_join.rb +293 -0
- data/lib/tecscde/tecs_model/tm_join_bar.rb +146 -0
- data/lib/tecscde/tecs_model/tm_port.rb +238 -0
- data/lib/tecscde/tecs_model/tm_port_array.rb +246 -0
- data/lib/tecscde/tecs_model/tm_region.rb +107 -0
- data/lib/tecscde/tecs_model/tm_uneditable.rb +68 -0
- data/lib/tecscde/tecs_model/vbar.rb +68 -0
- data/lib/tecscde/templates/_cell_info.cde.erb +15 -0
- data/lib/tecscde/templates/_join_info.cde.erb +28 -0
- data/lib/tecscde/templates/main.cde.erb +49 -0
- data/lib/tecscde/tm_object.rb +91 -0
- data/lib/tecscde/version.rb +4 -0
- data/lib/tecscde/view.rb +58 -0
- data/lib/tecscde/view/cairo_matrix.rb +90 -0
- data/lib/tecscde/view/canvas.rb +59 -0
- data/lib/tecscde/view/constants.rb +114 -0
- data/lib/tecscde/view/main_view.rb +1245 -0
- data/lib/tecsflow.rb +475 -0
- data/lib/tecsflow/C_parser.tab.rb +2471 -0
- data/lib/tecsflow/C_parser.y.rb +1087 -0
- data/lib/tecsflow/classes.rb +421 -0
- data/lib/tecsgen.rb +581 -0
- data/lib/tecsgen/core/C_parser.tab.rb +2477 -0
- data/lib/tecsgen/core/C_parser.y +1032 -0
- data/lib/tecsgen/core/bnf-deb.tab.rb +5193 -0
- data/lib/tecsgen/core/bnf.tab.rb +5193 -0
- data/lib/tecsgen/core/bnf.y +2211 -0
- data/lib/tecsgen/core/componentobj.rb +7901 -0
- data/lib/tecsgen/core/ctypes.rb +226 -0
- data/lib/tecsgen/core/expression.rb +1031 -0
- data/lib/tecsgen/core/gen_xml.rb +374 -0
- data/lib/tecsgen/core/generate.rb +5206 -0
- data/lib/tecsgen/core/location.rb +116 -0
- data/lib/tecsgen/core/messages.rb +101 -0
- data/lib/tecsgen/core/optimize.rb +456 -0
- data/lib/tecsgen/core/plugin.rb +332 -0
- data/lib/tecsgen/core/pluginModule.rb +165 -0
- data/lib/tecsgen/core/syntaxobj.rb +1234 -0
- data/lib/tecsgen/core/tecs_lang.rb +306 -0
- data/lib/tecsgen/core/tecsgen.rb +453 -0
- data/lib/tecsgen/core/tecsinfo.rb +860 -0
- data/lib/tecsgen/core/tool_info.rb +258 -0
- data/lib/tecsgen/core/types.rb +1632 -0
- data/lib/tecsgen/core/unjoin_plugin.rb +218 -0
- data/lib/tecsgen/core/value.rb +650 -0
- data/lib/tecsgen/messages/messages_console_en_US.rb +1171 -0
- data/lib/tecsgen/messages/messages_console_ja_JP.rb +1171 -0
- data/lib/tecsgen/messages/messages_file_en_US.rb +334 -0
- data/lib/tecsgen/messages/messages_file_ja_JP.rb +163 -0
- data/lib/tecsgen/plugin/ATK1AlarmPlugin.rb +196 -0
- data/lib/tecsgen/plugin/ATK1DelayTaskPlugin.rb +106 -0
- data/lib/tecsgen/plugin/ATK1EventPlugin.rb +147 -0
- data/lib/tecsgen/plugin/ATK1ISRPlugin.rb +174 -0
- data/lib/tecsgen/plugin/ATK1KernelPlugin.rb +287 -0
- data/lib/tecsgen/plugin/ATK1ResourcePlugin.rb +124 -0
- data/lib/tecsgen/plugin/ATK1TaskPlugin.rb +220 -0
- data/lib/tecsgen/plugin/C2TECSBridgePlugin.rb +210 -0
- data/lib/tecsgen/plugin/CellPlugin.rb +61 -0
- data/lib/tecsgen/plugin/CelltypePlugin.rb +72 -0
- data/lib/tecsgen/plugin/CompositePlugin.rb +66 -0
- data/lib/tecsgen/plugin/DomainPlugin.rb +89 -0
- data/lib/tecsgen/plugin/HRP2AlarmHandlerPlugin.rb +76 -0
- data/lib/tecsgen/plugin/HRP2Cache.rb +1 -0
- data/lib/tecsgen/plugin/HRP2CyclicHandlerPlugin.rb +75 -0
- data/lib/tecsgen/plugin/HRP2DataqueuePlugin.rb +68 -0
- data/lib/tecsgen/plugin/HRP2EventflagPlugin.rb +68 -0
- data/lib/tecsgen/plugin/HRP2FixedSizeMemoryPoolPlugin.rb +68 -0
- data/lib/tecsgen/plugin/HRP2HandlerPlugin.rb +117 -0
- data/lib/tecsgen/plugin/HRP2KernelObjectPlugin.rb +372 -0
- data/lib/tecsgen/plugin/HRP2ObjectPlugin.rb +94 -0
- data/lib/tecsgen/plugin/HRP2Plugin.rb +140 -0
- data/lib/tecsgen/plugin/HRP2PostHook.rb +111 -0
- data/lib/tecsgen/plugin/HRP2PriorityDataqueuePlugin.rb +66 -0
- data/lib/tecsgen/plugin/HRP2RPCPlugin.rb +319 -0
- data/lib/tecsgen/plugin/HRP2SVCPlugin.rb +473 -0
- data/lib/tecsgen/plugin/HRP2SemaphorePlugin.rb +67 -0
- data/lib/tecsgen/plugin/HRP2TaskPlugin.rb +200 -0
- data/lib/tecsgen/plugin/HRPHandlerPlugin.rb +125 -0
- data/lib/tecsgen/plugin/HRPKernelObjectManager.rb +72 -0
- data/lib/tecsgen/plugin/HRPKernelObjectPlugin.rb +333 -0
- data/lib/tecsgen/plugin/HRPObjectPlugin.rb +93 -0
- data/lib/tecsgen/plugin/HRPPlugin.rb +356 -0
- data/lib/tecsgen/plugin/HRPRPCPlugin.rb +407 -0
- data/lib/tecsgen/plugin/HRPSVCPlugin.rb +859 -0
- data/lib/tecsgen/plugin/HRPTaskPlugin.rb +107 -0
- data/lib/tecsgen/plugin/Mruby2CBridgePlugin.rb +86 -0
- data/lib/tecsgen/plugin/MrubyBridgeCellPlugin.rb +264 -0
- data/lib/tecsgen/plugin/MrubyBridgeCelltypePlugin.rb +293 -0
- data/lib/tecsgen/plugin/MrubyBridgeCompositePlugin.rb +49 -0
- data/lib/tecsgen/plugin/MrubyBridgePlugin.rb +67 -0
- data/lib/tecsgen/plugin/MrubyBridgeSignaturePlugin.rb +1307 -0
- data/lib/tecsgen/plugin/MrubyInfoBridgePlugin.rb +14 -0
- data/lib/tecsgen/plugin/MrubyInfoBridgeSignaturePlugin.rb +994 -0
- data/lib/tecsgen/plugin/MultiPlugin.rb +57 -0
- data/lib/tecsgen/plugin/NotifierPlugin.rb +1217 -0
- data/lib/tecsgen/plugin/OpaqueMarshalerPlugin.rb +81 -0
- data/lib/tecsgen/plugin/OpaqueRPCPlugin.rb +323 -0
- data/lib/tecsgen/plugin/RPCPlugin.rb +266 -0
- data/lib/tecsgen/plugin/RepeatCellPlugin.rb +166 -0
- data/lib/tecsgen/plugin/RepeatJoinPlugin.rb +130 -0
- data/lib/tecsgen/plugin/SharedOpaqueRPCPlugin.rb +357 -0
- data/lib/tecsgen/plugin/SharedRPCPlugin.rb +329 -0
- data/lib/tecsgen/plugin/SignaturePlugin.rb +77 -0
- data/lib/tecsgen/plugin/TECS2CBridgePlugin.rb +178 -0
- data/lib/tecsgen/plugin/TECSInfoPlugin.rb +280 -0
- data/lib/tecsgen/plugin/ThroughPlugin.rb +333 -0
- data/lib/tecsgen/plugin/TracePlugin.rb +484 -0
- data/lib/tecsgen/plugin/lib/GenHRP2Marshaler.rb +761 -0
- data/lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb +1107 -0
- data/lib/tecsgen/plugin/lib/GenParamCopy.rb +365 -0
- data/lib/tecsgen/plugin/lib/GenTransparentMarshaler.rb +683 -0
- data/lib/tecsgen/plugin/lib/MrubyBridgeCelltypePluginModule.rb +283 -0
- data/lib/tecsgen/plugin/lib/MrubyBridgeSignaturePluginModule.rb +277 -0
- data/lib/tecsgen/version.rb +6 -0
- data/samples/FigureSamples/active/active.cde +104 -0
- data/samples/FigureSamples/active/active.cdl +20 -0
- data/samples/FigureSamples/active/active.pdf +0 -0
- data/samples/FigureSamples/active/active.png +0 -0
- data/samples/FigureSamples/active/gen/tmp_C_src.c +36 -0
- data/samples/FigureSamples/active/gen/tmp_cygwin_tecs.h +1908 -0
- data/samples/FigureSamples/active/gen/tmp_plugin_post_code.cdl +0 -0
- data/samples/FigureSamples/allocator/allocator-internal.png +0 -0
- data/samples/FigureSamples/allocator/allocator.cde +171 -0
- data/samples/FigureSamples/allocator/allocator.cdl +58 -0
- data/samples/FigureSamples/allocator/allocator.png +0 -0
- data/samples/FigureSamples/basic/Makefile +87 -0
- data/samples/FigureSamples/basic/SimpleSample-trace.cdl +50 -0
- data/samples/FigureSamples/basic/SimpleSample.cde +91 -0
- data/samples/FigureSamples/basic/SimpleSample.cdl +47 -0
- data/samples/FigureSamples/basic/basic.cde +93 -0
- data/samples/FigureSamples/basic/basic.cdl +46 -0
- data/samples/FigureSamples/basic/basic.png +0 -0
- data/samples/FigureSamples/callback/callback.cde +130 -0
- data/samples/FigureSamples/callback/callback.cdl +29 -0
- data/samples/FigureSamples/callback/callback.png +0 -0
- data/samples/FigureSamples/carray/carray.cde +144 -0
- data/samples/FigureSamples/carray/carray.cdl +38 -0
- data/samples/FigureSamples/carray/carray.png +0 -0
- data/samples/FigureSamples/cearray/cearray.cde +314 -0
- data/samples/FigureSamples/cearray/cearray.cdl +60 -0
- data/samples/FigureSamples/cearray/cearray.png +0 -0
- data/samples/FigureSamples/composite/composite-internal.png +0 -0
- data/samples/FigureSamples/composite/composite.cde +216 -0
- data/samples/FigureSamples/composite/composite.cdl +95 -0
- data/samples/FigureSamples/composite/composite.png +0 -0
- data/samples/FigureSamples/earray/earray.cde +142 -0
- data/samples/FigureSamples/earray/earray.cdl +38 -0
- data/samples/FigureSamples/earray/earray.png +0 -0
- data/samples/FigureSamples/join/Makefile +87 -0
- data/samples/FigureSamples/join/join.cde +132 -0
- data/samples/FigureSamples/join/join.cdl +40 -0
- data/samples/FigureSamples/join/join.png +0 -0
- data/samples/FigureSamples/relay/Makefile +99 -0
- data/samples/FigureSamples/relay/relay-internal.png +0 -0
- data/samples/FigureSamples/relay/relay.cde +284 -0
- data/samples/FigureSamples/relay/relay.cdl +52 -0
- data/samples/FigureSamples/relay/relay.png +0 -0
- data/samples/FigureSamples/rpc/Makefile +123 -0
- data/samples/FigureSamples/rpc/rpc-expand.png +0 -0
- data/samples/FigureSamples/rpc/rpc.cde +245 -0
- data/samples/FigureSamples/rpc/rpc.png +0 -0
- data/samples/FigureSamples/rpc/rpc_sample.cdl +53 -0
- data/samples/SimpleSample/Makefile +25 -0
- data/samples/SimpleSample/SimpleSample/Makefile +86 -0
- data/samples/SimpleSample/SimpleSample/Makefile-trace +91 -0
- data/samples/SimpleSample/SimpleSample/README.txt +106 -0
- data/samples/SimpleSample/SimpleSample/SimpleSample-trace.cdl +50 -0
- data/samples/SimpleSample/SimpleSample/SimpleSample.cdl +45 -0
- data/samples/SimpleSample/SimpleSample/src/tSample.c +77 -0
- data/samples/SimpleSample/SimpleSample/src/tSimple.c +48 -0
- data/samples/SimpleSample/SimpleSample/src/tecs-types.h +27 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/Makefile +51 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/Makefile-trace +91 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/README.txt +106 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/SimpleSample-trace.cdl +80 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/SimpleSample.cdl +77 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/rSample/Makefile +112 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/rSimple/Makefile +109 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/src/tSample.c +80 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/src/tSimple.c +47 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/src/tTaskMain.c +66 -0
- data/samples/SimpleSample/SimpleSampleOpaqueRPC/src/tecs-types.h +27 -0
- data/samples/SimpleSample/SimpleSampleTransparentRPC/Makefile +125 -0
- data/samples/SimpleSample/SimpleSampleTransparentRPC/Makefile-trace +130 -0
- data/samples/SimpleSample/SimpleSampleTransparentRPC/SimpleSample-trace.cdl +54 -0
- data/samples/SimpleSample/SimpleSampleTransparentRPC/SimpleSample.cdl +53 -0
- data/samples/SimpleSample/SimpleSampleTransparentRPC/src/tSample.c +80 -0
- data/samples/SimpleSample/SimpleSampleTransparentRPC/src/tSimple.c +54 -0
- data/tecscde.gemspec +41 -0
- metadata +353 -0
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
#
|
|
2
|
+
# TECS Generator
|
|
3
|
+
# Generator for TOPPERS Embedded Component System
|
|
4
|
+
#
|
|
5
|
+
# Copyright (C) 2008-2017 by TOPPERS Project
|
|
6
|
+
#--
|
|
7
|
+
# 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
|
|
8
|
+
# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
|
|
9
|
+
# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
|
|
10
|
+
# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
|
|
11
|
+
# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
|
|
12
|
+
# スコード中に含まれていること.
|
|
13
|
+
# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
|
|
14
|
+
# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
|
|
15
|
+
# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
|
|
16
|
+
# の無保証規定を掲載すること.
|
|
17
|
+
# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
|
|
18
|
+
# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
|
|
19
|
+
# と.
|
|
20
|
+
# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
|
|
21
|
+
# 作権表示,この利用条件および下記の無保証規定を掲載すること.
|
|
22
|
+
# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
|
|
23
|
+
# 報告すること.
|
|
24
|
+
# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
|
|
25
|
+
# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
|
|
26
|
+
# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
|
|
27
|
+
# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
|
|
28
|
+
# 免責すること.
|
|
29
|
+
#
|
|
30
|
+
# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
|
|
31
|
+
# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
|
|
32
|
+
# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
|
|
33
|
+
# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
|
|
34
|
+
# の責任を負わない.
|
|
35
|
+
#
|
|
36
|
+
# $Id: tool_info.rb 2640 2017-06-03 11:27:12Z okuma-top $
|
|
37
|
+
#++
|
|
38
|
+
|
|
39
|
+
#= TOOL_INFO class
|
|
40
|
+
# The syntax of the contents of __tool_info__ is same as JSON.
|
|
41
|
+
# Home made schema is used to validate the contents of __tool_info__.
|
|
42
|
+
# the schema is not defiened well. see saveload.rb for example of the schema.
|
|
43
|
+
#
|
|
44
|
+
class TOOL_INFO
|
|
45
|
+
# tool_info
|
|
46
|
+
@@tool_info = { }
|
|
47
|
+
|
|
48
|
+
# tool_info schema for tecsgen
|
|
49
|
+
@@TECSGEN_schema = {
|
|
50
|
+
:tecsgen => { # require
|
|
51
|
+
:base_dir => [:string], # dir where the cde created initially
|
|
52
|
+
:direct_import => [:string], # .cdl (sometimes .cde) specified in argments
|
|
53
|
+
:import_path => [:string], # -I of tecsgen
|
|
54
|
+
:define_macro => [:string], # -D of tecsgen
|
|
55
|
+
:tecscde_version => :string, # TECSCDE version
|
|
56
|
+
:cde_format_version => :string, # CDE format version
|
|
57
|
+
:save_date => :string, # last save date & time
|
|
58
|
+
},
|
|
59
|
+
:__tecsgen => { # optioanl
|
|
60
|
+
:cpp => :string # -c or TECS_CPP environment variable
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
def initialize(name, val)
|
|
65
|
+
@@tool_info[name] = val
|
|
66
|
+
|
|
67
|
+
# __tool_info__( "tecsgen" ): validate & reflect immediately
|
|
68
|
+
p "tool_info: tecsgen #{name}"
|
|
69
|
+
if name == :tecsgen
|
|
70
|
+
set_tecsgen_tool_info
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def self.get_tool_info(name)
|
|
75
|
+
@@tool_info[name]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
#=== TOOL_INFO#set_tecsgen_tool_info
|
|
79
|
+
# __tool_info__( "tecsgen" )
|
|
80
|
+
def set_tecsgen_tool_info
|
|
81
|
+
validator = TOOL_INFO::VALIDATOR.new(:tecsgen, @@TECSGEN_schema)
|
|
82
|
+
if validator.validate || $b_force_apply_tool_info
|
|
83
|
+
info = TOOL_INFO.get_tool_info(:tecsgen)
|
|
84
|
+
(info[:base_dir]).each{|bd|
|
|
85
|
+
if !$base_dir.include? bd
|
|
86
|
+
$base_dir[bd] = true
|
|
87
|
+
end
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
info[:import_path].each{|path|
|
|
91
|
+
if !$import_path.include?(path)
|
|
92
|
+
$import_path << path
|
|
93
|
+
end
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
info[:define_macro].each{|define|
|
|
97
|
+
if !$define.include?(define)
|
|
98
|
+
$define << define
|
|
99
|
+
end
|
|
100
|
+
}
|
|
101
|
+
if info[:cpp]
|
|
102
|
+
if !$b_cpp_specified
|
|
103
|
+
$cpp = info[:cpp]
|
|
104
|
+
$b_cpp_specified = true
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
info[:direct_import] && info[:direct_import].each{|import|
|
|
109
|
+
Import.new(import, false, false)
|
|
110
|
+
}
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
#== simple JSON validator
|
|
115
|
+
# this validator use simple schema.
|
|
116
|
+
# array length cannot be checked.
|
|
117
|
+
# you have to check array length in your code, if necessary.
|
|
118
|
+
class VALIDATOR
|
|
119
|
+
# @b_ok::Bool
|
|
120
|
+
|
|
121
|
+
def error(msg)
|
|
122
|
+
STDERR.print("__tool_info__: " + msg)
|
|
123
|
+
@b_ok = false
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def initialize(name, schema)
|
|
127
|
+
@name = name
|
|
128
|
+
@schema = schema
|
|
129
|
+
@b_ok = true
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
#=== VALIDATOR#validate
|
|
133
|
+
def validate
|
|
134
|
+
info = TOOL_INFO.get_tool_info @name
|
|
135
|
+
if info.nil?
|
|
136
|
+
error("\"#{@name}\" not found\n")
|
|
137
|
+
return @b_ok
|
|
138
|
+
end
|
|
139
|
+
validate_object info, @name, @name
|
|
140
|
+
return @b_ok
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def validate_object(object, require_type, path)
|
|
144
|
+
obj_type = @schema[require_type]
|
|
145
|
+
dbgPrint "validate_object: #{path} object=#{obj_type[:type]} required=#{object[:type]}\n"
|
|
146
|
+
|
|
147
|
+
obj_type.each{|name, val_type|
|
|
148
|
+
val = object[name]
|
|
149
|
+
path2 = path.to_s + "." + name.to_s
|
|
150
|
+
if val.nil?
|
|
151
|
+
error("#{path}: required property not found '#{name}'\n")
|
|
152
|
+
next
|
|
153
|
+
end
|
|
154
|
+
if val_type.is_a? Array
|
|
155
|
+
validate_array_member val, val_type, path2
|
|
156
|
+
else
|
|
157
|
+
validate_types val, val_type, path2
|
|
158
|
+
end
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
optional = @schema[("__" + require_type.to_s).to_sym]
|
|
162
|
+
if optional
|
|
163
|
+
dbgPrint "#{require_type} has optional\n"
|
|
164
|
+
|
|
165
|
+
optional.each{|name, val_type|
|
|
166
|
+
val = object[name]
|
|
167
|
+
path2 = path.to_s + "." + name.to_s
|
|
168
|
+
if val.nil?
|
|
169
|
+
# no need to occur error
|
|
170
|
+
# error( "#{path}: required property not found '#{name}'\n" )
|
|
171
|
+
next
|
|
172
|
+
end
|
|
173
|
+
if val_type.is_a? Array
|
|
174
|
+
validate_array_member val, val_type, path2
|
|
175
|
+
else
|
|
176
|
+
validate_types val, val_type, path2
|
|
177
|
+
end
|
|
178
|
+
}
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def validate_array_member(array, val_types, path)
|
|
183
|
+
if !array.is_a? Array
|
|
184
|
+
error("#{path2}: array required as value\n")
|
|
185
|
+
return
|
|
186
|
+
end
|
|
187
|
+
index = 0
|
|
188
|
+
array.each{|member|
|
|
189
|
+
type = get_object_type member
|
|
190
|
+
i = val_types.find_index type
|
|
191
|
+
if i.nil?
|
|
192
|
+
if type == :integer
|
|
193
|
+
i = val_types.find_index :number
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
if i.nil?
|
|
197
|
+
error("#{path}: array member type mismatch, #{type} for #{val_types}\n")
|
|
198
|
+
next
|
|
199
|
+
end
|
|
200
|
+
val_type = val_types[i]
|
|
201
|
+
validate_types member, val_type, (path.to_s + "[" + index.to_s + "].")
|
|
202
|
+
index += 1
|
|
203
|
+
}
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
#=== TOOL_INFO::VALIDATOR#validate_types
|
|
207
|
+
# obj::Object (Integer, Floating, String, Hash)
|
|
208
|
+
# val_type::Symbol : required object type
|
|
209
|
+
def validate_types(obj, val_type, path)
|
|
210
|
+
type = get_object_type obj
|
|
211
|
+
case val_type
|
|
212
|
+
when :integer
|
|
213
|
+
if type == :integer
|
|
214
|
+
return
|
|
215
|
+
end
|
|
216
|
+
when :number
|
|
217
|
+
if type == :integer || type == :number
|
|
218
|
+
return
|
|
219
|
+
end
|
|
220
|
+
when :string
|
|
221
|
+
if type == :string
|
|
222
|
+
return
|
|
223
|
+
end
|
|
224
|
+
# when :nil # mikan
|
|
225
|
+
# when :bool # mikan
|
|
226
|
+
else # object or fixed string
|
|
227
|
+
if val_type.is_a? String
|
|
228
|
+
# val is specified by String
|
|
229
|
+
if type == :string
|
|
230
|
+
if obj == val_type
|
|
231
|
+
return
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
else
|
|
235
|
+
if type.to_sym == val_type
|
|
236
|
+
validate_object(obj, val_type, path + val_type.to_s)
|
|
237
|
+
return
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
error("#{path}: type mismatch, #{type} for #{val_type}\n")
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def get_object_type(obj)
|
|
245
|
+
# p "#{obj.class} #{obj.to_s}"
|
|
246
|
+
if obj.is_a? Integer
|
|
247
|
+
return :integer
|
|
248
|
+
elsif obj.is_a? Float
|
|
249
|
+
return :number
|
|
250
|
+
elsif obj.is_a? String
|
|
251
|
+
return :string
|
|
252
|
+
elsif obj.is_a? Hash
|
|
253
|
+
return obj[:type].to_sym
|
|
254
|
+
end
|
|
255
|
+
return nil
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
end
|
|
@@ -0,0 +1,1632 @@
|
|
|
1
|
+
#
|
|
2
|
+
# TECS Generator
|
|
3
|
+
# Generator for TOPPERS Embedded Component System
|
|
4
|
+
#
|
|
5
|
+
# Copyright (C) 2008-2017 by TOPPERS Project
|
|
6
|
+
#--
|
|
7
|
+
# 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
|
|
8
|
+
# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
|
|
9
|
+
# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
|
|
10
|
+
# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
|
|
11
|
+
# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
|
|
12
|
+
# スコード中に含まれていること.
|
|
13
|
+
# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
|
|
14
|
+
# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
|
|
15
|
+
# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
|
|
16
|
+
# の無保証規定を掲載すること.
|
|
17
|
+
# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
|
|
18
|
+
# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
|
|
19
|
+
# と.
|
|
20
|
+
# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
|
|
21
|
+
# 作権表示,この利用条件および下記の無保証規定を掲載すること.
|
|
22
|
+
# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
|
|
23
|
+
# 報告すること.
|
|
24
|
+
# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
|
|
25
|
+
# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
|
|
26
|
+
# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
|
|
27
|
+
# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
|
|
28
|
+
# 免責すること.
|
|
29
|
+
#
|
|
30
|
+
# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
|
|
31
|
+
# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
|
|
32
|
+
# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
|
|
33
|
+
# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
|
|
34
|
+
# の責任を負わない.
|
|
35
|
+
#
|
|
36
|
+
# $Id: types.rb 2665 2017-07-24 08:59:28Z okuma-top $
|
|
37
|
+
#++
|
|
38
|
+
|
|
39
|
+
#= HasType: @type を内部に持つ型のためのモジュール
|
|
40
|
+
# @b_cloned::Bool : true if @type is cloned
|
|
41
|
+
#
|
|
42
|
+
# このモジュールは DefinedType, PtrType, ArrayType に include される
|
|
43
|
+
# 本当は typedef された時の Decl の要素のみ clone すればよいのだが、get_type, get_original_type で
|
|
44
|
+
# 取り出されたとき、set_scs, set_qualifier されたときに無条件で clone する (無駄にメモリを使用する)
|
|
45
|
+
# ただし、clone するのは一回のみである (二回 clone すると別の型を参照してしまう)
|
|
46
|
+
#
|
|
47
|
+
# initialize で clone しても、共有されているときに clone されない
|
|
48
|
+
#
|
|
49
|
+
module HasType
|
|
50
|
+
def initHasType
|
|
51
|
+
@b_cloned = false
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
#=== HasType# @type をクローンする
|
|
55
|
+
def clone_type
|
|
56
|
+
# if @b_cloned == false then
|
|
57
|
+
@type = @type.clone
|
|
58
|
+
@b_cloned = true
|
|
59
|
+
# end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
class Type < Node
|
|
64
|
+
# @b_const : bool
|
|
65
|
+
# @b_volatile : bool
|
|
66
|
+
|
|
67
|
+
def initialize
|
|
68
|
+
super
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def set_qualifier(qualifier)
|
|
72
|
+
case qualifier
|
|
73
|
+
when :CONST
|
|
74
|
+
# if @b_const then
|
|
75
|
+
# cdl_error( "T1001 const duplicate" )
|
|
76
|
+
# end
|
|
77
|
+
@b_const = true
|
|
78
|
+
when :VOLATILE
|
|
79
|
+
# if @b_volatile then
|
|
80
|
+
# cdl_error( "T1002 volatile duplicate" )
|
|
81
|
+
# end
|
|
82
|
+
@b_volatile = true
|
|
83
|
+
else
|
|
84
|
+
raise "Unknown qualifier #{qualifier}"
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def is_const?
|
|
89
|
+
if @b_const
|
|
90
|
+
return true
|
|
91
|
+
else
|
|
92
|
+
return false
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def is_volatile?
|
|
97
|
+
if @b_volatile
|
|
98
|
+
return true
|
|
99
|
+
else
|
|
100
|
+
return false
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def is_void?
|
|
105
|
+
if self.is_a? DefinedType
|
|
106
|
+
return @type.is_void?
|
|
107
|
+
elsif self.is_a? VoidType
|
|
108
|
+
return true
|
|
109
|
+
else
|
|
110
|
+
return false
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
#=== size_is, count_is, string を設定
|
|
115
|
+
# 派生クラスでオーバーライドする(デフォルトではエラー)
|
|
116
|
+
def set_scs(size, count, string, max = nil, b_nullable = false)
|
|
117
|
+
str = ""
|
|
118
|
+
delim = ""
|
|
119
|
+
if size
|
|
120
|
+
str = "size_is"
|
|
121
|
+
delim = ", "
|
|
122
|
+
end
|
|
123
|
+
if count
|
|
124
|
+
str = "#{str}#{delim}count_is"
|
|
125
|
+
delim = ", "
|
|
126
|
+
end
|
|
127
|
+
if string
|
|
128
|
+
str = "#{str}#{delim}string"
|
|
129
|
+
delim = ", "
|
|
130
|
+
end
|
|
131
|
+
if b_nullable
|
|
132
|
+
str = "#{str}#{delim}nullable"
|
|
133
|
+
delim = ", "
|
|
134
|
+
end
|
|
135
|
+
cdl_error("T1003 $1: unsuitable specifier for $2", str, self.class)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def clear_max
|
|
139
|
+
raise "clear_max called: #{self.class}"
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def get_type_str
|
|
143
|
+
str = ""
|
|
144
|
+
if @b_const
|
|
145
|
+
str = "#{str}const "
|
|
146
|
+
end
|
|
147
|
+
if @b_volatile
|
|
148
|
+
str = "#{str}volatile "
|
|
149
|
+
end
|
|
150
|
+
return str
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
#=== 型をチェック
|
|
154
|
+
# 正当な型定義かどうか、チェックする
|
|
155
|
+
def check
|
|
156
|
+
# 型に誤りがあれば、エラー文字列を返す
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
#=== struct の tag をチェック
|
|
160
|
+
# 正当な型定義かどうか、チェックする
|
|
161
|
+
# kind:: Decl の @kind を参照
|
|
162
|
+
def check_struct_tag(kind)
|
|
163
|
+
# tag が存在しなければエラーを出力する
|
|
164
|
+
# 配列型では、要素の型を再帰的にチェック
|
|
165
|
+
# ポインタ型では、指す先の tag チェックはしない
|
|
166
|
+
# 関数型ではパラメータリストのすべてについて行う
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
#=== 初期化可能かチェック
|
|
170
|
+
# attribute など初期化可能かチェックする(型に対し正当な初期化子が与えられているか)
|
|
171
|
+
# ident:: string 被代入変数命
|
|
172
|
+
# initialize:: Expression, Array of initializer or C_EXP
|
|
173
|
+
# 代入値、C_EXP が与えられるのは IntType の場合のみ
|
|
174
|
+
# kind:: symbol (:ATTRIBUTE, :VAR, :CONSTNAT )
|
|
175
|
+
# attribute:: NameList kind == :VAR のとき参照できる attribute
|
|
176
|
+
#
|
|
177
|
+
# locale を第一引数として取るのは、以下の理由による。
|
|
178
|
+
# このメソッドは、変数への代入が行われる「行」に対して呼び出されるが、
|
|
179
|
+
# Type クラスのインスタンスは、変数が定義された「行」を記憶している。
|
|
180
|
+
#
|
|
181
|
+
# STAGE: S
|
|
182
|
+
def check_init(locale, ident, initializer, kind, attribute = nil)
|
|
183
|
+
#
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
#=== const_val を指定の型にキャストする
|
|
187
|
+
# 派生クラスでオーバーライドしていないとエラー
|
|
188
|
+
def cast(const_val)
|
|
189
|
+
cdl_error("T1004 cannot cast to $1", self.class)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
#=== 型が一致するかのチェック
|
|
193
|
+
# 型名の字面でチェック.
|
|
194
|
+
# typedef された型も字面で一致を見るため、元の型が同じでも型名が異なれば不一致となる
|
|
195
|
+
def equal?(type2)
|
|
196
|
+
return (get_type_str == type2.get_type_str) && (get_type_str_post == type2.get_type_str_post)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
#=== bit size を得る
|
|
200
|
+
# IntType, FloatType 以外は0
|
|
201
|
+
def get_bit_size
|
|
202
|
+
return 0
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
#=== 元の型を得る
|
|
206
|
+
# typedef された型の場合、その元の型を返す.
|
|
207
|
+
# それ以外は、自分自身を返す.
|
|
208
|
+
# (DefinedType では本メソッドがオーバーライドされる)
|
|
209
|
+
def get_original_type
|
|
210
|
+
return self
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
#=== 内部にポインタ型を持つ
|
|
214
|
+
# ポインタ型、またはポインタ型メンバを持つ構造体、または要素がポインタ型を持つ配列
|
|
215
|
+
def has_pointer?
|
|
216
|
+
false
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
#=== size_is, count_is, string 指定されたポインタを持つか
|
|
220
|
+
# size_is, count_is, string 指定されたポインタ型、またはそれをメンバに持つ構造体、またはそれをを要素に持つ配列
|
|
221
|
+
def has_sized_pointer?
|
|
222
|
+
false
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
#=== 長さ指定のない string を持つ
|
|
226
|
+
# なさ指定のない string 指定されたポインタ型、またはそれをメンバに持つ構造体、またはそれを要素に持つ配列
|
|
227
|
+
def has_unsized_string?
|
|
228
|
+
false
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def show_tree(indent)
|
|
232
|
+
indent.times { print " " }
|
|
233
|
+
puts "const=#{@b_const} volatile=#{@b_volatile} #{locale_str}"
|
|
234
|
+
indent.times { print " " }
|
|
235
|
+
puts "has_pointer=#{has_pointer?} has_sized_pointer=#{has_sized_pointer?} has_unsized_string=#{has_unsized_string?}"
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
class DefinedType < Type
|
|
240
|
+
# @type_name::string
|
|
241
|
+
# @typedef::Typedef
|
|
242
|
+
# @type:: kind_of Type
|
|
243
|
+
|
|
244
|
+
include HasType
|
|
245
|
+
|
|
246
|
+
def initialize(type_name)
|
|
247
|
+
super()
|
|
248
|
+
@type_name = type_name
|
|
249
|
+
|
|
250
|
+
# mikan type_name が path になっていないため暫定
|
|
251
|
+
@typedef = Namespace.find([type_name]) # 1
|
|
252
|
+
|
|
253
|
+
# if @type.class != Typedef then
|
|
254
|
+
# raise NotTypedef
|
|
255
|
+
# end
|
|
256
|
+
if @typedef.nil?
|
|
257
|
+
cdl_error("T1005 \'$1\' not defined", type_name)
|
|
258
|
+
elsif @typedef.class != Typedef
|
|
259
|
+
cdl_error("T1006 \'$1\' not type name. expecting type name here", type_name)
|
|
260
|
+
end
|
|
261
|
+
@type = @typedef.get_declarator.get_type
|
|
262
|
+
initHasType
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
def get_type
|
|
266
|
+
clone_type
|
|
267
|
+
return @type
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def get_type_str
|
|
271
|
+
"#{super}#{@type_name}"
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def get_type_str_post
|
|
275
|
+
""
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def get_size
|
|
279
|
+
return @type.get_size
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
def is_nullable?
|
|
283
|
+
return @type.is_nullable?
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
#=== qualifier(const, volatile) の設定
|
|
287
|
+
def set_qualifier(qualifier)
|
|
288
|
+
clone_type
|
|
289
|
+
@type.set_qualifier(qualifier)
|
|
290
|
+
super
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
def set_scs(size, count, string, max = nil, b_nullable = false)
|
|
294
|
+
clone_type
|
|
295
|
+
@type.set_scs(size, count, string, max, b_nullable)
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def clear_max
|
|
299
|
+
@type.clear_max
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
def get_original_type
|
|
303
|
+
clone_type
|
|
304
|
+
return @type.get_original_type
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
def check # 意味的誤りがあれば、文字列を返す
|
|
308
|
+
nil # typedef の段階で意味チェックされている
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
def check_init(locale, ident, initializer, kind, attribute = nil)
|
|
312
|
+
get_type.check_init(locale, ident, initializer, kind, attribute)
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
#=== 内部にポインタ型を持つ
|
|
316
|
+
# ポインタ型、またはポインタ型メンバを持つ構造体、または要素がポインタ型を持つ配列
|
|
317
|
+
def has_pointer?
|
|
318
|
+
@type.has_pointer?
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
#=== size_is, count_is, string 指定されたポインタを持つか
|
|
322
|
+
# size_is, count_is, string 指定されたポインタ型、またはそれをメンバに持つ構造体、またはそれをを要素に持つ配列
|
|
323
|
+
def has_sized_pointer?
|
|
324
|
+
@type.has_sized_pointer?
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
#=== 長さ指定のない string を持つ
|
|
328
|
+
# なさ指定のない string 指定されたポインタ型、またはそれをメンバに持つ構造体、またはそれを要素に持つ配列
|
|
329
|
+
def has_unsized_string?
|
|
330
|
+
@type.has_unsized_string?
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
def show_tree(indent)
|
|
334
|
+
indent.times { print " " }
|
|
335
|
+
if @typedef.nil?
|
|
336
|
+
puts "DefinedType: #{@type_name} is missing, const=#{@b_const} volatile=#{@b_volatile} #{locale_str}"
|
|
337
|
+
else
|
|
338
|
+
puts "DefinedType: #{@type_name}, const=#{@b_const} volatile=#{@b_volatile}"
|
|
339
|
+
end
|
|
340
|
+
super(indent + 1)
|
|
341
|
+
@typedef.show_tree(indent + 1)
|
|
342
|
+
@type.show_tree(indent + 1)
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
class VoidType < Type
|
|
347
|
+
def check # 意味的誤りがあれば、文字列を返す
|
|
348
|
+
nil
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
def check_init(locale, ident, initializer, kind, attribute = nil)
|
|
352
|
+
cdl_error2(locale, "T1007 $1: void type variable cannot have initializer", ident)
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
def get_type_str
|
|
356
|
+
"#{super}void"
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
def get_type_str_post
|
|
360
|
+
""
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
def show_tree(indent)
|
|
364
|
+
indent.times { print " " }
|
|
365
|
+
puts "VoidType #{locale_str}"
|
|
366
|
+
super(indent + 1)
|
|
367
|
+
end
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
class BoolType < Type
|
|
371
|
+
def check # 意味的誤りがあれば、文字列を返す
|
|
372
|
+
nil
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
def get_type_str
|
|
376
|
+
"#{super}bool_t"
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
def get_type_str_post
|
|
380
|
+
""
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
def show_tree(indent)
|
|
384
|
+
indent.times { print " " }
|
|
385
|
+
puts "BoolType #{locale_str}"
|
|
386
|
+
super(indent + 1)
|
|
387
|
+
end
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
class IntType < Type
|
|
391
|
+
# @bit_size:: -11: char, -1: char_t, -2: short, -3: int, -4: long, -5: long long
|
|
392
|
+
# 8, 16, 32, 64, 128
|
|
393
|
+
# @sign:: :SIGNED, :UNSIGNED, nil
|
|
394
|
+
|
|
395
|
+
def initialize(bit_size)
|
|
396
|
+
super()
|
|
397
|
+
@bit_size = bit_size
|
|
398
|
+
@sign = nil
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
def set_sign(sign, b_uint = false)
|
|
402
|
+
if @sign
|
|
403
|
+
if @sign != sign
|
|
404
|
+
cdl_error("T1008 ambigous signed or unsigned")
|
|
405
|
+
end
|
|
406
|
+
elsif b_uint == false && @bit_size > 0
|
|
407
|
+
if sign == :SIGNED
|
|
408
|
+
cdl_warning("W2001 signed int$1_t: obsolete. use int$2_t", @bit_size, @bit_size)
|
|
409
|
+
else
|
|
410
|
+
cdl_warning("W2002 unsinged int$1_t: obsolete. use uint$2_t", @bit_size, @bit_size)
|
|
411
|
+
end
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
@sign = sign
|
|
415
|
+
|
|
416
|
+
if @sign != :SIGNED && @sign != :UNSIGNED
|
|
417
|
+
raise "set_sign: unknown sign: #{@sign}"
|
|
418
|
+
end
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
def check # 意味的誤りがあれば、文字列を返す
|
|
422
|
+
nil
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
def check_init(locale, ident, initializer, kind, attribute = nil)
|
|
426
|
+
val = initializer # C_EXP, Array
|
|
427
|
+
if val.instance_of?(Expression)
|
|
428
|
+
val = val.eval_const2(nil, attribute)
|
|
429
|
+
# 評価の結果 C_EXP や Array となる可能性がある
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
if val.instance_of? Token # StringVal 導入により、もはや Token は来ないはず
|
|
433
|
+
# val が Token の場合 == の右辺が String だとエラーを起こす (#198)
|
|
434
|
+
cdl_error2(locale, "T1009 $1: $2: not integer", ident, val)
|
|
435
|
+
return
|
|
436
|
+
elsif val.is_a? C_EXP
|
|
437
|
+
# #192 var が attribute を参照し、attribute の右辺が C_EXP の場合
|
|
438
|
+
# const の右辺が C_EXP の場合も
|
|
439
|
+
return
|
|
440
|
+
elsif val.is_a? FloatVal
|
|
441
|
+
cdl_error2(locale, "T1011 $1: need cast to assign float to integer", ident)
|
|
442
|
+
return
|
|
443
|
+
elsif val.instance_of? Array
|
|
444
|
+
cdl_error2(locale, "T1017 $1: unsuitable initializer for scalar type", ident)
|
|
445
|
+
return
|
|
446
|
+
elsif val.nil?
|
|
447
|
+
cdl_error2(locale, "T1010 $1: initializer is not constant", ident)
|
|
448
|
+
return
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
if !val.is_a? IntegerVal
|
|
452
|
+
cdl_error2(locale, "T1012 $1: $2: not integer", ident, val)
|
|
453
|
+
return
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
val = val.to_i
|
|
457
|
+
max = get_max
|
|
458
|
+
min = get_min
|
|
459
|
+
dbgPrint "sign=#{@sign} ident=#{ident} val=#{val} max=#{max} min=#{min}\n"
|
|
460
|
+
|
|
461
|
+
if !max.nil?
|
|
462
|
+
if val > max
|
|
463
|
+
if @sign == :SIGNED || @sign.nil?
|
|
464
|
+
cdl_error2(locale, "T1013 $1: too large (max=$2)", ident, max)
|
|
465
|
+
else
|
|
466
|
+
cdl_error2(locale, "T1016 $1: too large (max=$2)", ident, max)
|
|
467
|
+
end
|
|
468
|
+
end
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
if !min.nil?
|
|
472
|
+
if val < min
|
|
473
|
+
if @sign == :SIGNED || @sign.nil?
|
|
474
|
+
cdl_error2(locale, "T1014 $1: too large negative value (min=$2)", ident, min)
|
|
475
|
+
else
|
|
476
|
+
cdl_error2(locale, "T1015 $1: negative value for unsigned", ident)
|
|
477
|
+
end
|
|
478
|
+
end
|
|
479
|
+
end
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
#=== IntType# 最大値、最小値をチェックしてクリップする
|
|
483
|
+
# キャスト演算を行う
|
|
484
|
+
# in_val:: IntegerVal, FloatVal: この型にキャストする値
|
|
485
|
+
# from_type:: Symbol: :IntType, :FloatType IntType の場合はビット数でクリップ、FloatType の場合は最大値でクリップ
|
|
486
|
+
def check_and_clip(in_val, from_type = :IntType)
|
|
487
|
+
bit_size = get_bit_size
|
|
488
|
+
if bit_size == -1
|
|
489
|
+
bit_size = 8
|
|
490
|
+
end
|
|
491
|
+
val = in_val.to_i
|
|
492
|
+
if get_max && val > get_max
|
|
493
|
+
if from_type == :IntType
|
|
494
|
+
rval = ((1 << bit_size) - 1) & val # bit 数でクリップ
|
|
495
|
+
else
|
|
496
|
+
rval = get_max # 最大値でクリップ (FloatType)
|
|
497
|
+
end
|
|
498
|
+
cdl_warning("W2003 $1: too large to cast to $2, clipped($3)", in_val, get_type_str, rval)
|
|
499
|
+
elsif get_min && val < get_min
|
|
500
|
+
if from_type == :IntType
|
|
501
|
+
rval = ((1 << bit_size) - 1) & val
|
|
502
|
+
else
|
|
503
|
+
rval = get_min
|
|
504
|
+
end
|
|
505
|
+
if @sign == :SIGNED || @sign.nil?
|
|
506
|
+
cdl_warning("W2004 $1: too small to cast to $2, clipped($3)", in_val, get_type_str, rval)
|
|
507
|
+
else # @sign == :UNSIGNED || @sign == nil (char の場合)
|
|
508
|
+
cdl_warning("W2005 $1: negative value for unsigned: convert to $2", in_val, rval)
|
|
509
|
+
end
|
|
510
|
+
else
|
|
511
|
+
rval = val
|
|
512
|
+
end
|
|
513
|
+
return rval
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
def get_min
|
|
517
|
+
if @sign == :SIGNED || @sign.nil?
|
|
518
|
+
if @bit_size == -1
|
|
519
|
+
bit_sz = 8 # char_t は、有符号に扱う
|
|
520
|
+
else
|
|
521
|
+
bit_sz = @bit_size
|
|
522
|
+
end
|
|
523
|
+
case bit_sz
|
|
524
|
+
when 8, 16, 32, 64, 128
|
|
525
|
+
return - (1 << (bit_sz - 1))
|
|
526
|
+
else # -1, -2, -3, -4, -5, -11
|
|
527
|
+
return nil
|
|
528
|
+
end
|
|
529
|
+
else # @sign == :UNSIGNED
|
|
530
|
+
return 0
|
|
531
|
+
end
|
|
532
|
+
end
|
|
533
|
+
|
|
534
|
+
def get_max
|
|
535
|
+
if @bit_size == -1
|
|
536
|
+
if @sign.nil?
|
|
537
|
+
return 255 # char_t は、無符号に扱う
|
|
538
|
+
else
|
|
539
|
+
bit_sz = 8
|
|
540
|
+
end
|
|
541
|
+
else
|
|
542
|
+
bit_sz = @bit_size
|
|
543
|
+
end
|
|
544
|
+
if @sign == :SIGNED || @sign.nil?
|
|
545
|
+
case bit_sz
|
|
546
|
+
when 8, 16, 32, 64, 128
|
|
547
|
+
return (1 << (bit_sz - 1)) - 1
|
|
548
|
+
else # -1, -2, -3, -4, -5, -11
|
|
549
|
+
return nil
|
|
550
|
+
end
|
|
551
|
+
else # @sign == :UNSIGNED
|
|
552
|
+
case bit_sz
|
|
553
|
+
when 8, 16, 32, 64, 128
|
|
554
|
+
return (1 << bit_sz) - 1
|
|
555
|
+
else # -2, -3, -4, -5, -11
|
|
556
|
+
return nil
|
|
557
|
+
end
|
|
558
|
+
end
|
|
559
|
+
end
|
|
560
|
+
|
|
561
|
+
#=== IntType# C 言語における型名(修飾子付き)
|
|
562
|
+
def get_type_str
|
|
563
|
+
str = super
|
|
564
|
+
|
|
565
|
+
# NEW_MODE
|
|
566
|
+
case @sign
|
|
567
|
+
when :SIGNED
|
|
568
|
+
sign = ""
|
|
569
|
+
signL = "signed "
|
|
570
|
+
when :UNSIGNED
|
|
571
|
+
sign = "u"
|
|
572
|
+
signL = "unsigned "
|
|
573
|
+
else
|
|
574
|
+
sign = ""
|
|
575
|
+
signL = ""
|
|
576
|
+
end
|
|
577
|
+
|
|
578
|
+
# p "get_type_str: sign:#{@sign} signL=#{signL}"
|
|
579
|
+
|
|
580
|
+
case @bit_size
|
|
581
|
+
when -1 # char_t 型
|
|
582
|
+
if @sign == :SIGNED
|
|
583
|
+
sign = "s"
|
|
584
|
+
end
|
|
585
|
+
str = "#{str}#{sign}char_t"
|
|
586
|
+
when -11 # char 型(obsolete)
|
|
587
|
+
str = "#{str}#{signL}char"
|
|
588
|
+
when -2 # short 型
|
|
589
|
+
str = "#{str}#{signL}short"
|
|
590
|
+
when -3 # int 型
|
|
591
|
+
str = "#{str}#{signL}int"
|
|
592
|
+
when -4 # long 型
|
|
593
|
+
str = "#{str}#{signL}long"
|
|
594
|
+
when -5 # long long 型
|
|
595
|
+
str = "#{str}#{signL}long long"
|
|
596
|
+
when 8, 16, 32, 64, 128 # int16, int32, int64, int128 型
|
|
597
|
+
str = "#{str}#{sign}int#{@bit_size}_t"
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
return str
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
#=== IntType# C 言語における型名(後置文字列)
|
|
604
|
+
def get_type_str_post
|
|
605
|
+
""
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
#=== IntType#bit_size を得る
|
|
609
|
+
# 返される値は @bit_size の仕様を参照
|
|
610
|
+
def get_bit_size
|
|
611
|
+
return @bit_size
|
|
612
|
+
end
|
|
613
|
+
|
|
614
|
+
#=== IntType# sign を得る
|
|
615
|
+
# @sign の説明を参照
|
|
616
|
+
def get_sign
|
|
617
|
+
@sign
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
def show_tree(indent)
|
|
621
|
+
indent.times { print " " }
|
|
622
|
+
puts "IntType bit_size=#{@bit_size} sign=#{@sign} const=#{@b_const} volatile=#{@b_volatile} #{locale_str}"
|
|
623
|
+
super(indent + 1)
|
|
624
|
+
end
|
|
625
|
+
end
|
|
626
|
+
|
|
627
|
+
class FloatType < Type
|
|
628
|
+
# @bit_size:: 32, 64, (80), -32, -64, -128
|
|
629
|
+
|
|
630
|
+
def initialize(bit_size)
|
|
631
|
+
super()
|
|
632
|
+
@bit_size = bit_size
|
|
633
|
+
end
|
|
634
|
+
|
|
635
|
+
def check # 意味的誤りがあれば、文字列を返す
|
|
636
|
+
nil
|
|
637
|
+
end
|
|
638
|
+
|
|
639
|
+
# mikan Float 型の C_EXP 対応 (generate.rb にも変更必要)
|
|
640
|
+
def check_init(locale, ident, initializer, kind, attribute = nil)
|
|
641
|
+
# 型に対する初期値に誤りがあれば、エラー文字列を返す
|
|
642
|
+
val = initializer
|
|
643
|
+
if val.instance_of?(Expression)
|
|
644
|
+
val = val.eval_const2(nil, attribute)
|
|
645
|
+
# 評価の結果 C_EXP や Array となる可能性がある
|
|
646
|
+
end
|
|
647
|
+
|
|
648
|
+
if val.instance_of? Token
|
|
649
|
+
# val が Token の場合 == の右辺が String だとエラーを起こす
|
|
650
|
+
cdl_error2(locale, "T1018 $1: $2: not number", ident, val)
|
|
651
|
+
return
|
|
652
|
+
elsif val.instance_of? Array
|
|
653
|
+
cdl_error2(locale, "T1020 $1: unsuitable initializer for scalar type", ident)
|
|
654
|
+
return
|
|
655
|
+
elsif val.instance_of? C_EXP
|
|
656
|
+
return
|
|
657
|
+
elsif val.nil?
|
|
658
|
+
cdl_error2(locale, "T1019 $1: initializer is not constant", ident)
|
|
659
|
+
return
|
|
660
|
+
elsif !val.is_a?(IntegerVal) && !val.is_a?(FloatVal)
|
|
661
|
+
cdl_error2(locale, "T1037 $1: not number", ident)
|
|
662
|
+
return
|
|
663
|
+
end
|
|
664
|
+
# else
|
|
665
|
+
# cdl_error2( locale, "T1020 $1: unsuitable initializer for scalar type" , ident )
|
|
666
|
+
# return
|
|
667
|
+
# end
|
|
668
|
+
return
|
|
669
|
+
end
|
|
670
|
+
|
|
671
|
+
def get_type_str
|
|
672
|
+
str = super
|
|
673
|
+
|
|
674
|
+
case @bit_size
|
|
675
|
+
when 32
|
|
676
|
+
str = "#{str}float32_t"
|
|
677
|
+
when 64
|
|
678
|
+
str = "#{str}double64_t"
|
|
679
|
+
when -32
|
|
680
|
+
str = "#{str}float"
|
|
681
|
+
when -64
|
|
682
|
+
str = "#{str}double"
|
|
683
|
+
when -128
|
|
684
|
+
str = "#{str}long double"
|
|
685
|
+
end
|
|
686
|
+
return str
|
|
687
|
+
end
|
|
688
|
+
|
|
689
|
+
def get_type_str_post
|
|
690
|
+
""
|
|
691
|
+
end
|
|
692
|
+
|
|
693
|
+
def get_bit_size
|
|
694
|
+
@bit_size
|
|
695
|
+
end
|
|
696
|
+
|
|
697
|
+
def show_tree(indent)
|
|
698
|
+
indent.times { print " " }
|
|
699
|
+
puts "FloatType bit_size=#{@bit_size} qualifier=#{@qualifier} #{locale_str}"
|
|
700
|
+
super(indent + 1)
|
|
701
|
+
end
|
|
702
|
+
end
|
|
703
|
+
|
|
704
|
+
class EnumType < Type # mikan
|
|
705
|
+
# @bit_size:: -1: enum
|
|
706
|
+
# 8, 16, 32, 64, 128
|
|
707
|
+
# @element:: []
|
|
708
|
+
# @element_val:: []
|
|
709
|
+
|
|
710
|
+
def initialize(bit_size)
|
|
711
|
+
super()
|
|
712
|
+
@bit_size = bit_size
|
|
713
|
+
end
|
|
714
|
+
|
|
715
|
+
def check
|
|
716
|
+
# mikan enum check
|
|
717
|
+
end
|
|
718
|
+
|
|
719
|
+
def show_tree(indent)
|
|
720
|
+
indent.times { print " " }
|
|
721
|
+
puts "EnumType bit_size=#{@bit_size} qualifier=#{@qualifier} #{locale_str}"
|
|
722
|
+
super(indent + 1)
|
|
723
|
+
# mikan element
|
|
724
|
+
end
|
|
725
|
+
end
|
|
726
|
+
|
|
727
|
+
class StructType < Type
|
|
728
|
+
# @tag::
|
|
729
|
+
# @b_define:: true if define, false if refer
|
|
730
|
+
# @members_decl:: NamedList
|
|
731
|
+
# @definition:: StructType
|
|
732
|
+
# @b_has_pointer_member:: bool : メンバにポインタ型がある
|
|
733
|
+
# @b_has_sized_pointer_member:: bool : メンバにポインタ型がある
|
|
734
|
+
# @b_has_unsized_string_member:: bool : メンバにポインタ型がある
|
|
735
|
+
# @b_hasTag:: bool : タグがある
|
|
736
|
+
# @member_types_symbol:: Symbol : tag が無い時のみ設定 (それ以外では nil)
|
|
737
|
+
|
|
738
|
+
@@structtype_current_stack = []
|
|
739
|
+
@@structtype_current_sp = -1
|
|
740
|
+
|
|
741
|
+
# tag なし struct
|
|
742
|
+
@@no_struct_tag_num = 0
|
|
743
|
+
@@no_tag_struct_list = {}
|
|
744
|
+
|
|
745
|
+
def initialize(tag = nil)
|
|
746
|
+
super()
|
|
747
|
+
@tag = tag
|
|
748
|
+
if tag
|
|
749
|
+
@b_hasTag = true
|
|
750
|
+
else
|
|
751
|
+
@b_hasTag = false
|
|
752
|
+
end
|
|
753
|
+
@@structtype_current_sp += 1
|
|
754
|
+
@@structtype_current_stack[@@structtype_current_sp] = self
|
|
755
|
+
@b_has_pointer_member = false
|
|
756
|
+
@b_has_sized_pointer_member = false
|
|
757
|
+
@b_has_unsized_string_member = false
|
|
758
|
+
@member_types_symbol = nil
|
|
759
|
+
end
|
|
760
|
+
|
|
761
|
+
def self.set_define(b_define)
|
|
762
|
+
@@structtype_current_stack[@@structtype_current_sp].set_define(b_define)
|
|
763
|
+
end
|
|
764
|
+
|
|
765
|
+
def set_define(b_define)
|
|
766
|
+
@b_define = b_define
|
|
767
|
+
if @b_define
|
|
768
|
+
@members_decl = NamedList.new(nil, "in struct #{@tag}")
|
|
769
|
+
# if @tag then 登録タイミングを終わりに変更 V1.0.2.19
|
|
770
|
+
# Namespace.new_structtype( self )
|
|
771
|
+
# end
|
|
772
|
+
else
|
|
773
|
+
@definition = Namespace.find_tag(@tag)
|
|
774
|
+
# check_struct_tag に移す V1.0.2.19
|
|
775
|
+
# if @definition == nil then
|
|
776
|
+
# cdl_error( "T1021 \'$1\': struct not defined" , @tag )
|
|
777
|
+
# end
|
|
778
|
+
end
|
|
779
|
+
end
|
|
780
|
+
|
|
781
|
+
def self.new_member(member_decl)
|
|
782
|
+
@@structtype_current_stack[@@structtype_current_sp].new_member(member_decl)
|
|
783
|
+
end
|
|
784
|
+
|
|
785
|
+
def new_member(member_decl)
|
|
786
|
+
member_decl.set_owner self # Decl (StructType)
|
|
787
|
+
@members_decl.add_item(member_decl)
|
|
788
|
+
if member_decl.get_type.has_pointer?
|
|
789
|
+
@b_has_pointer_member = true
|
|
790
|
+
end
|
|
791
|
+
if member_decl.get_type.has_sized_pointer?
|
|
792
|
+
@b_has_sized_pointer_member = true
|
|
793
|
+
end
|
|
794
|
+
if member_decl.get_type.has_unsized_string?
|
|
795
|
+
@b_has_unsized_string_member = true
|
|
796
|
+
end
|
|
797
|
+
end
|
|
798
|
+
|
|
799
|
+
def check # 意味的誤りがあれば、文字列を返す
|
|
800
|
+
nil
|
|
801
|
+
end
|
|
802
|
+
|
|
803
|
+
#=== 構造体のタグをチェック
|
|
804
|
+
# declarator の時点でチェックする
|
|
805
|
+
# kind:: Decl の @kind を参照
|
|
806
|
+
def check_struct_tag(kind)
|
|
807
|
+
if @tag.nil?
|
|
808
|
+
return
|
|
809
|
+
end
|
|
810
|
+
|
|
811
|
+
st = Namespace.find_tag(@tag)
|
|
812
|
+
if st.nil?
|
|
813
|
+
cdl_error("T1022 struct $1: not defined", @tag)
|
|
814
|
+
end
|
|
815
|
+
end
|
|
816
|
+
|
|
817
|
+
# mikan Float 型の C_EXP 対応 (generate.rb にも変更必要)
|
|
818
|
+
def check_init(locale, ident, initializer, kind, attribute = nil)
|
|
819
|
+
st = Namespace.find_tag(@tag)
|
|
820
|
+
if st.nil?
|
|
821
|
+
cdl_error2(locale, "T1023 struct $1: not defined", @tag)
|
|
822
|
+
return
|
|
823
|
+
end
|
|
824
|
+
|
|
825
|
+
# 初期化子が式の場合、型(タグ)が一致するかチェック
|
|
826
|
+
if initializer.instance_of?(Expression)
|
|
827
|
+
t = initializer.get_type(attribute)
|
|
828
|
+
# print "Check init #{t.class} #{t.get_name}\n"
|
|
829
|
+
if !t.is_a?(StructType)
|
|
830
|
+
if t
|
|
831
|
+
str = t.get_type_str
|
|
832
|
+
else
|
|
833
|
+
str = "unknown"
|
|
834
|
+
end
|
|
835
|
+
cdl_error2(locale, "T1038 $1: initializer type mismatch. '$2' & '$3'", ident, get_type_str, str)
|
|
836
|
+
elsif @tag != t.get_name
|
|
837
|
+
cdl_error2(locale, "T1039 $1: struct tag mismatch $2 and $3", ident, @tag, t.get_name)
|
|
838
|
+
end
|
|
839
|
+
initializer = initializer.eval_const(attribute)
|
|
840
|
+
end
|
|
841
|
+
|
|
842
|
+
if initializer.instance_of?(Array)
|
|
843
|
+
i = 0
|
|
844
|
+
st.get_members_decl.get_items.each {|d|
|
|
845
|
+
if initializer[i]
|
|
846
|
+
d.get_type.check_init(locale, "#{ident}.#{d.get_identifier}", initializer[i], kind)
|
|
847
|
+
end
|
|
848
|
+
i += 1
|
|
849
|
+
}
|
|
850
|
+
else
|
|
851
|
+
cdl_error2(locale, "T1024 $1: unsuitable initializer for struct", ident)
|
|
852
|
+
end
|
|
853
|
+
end
|
|
854
|
+
|
|
855
|
+
def self.end_of_parse
|
|
856
|
+
@@structtype_current_stack[@@structtype_current_sp].end_of_parse
|
|
857
|
+
@@structtype_current_sp -= 1
|
|
858
|
+
end
|
|
859
|
+
|
|
860
|
+
def end_of_parse
|
|
861
|
+
if @members_decl.nil? # @b_define = false またはメンバーのない構造体(エラー)
|
|
862
|
+
return
|
|
863
|
+
end
|
|
864
|
+
@members_decl.get_items.each{|md|
|
|
865
|
+
size = md.get_size_is
|
|
866
|
+
if size
|
|
867
|
+
val = size.eval_const(@members_decl)
|
|
868
|
+
if val.nil?
|
|
869
|
+
type = size.get_type(@members_decl)
|
|
870
|
+
if !type.is_a?(IntType)
|
|
871
|
+
cdl_error("T1025 size_is argument is not integer type")
|
|
872
|
+
end
|
|
873
|
+
end
|
|
874
|
+
end
|
|
875
|
+
count = md.get_count_is
|
|
876
|
+
if count
|
|
877
|
+
val = count.eval_const(@members_decl)
|
|
878
|
+
if val.nil?
|
|
879
|
+
type = count.get_type(@members_decl)
|
|
880
|
+
if !type.is_a?(IntType)
|
|
881
|
+
cdl_error("T1026 count_is argument is not integer type")
|
|
882
|
+
end
|
|
883
|
+
end
|
|
884
|
+
end
|
|
885
|
+
string = md.get_string
|
|
886
|
+
if string == -1
|
|
887
|
+
# 長さ指定なし
|
|
888
|
+
elsif string
|
|
889
|
+
val = string.eval_const(@members_decl)
|
|
890
|
+
if val.nil?
|
|
891
|
+
type = string.get_type(@members_decl)
|
|
892
|
+
if !type.is_a?(IntType)
|
|
893
|
+
cdl_error("T1027 string argument is not integer type")
|
|
894
|
+
end
|
|
895
|
+
end
|
|
896
|
+
end
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
if @tag.nil?
|
|
900
|
+
@member_types_symbol = get_member_types_symbol
|
|
901
|
+
# print "member_types_symbol = #{get_member_types_symbol}\n"
|
|
902
|
+
if @@no_tag_struct_list[@member_types_symbol]
|
|
903
|
+
@tag = @@no_tag_struct_list[@member_types_symbol]
|
|
904
|
+
else
|
|
905
|
+
@tag = :"TAG_#{@@no_struct_tag_num}_TECS_internal__"
|
|
906
|
+
@@no_struct_tag_num += 1
|
|
907
|
+
@@no_tag_struct_list[@member_types_symbol] = @tag
|
|
908
|
+
Namespace.new_structtype(self)
|
|
909
|
+
end
|
|
910
|
+
else
|
|
911
|
+
if @b_define
|
|
912
|
+
Namespace.new_structtype(self)
|
|
913
|
+
end
|
|
914
|
+
end
|
|
915
|
+
end
|
|
916
|
+
|
|
917
|
+
def get_name
|
|
918
|
+
@tag
|
|
919
|
+
end
|
|
920
|
+
|
|
921
|
+
def get_type_str # mikan struct get_type_str
|
|
922
|
+
str = super
|
|
923
|
+
|
|
924
|
+
if @b_hasTag
|
|
925
|
+
# typedef struct tag StructType; の形式の場合
|
|
926
|
+
# struct の本体は、別に生成される
|
|
927
|
+
return "#{str}struct #{@tag}"
|
|
928
|
+
|
|
929
|
+
else
|
|
930
|
+
# typedef struct { int a; } StructType; の形式の場合
|
|
931
|
+
str += "struct {"
|
|
932
|
+
@members_decl.get_items.each{|i|
|
|
933
|
+
str += sprintf("%s %s%s;", i.get_type.get_type_str, i.get_name, i.get_type.get_type_str_post)
|
|
934
|
+
}
|
|
935
|
+
str += "} "
|
|
936
|
+
|
|
937
|
+
return str
|
|
938
|
+
|
|
939
|
+
end
|
|
940
|
+
end
|
|
941
|
+
|
|
942
|
+
def get_type_str_post
|
|
943
|
+
""
|
|
944
|
+
end
|
|
945
|
+
|
|
946
|
+
def get_members_decl
|
|
947
|
+
return @members_decl if @members_decl
|
|
948
|
+
|
|
949
|
+
st = Namespace.find_tag(@tag)
|
|
950
|
+
if st
|
|
951
|
+
return st.get_members_decl
|
|
952
|
+
end
|
|
953
|
+
|
|
954
|
+
return nil
|
|
955
|
+
end
|
|
956
|
+
|
|
957
|
+
def has_pointer?
|
|
958
|
+
if @definition
|
|
959
|
+
return @definition.has_pointer?
|
|
960
|
+
else
|
|
961
|
+
return @b_has_pointer_member
|
|
962
|
+
end
|
|
963
|
+
end
|
|
964
|
+
|
|
965
|
+
def has_sized_pointer?
|
|
966
|
+
if @definition
|
|
967
|
+
return @definition.has_sized_pointer?
|
|
968
|
+
else
|
|
969
|
+
return @b_has_sized_pointer_member
|
|
970
|
+
end
|
|
971
|
+
end
|
|
972
|
+
|
|
973
|
+
def has_unsized_string?
|
|
974
|
+
if @definition
|
|
975
|
+
return @definition.has_unsized_string?
|
|
976
|
+
else
|
|
977
|
+
return @b_has_unsized_string_member
|
|
978
|
+
end
|
|
979
|
+
end
|
|
980
|
+
|
|
981
|
+
#=== 同じ構造体かどうかチェックする
|
|
982
|
+
# tag のチェックは行わない
|
|
983
|
+
# すべてのメンバの名前と型が一致することを確認する
|
|
984
|
+
def same?(another)
|
|
985
|
+
md = another.get_members_decl
|
|
986
|
+
if @members_decl.nil? || md.nil?
|
|
987
|
+
return false
|
|
988
|
+
end
|
|
989
|
+
|
|
990
|
+
md1 = @members_decl.get_items
|
|
991
|
+
md2 = md.get_items
|
|
992
|
+
if md1.length != md2.length
|
|
993
|
+
return false
|
|
994
|
+
end
|
|
995
|
+
|
|
996
|
+
i = 0
|
|
997
|
+
while i < md1.length
|
|
998
|
+
if md1[i].get_name != md2[i].get_name ||
|
|
999
|
+
md1[i].get_type.get_type_str != md2[i].get_type.get_type_str ||
|
|
1000
|
+
md1[i].get_type.get_type_str_post != md2[i].get_type.get_type_str_post
|
|
1001
|
+
return false
|
|
1002
|
+
end
|
|
1003
|
+
i += 1
|
|
1004
|
+
end
|
|
1005
|
+
|
|
1006
|
+
return true
|
|
1007
|
+
end
|
|
1008
|
+
|
|
1009
|
+
def get_member_types_symbol
|
|
1010
|
+
mts = ""
|
|
1011
|
+
@members_decl.get_items.each {|member|
|
|
1012
|
+
mts += member.get_type.get_type_str + member.get_type.get_type_str_post + ";"
|
|
1013
|
+
}
|
|
1014
|
+
return mts.to_sym
|
|
1015
|
+
end
|
|
1016
|
+
|
|
1017
|
+
def show_tree(indent)
|
|
1018
|
+
indent.times { print " " }
|
|
1019
|
+
puts "StructType tag: #{@tag} qualifier=#{@qualifier} has_pointer=#{@b_has_pointer_member} #{locale_str}"
|
|
1020
|
+
super(indent + 1)
|
|
1021
|
+
if @b_define
|
|
1022
|
+
@members_decl.show_tree(indent + 1)
|
|
1023
|
+
end
|
|
1024
|
+
end
|
|
1025
|
+
end
|
|
1026
|
+
|
|
1027
|
+
class FuncType < Type
|
|
1028
|
+
# @paramlist:: ParamList
|
|
1029
|
+
# @type:: return type : PtrType, ArrayType, FuncType, IntType, FloatType, ...
|
|
1030
|
+
# @b_oneway:: bool: true, false
|
|
1031
|
+
# @has_in:: bool : has [in] parameter
|
|
1032
|
+
# @has_inout:: bool : has [inout] parameter
|
|
1033
|
+
# @has_out:: bool : has [out] parameter
|
|
1034
|
+
# @has_send:: bool : has [send] parameter
|
|
1035
|
+
# @has_receive:: bool : has [receive] parameter
|
|
1036
|
+
|
|
1037
|
+
def initialize(paramlist = nil)
|
|
1038
|
+
super()
|
|
1039
|
+
|
|
1040
|
+
@has_in = false
|
|
1041
|
+
@has_inout = false
|
|
1042
|
+
@has_out = false
|
|
1043
|
+
@has_send = false
|
|
1044
|
+
@has_receive = false
|
|
1045
|
+
|
|
1046
|
+
@paramlist = paramlist
|
|
1047
|
+
@b_oneway = false
|
|
1048
|
+
if paramlist
|
|
1049
|
+
paramlist.check_param
|
|
1050
|
+
else
|
|
1051
|
+
@paramlist = ParamList.new(nil)
|
|
1052
|
+
end
|
|
1053
|
+
@paramlist.set_owner self # ParamList
|
|
1054
|
+
@paramlist.get_items.each{|p|
|
|
1055
|
+
case p.get_direction
|
|
1056
|
+
when :IN
|
|
1057
|
+
@has_in = true
|
|
1058
|
+
when :INOUT
|
|
1059
|
+
@has_inout = true
|
|
1060
|
+
when :OUT
|
|
1061
|
+
@has_out = true
|
|
1062
|
+
when :SEND
|
|
1063
|
+
@has_send = true
|
|
1064
|
+
when :RECEIVE
|
|
1065
|
+
@has_receive = true
|
|
1066
|
+
else
|
|
1067
|
+
raise "unkown direction"
|
|
1068
|
+
end
|
|
1069
|
+
}
|
|
1070
|
+
end
|
|
1071
|
+
|
|
1072
|
+
def check # 意味的誤りがあれば、文字列を返す
|
|
1073
|
+
if @type.class == ArrayType # 配列を返す関数
|
|
1074
|
+
return "function returning array"
|
|
1075
|
+
elsif @type.class == FuncType # 関数を返す関数
|
|
1076
|
+
return "function returning function"
|
|
1077
|
+
end
|
|
1078
|
+
return @type.check # 関数の return する型のチェック
|
|
1079
|
+
|
|
1080
|
+
# パラメータの型のチェックは ParamList#check_param で行う
|
|
1081
|
+
end
|
|
1082
|
+
|
|
1083
|
+
def check_struct_tag(kind)
|
|
1084
|
+
@type.check_struct_tag kind
|
|
1085
|
+
# ParamDecl でもチェックされるので、ここではチェックしない
|
|
1086
|
+
# @paramlist.check_struct_tag kind
|
|
1087
|
+
end
|
|
1088
|
+
|
|
1089
|
+
def check_init(locale, ident, initializer, kind, attribute = nil)
|
|
1090
|
+
cdl_error2(locale, "T1028 $1: cannot initialize function pointer", ident)
|
|
1091
|
+
return
|
|
1092
|
+
end
|
|
1093
|
+
|
|
1094
|
+
def set_type(type)
|
|
1095
|
+
unless @type
|
|
1096
|
+
@type = type
|
|
1097
|
+
else
|
|
1098
|
+
@type.set_type(type)
|
|
1099
|
+
end
|
|
1100
|
+
end
|
|
1101
|
+
|
|
1102
|
+
#=== return type を返す
|
|
1103
|
+
#
|
|
1104
|
+
# return type を返す
|
|
1105
|
+
# get_return_type とすべきだった
|
|
1106
|
+
def get_type
|
|
1107
|
+
@type
|
|
1108
|
+
end
|
|
1109
|
+
|
|
1110
|
+
def get_type_str
|
|
1111
|
+
return @type.get_type_str
|
|
1112
|
+
end
|
|
1113
|
+
|
|
1114
|
+
def get_type_str_post
|
|
1115
|
+
# 型だけを返す (仮引数の名前を含めない)
|
|
1116
|
+
@paramlist.to_str(false)
|
|
1117
|
+
end
|
|
1118
|
+
|
|
1119
|
+
def get_paramlist
|
|
1120
|
+
@paramlist
|
|
1121
|
+
end
|
|
1122
|
+
|
|
1123
|
+
def set_oneway(b_oneway)
|
|
1124
|
+
@b_oneway = b_oneway
|
|
1125
|
+
|
|
1126
|
+
if (@type.get_type_str != "ER" && @type.get_type_str != "void") || @type.get_type_str_post != ""
|
|
1127
|
+
cdl_error("T1029 oneway function cannot return type \'$1$2\', \'void\' or \'ER\' is permitted", @type.get_type_str, @type.get_type_str_post)
|
|
1128
|
+
end
|
|
1129
|
+
|
|
1130
|
+
if @paramlist
|
|
1131
|
+
@paramlist.get_items.each{|p|
|
|
1132
|
+
if p.get_direction != :IN && p.get_direction != :SEND
|
|
1133
|
+
cdl_error("T1030 oneway function cannot have $1 parameter for \'$2\'", p.get_direction, p.get_name)
|
|
1134
|
+
end
|
|
1135
|
+
}
|
|
1136
|
+
end
|
|
1137
|
+
end
|
|
1138
|
+
|
|
1139
|
+
def is_oneway?
|
|
1140
|
+
@b_oneway
|
|
1141
|
+
end
|
|
1142
|
+
|
|
1143
|
+
#=== Push Pop Allocator が必要か?
|
|
1144
|
+
# Transparent RPC の場合 oneway かつ in の配列(size_is, count_is, string のいずれかで修飾)がある
|
|
1145
|
+
def need_PPAllocator?(b_opaque = false)
|
|
1146
|
+
if @b_oneway || b_opaque
|
|
1147
|
+
return @paramlist.need_PPAllocator?(b_opaque)
|
|
1148
|
+
else
|
|
1149
|
+
return false
|
|
1150
|
+
end
|
|
1151
|
+
end
|
|
1152
|
+
|
|
1153
|
+
#=== パラメータが in, inout, out, send, receive を持つか
|
|
1154
|
+
def has_in?
|
|
1155
|
+
@has_in
|
|
1156
|
+
end
|
|
1157
|
+
|
|
1158
|
+
def has_inout?
|
|
1159
|
+
@has_inout
|
|
1160
|
+
end
|
|
1161
|
+
|
|
1162
|
+
def has_out?
|
|
1163
|
+
@has_out
|
|
1164
|
+
end
|
|
1165
|
+
|
|
1166
|
+
def has_send?
|
|
1167
|
+
@has_send
|
|
1168
|
+
end
|
|
1169
|
+
|
|
1170
|
+
def has_receive?
|
|
1171
|
+
@has_receive
|
|
1172
|
+
end
|
|
1173
|
+
|
|
1174
|
+
#=== 入力方向のパラメータを持つか
|
|
1175
|
+
def has_inward?
|
|
1176
|
+
@has_in || @has_inout || @has_send
|
|
1177
|
+
end
|
|
1178
|
+
|
|
1179
|
+
#=== 出力方向のパラメータを持つか
|
|
1180
|
+
def has_outward?
|
|
1181
|
+
@has_inout || @has_out || @has_receive
|
|
1182
|
+
end
|
|
1183
|
+
|
|
1184
|
+
def show_tree(indent)
|
|
1185
|
+
indent.times { print " " }
|
|
1186
|
+
if @b_oneway
|
|
1187
|
+
puts "FunctType: oneway=true #{locale_str}"
|
|
1188
|
+
else
|
|
1189
|
+
puts "FunctType: oneway=false #{locale_str}"
|
|
1190
|
+
end
|
|
1191
|
+
super(indent + 1)
|
|
1192
|
+
if @paramlist
|
|
1193
|
+
@paramlist.show_tree(indent + 1)
|
|
1194
|
+
end
|
|
1195
|
+
(indent + 1).times { print " " }
|
|
1196
|
+
puts "return type:"
|
|
1197
|
+
@type.show_tree(indent + 2)
|
|
1198
|
+
end
|
|
1199
|
+
end
|
|
1200
|
+
|
|
1201
|
+
class ArrayType < Type
|
|
1202
|
+
# @type:: element type : ArrayType, FuncType, IntType, FloatType, ...
|
|
1203
|
+
# @subscript:: Expression, nil if '[]'
|
|
1204
|
+
|
|
1205
|
+
include HasType
|
|
1206
|
+
|
|
1207
|
+
def initialize(subscript = nil)
|
|
1208
|
+
super()
|
|
1209
|
+
@subscript = subscript
|
|
1210
|
+
initHasType
|
|
1211
|
+
end
|
|
1212
|
+
|
|
1213
|
+
def set_type(type)
|
|
1214
|
+
unless @type
|
|
1215
|
+
@type = type
|
|
1216
|
+
else
|
|
1217
|
+
@type.set_type(type)
|
|
1218
|
+
end
|
|
1219
|
+
end
|
|
1220
|
+
|
|
1221
|
+
#=== Array#qualifier(const, volatile) の設定
|
|
1222
|
+
def set_qualifier(qualifier)
|
|
1223
|
+
clone_type
|
|
1224
|
+
@type.set_qualifier(qualifier)
|
|
1225
|
+
super
|
|
1226
|
+
end
|
|
1227
|
+
|
|
1228
|
+
# 配列要素が const なら const
|
|
1229
|
+
def is_const?
|
|
1230
|
+
@type.is_const?
|
|
1231
|
+
end
|
|
1232
|
+
|
|
1233
|
+
# 配列要素が volatile なら volatile
|
|
1234
|
+
def is_volatile?
|
|
1235
|
+
@type.is_volatile?
|
|
1236
|
+
end
|
|
1237
|
+
|
|
1238
|
+
def get_type
|
|
1239
|
+
@type
|
|
1240
|
+
end
|
|
1241
|
+
|
|
1242
|
+
def get_subscript
|
|
1243
|
+
@subscript
|
|
1244
|
+
end
|
|
1245
|
+
|
|
1246
|
+
def get_type_str
|
|
1247
|
+
return @type.get_type_str.to_s
|
|
1248
|
+
end
|
|
1249
|
+
|
|
1250
|
+
def get_type_str_post
|
|
1251
|
+
if @subscript
|
|
1252
|
+
"[#{@subscript.eval_const(nil)}]#{@type.get_type_str_post}"
|
|
1253
|
+
else
|
|
1254
|
+
"[]#{@type.get_type_str_post}"
|
|
1255
|
+
end
|
|
1256
|
+
# "[#{@subscript.to_s}]#{@type.get_type_str_post}"
|
|
1257
|
+
end
|
|
1258
|
+
|
|
1259
|
+
def check # 意味的誤りがあれば、文字列を返す
|
|
1260
|
+
if @type.class == FuncType # 関数の配列
|
|
1261
|
+
return "array of function"
|
|
1262
|
+
elsif @type.class == ArrayType # 添数なし配列の配列
|
|
1263
|
+
unless @type.get_subscript
|
|
1264
|
+
return "subscript not specified"
|
|
1265
|
+
end
|
|
1266
|
+
end
|
|
1267
|
+
|
|
1268
|
+
return @type.check # 配列要素の型をチェック
|
|
1269
|
+
end
|
|
1270
|
+
|
|
1271
|
+
def check_struct_tag(kind)
|
|
1272
|
+
@type.check_struct_tag kind
|
|
1273
|
+
end
|
|
1274
|
+
|
|
1275
|
+
def check_init(locale, ident, initializer, kind, attribute = nil)
|
|
1276
|
+
if initializer.instance_of?(Array)
|
|
1277
|
+
# 要素数が指定されている場合、初期化要素数をチェック
|
|
1278
|
+
if @subscript
|
|
1279
|
+
n_sub = @subscript.eval_const(nil)
|
|
1280
|
+
if n_sub
|
|
1281
|
+
if initializer.length > n_sub
|
|
1282
|
+
cdl_error2(locale, "T9999 $1: too many initializer, $2 for $3", ident, initializer.length, n_sub)
|
|
1283
|
+
end
|
|
1284
|
+
end
|
|
1285
|
+
end
|
|
1286
|
+
index = 0
|
|
1287
|
+
initializer.each{|i|
|
|
1288
|
+
@type.check_init(locale, "#{ident}[#{index}]", i, kind, attribute = nil)
|
|
1289
|
+
index += 1
|
|
1290
|
+
}
|
|
1291
|
+
else
|
|
1292
|
+
cdl_error2(locale, "T1031 $1: unsuitable initializer for array", ident)
|
|
1293
|
+
end
|
|
1294
|
+
end
|
|
1295
|
+
|
|
1296
|
+
def has_pointer?
|
|
1297
|
+
@type.has_pointer?
|
|
1298
|
+
end
|
|
1299
|
+
|
|
1300
|
+
def has_sized_pointer?
|
|
1301
|
+
@type.has_sized_pointer?
|
|
1302
|
+
end
|
|
1303
|
+
|
|
1304
|
+
def has_unsized_string?
|
|
1305
|
+
@type.has_unsized_string?
|
|
1306
|
+
end
|
|
1307
|
+
|
|
1308
|
+
def show_tree(indent)
|
|
1309
|
+
indent.times { print " " }
|
|
1310
|
+
puts "ArrayType: #{locale_str}"
|
|
1311
|
+
super(indent + 1)
|
|
1312
|
+
(indent + 1).times { print " " }
|
|
1313
|
+
puts "type:"
|
|
1314
|
+
@type.show_tree(indent + 2)
|
|
1315
|
+
(indent + 1).times { print " " }
|
|
1316
|
+
puts "subscript:"
|
|
1317
|
+
if @subscript
|
|
1318
|
+
@subscript.show_tree(indent + 2)
|
|
1319
|
+
else
|
|
1320
|
+
(indent + 2).times { print " " }
|
|
1321
|
+
puts "no subscript"
|
|
1322
|
+
end
|
|
1323
|
+
end
|
|
1324
|
+
end
|
|
1325
|
+
|
|
1326
|
+
class PtrType < Type
|
|
1327
|
+
# @type:: refer to : PtrType, FuncType, ArrayType, IntType, FloatType, ...
|
|
1328
|
+
# @size:: Expr, or nil if not specified
|
|
1329
|
+
# @count:: Expr, or nil if not specified
|
|
1330
|
+
# @string:: Expr or -1(if size not specified) (string 引数), or nil if not specified
|
|
1331
|
+
|
|
1332
|
+
include HasType
|
|
1333
|
+
|
|
1334
|
+
def initialize(referto = nil)
|
|
1335
|
+
super()
|
|
1336
|
+
@type = referto
|
|
1337
|
+
@size = nil
|
|
1338
|
+
@count = nil
|
|
1339
|
+
@string = nil
|
|
1340
|
+
initHasType
|
|
1341
|
+
end
|
|
1342
|
+
|
|
1343
|
+
def set_type(type)
|
|
1344
|
+
unless @type
|
|
1345
|
+
@type = type
|
|
1346
|
+
else
|
|
1347
|
+
@type.set_type(type) # 枝先の type を設定
|
|
1348
|
+
end
|
|
1349
|
+
end
|
|
1350
|
+
|
|
1351
|
+
def get_type_str
|
|
1352
|
+
if @type.is_a?(ArrayType) || @type.is_a?(FuncType)
|
|
1353
|
+
parenthes = "("
|
|
1354
|
+
else
|
|
1355
|
+
parenthes = ""
|
|
1356
|
+
end
|
|
1357
|
+
return "#{@type.get_type_str}#{parenthes}*"
|
|
1358
|
+
end
|
|
1359
|
+
|
|
1360
|
+
def get_type_str_post
|
|
1361
|
+
if @type.is_a?(ArrayType) || @type.is_a?(FuncType)
|
|
1362
|
+
parenthes = ")"
|
|
1363
|
+
else
|
|
1364
|
+
parenthes = ""
|
|
1365
|
+
end
|
|
1366
|
+
"#{parenthes}#{@type.get_type_str_post}"
|
|
1367
|
+
end
|
|
1368
|
+
|
|
1369
|
+
def check # 意味的誤りがあれば、文字列を返す
|
|
1370
|
+
return nil if @type.nil?
|
|
1371
|
+
@type.check
|
|
1372
|
+
end
|
|
1373
|
+
|
|
1374
|
+
def check_struct_tag(kind)
|
|
1375
|
+
if kind != :MEMBER # 構造体メンバーの場合、ポインタの先の構造体タグをチェックしない
|
|
1376
|
+
@type.check_struct_tag kind
|
|
1377
|
+
end
|
|
1378
|
+
end
|
|
1379
|
+
|
|
1380
|
+
def check_init(locale, ident, initializer, kind, attribute = nil)
|
|
1381
|
+
if initializer.instance_of?(Expression)
|
|
1382
|
+
val = initializer.eval_const2(nil, attribute)
|
|
1383
|
+
if val.is_a? PointerVal
|
|
1384
|
+
type = val.get_type # PtrType
|
|
1385
|
+
t1 = self
|
|
1386
|
+
t2 = type
|
|
1387
|
+
while t1.is_a?(PtrType) && t2.is_a?(PtrType)
|
|
1388
|
+
t1 = t1.get_type
|
|
1389
|
+
t2 = t2.get_type
|
|
1390
|
+
if (t1.class == t2.class) && (t1.get_bit_size == t2.get_bit_size)
|
|
1391
|
+
elsif (t1.is_a?(CDefinedType) || t2.is_a?(CDefinedType)) && t1.get_type_str == t2.get_type_str && t1.get_type_str_post && t2.get_type_str_post
|
|
1392
|
+
# int8_t などが、一方は .h に定義されているケース
|
|
1393
|
+
else
|
|
1394
|
+
cdl_error2(locale, "T1032 $1: incompatible pointer type", ident)
|
|
1395
|
+
break
|
|
1396
|
+
end
|
|
1397
|
+
end
|
|
1398
|
+
elsif val.is_a? IntegerVal
|
|
1399
|
+
if val.to_i != 0
|
|
1400
|
+
cdl_error2(locale, "T1033 $1: need cast to assign integer to pointer", ident)
|
|
1401
|
+
end
|
|
1402
|
+
elsif val.is_a? StringVal
|
|
1403
|
+
# 文字列定数
|
|
1404
|
+
# mikan L"wide string"
|
|
1405
|
+
if @type.get_bit_size != -1 && @type.get_bit_size != -11 # -1: char_t
|
|
1406
|
+
cdl_error2(locale, "T1034 $1: unsuitable string constant", ident)
|
|
1407
|
+
end
|
|
1408
|
+
elsif val.instance_of?(Array)
|
|
1409
|
+
i = 0
|
|
1410
|
+
val.each {|ini|
|
|
1411
|
+
@type.check_init(locale, "#{ident}[#{i}]", ini, kind, attribute = nil)
|
|
1412
|
+
i += 1
|
|
1413
|
+
}
|
|
1414
|
+
elsif val.instance_of?(C_EXP)
|
|
1415
|
+
|
|
1416
|
+
else
|
|
1417
|
+
cdl_error2(locale, "T1035 $1: unsuitable initializer for pointer", ident)
|
|
1418
|
+
end
|
|
1419
|
+
elsif initializer.instance_of?(Array)
|
|
1420
|
+
if @size.nil? && @count.nil?
|
|
1421
|
+
cdl_error2(locale, "T9999 $1: non-size_is pointer cannot have array initializer", ident)
|
|
1422
|
+
end
|
|
1423
|
+
|
|
1424
|
+
i = 0
|
|
1425
|
+
initializer.each {|ini|
|
|
1426
|
+
@type.check_init(locale, "#{ident}[#{i}]", ini, kind, attribute = nil)
|
|
1427
|
+
i += 1
|
|
1428
|
+
}
|
|
1429
|
+
elsif initializer.instance_of?(C_EXP)
|
|
1430
|
+
|
|
1431
|
+
else
|
|
1432
|
+
cdl_error2(locale, "T1036 $1: unsuitable initializer for pointer", ident)
|
|
1433
|
+
end
|
|
1434
|
+
end
|
|
1435
|
+
|
|
1436
|
+
def get_referto
|
|
1437
|
+
clone_type
|
|
1438
|
+
@type
|
|
1439
|
+
end
|
|
1440
|
+
|
|
1441
|
+
def set_scs(size, count, string, max, b_nullable)
|
|
1442
|
+
@size = size
|
|
1443
|
+
@count = count
|
|
1444
|
+
@max = max
|
|
1445
|
+
@b_nullable = b_nullable
|
|
1446
|
+
|
|
1447
|
+
# string は最も左側の ptr に作用する
|
|
1448
|
+
if @type.is_a?(PtrType)
|
|
1449
|
+
# ptr_level が 2 以上であることは ParamDecl#initializer でチェックされる
|
|
1450
|
+
clone_type
|
|
1451
|
+
@type.set_scs(nil, nil, string, nil, false)
|
|
1452
|
+
elsif @type.is_a?(VoidType) && (size || count || string)
|
|
1453
|
+
str = ""
|
|
1454
|
+
if size
|
|
1455
|
+
str = "size_is"
|
|
1456
|
+
end
|
|
1457
|
+
if count
|
|
1458
|
+
if str
|
|
1459
|
+
str += ", "
|
|
1460
|
+
end
|
|
1461
|
+
str += "count_is"
|
|
1462
|
+
end
|
|
1463
|
+
if string
|
|
1464
|
+
if str
|
|
1465
|
+
str += ", "
|
|
1466
|
+
end
|
|
1467
|
+
str += "string"
|
|
1468
|
+
end
|
|
1469
|
+
|
|
1470
|
+
cdl_error("T1040 $1 specified for void pointer type", str)
|
|
1471
|
+
else
|
|
1472
|
+
@string = string
|
|
1473
|
+
end
|
|
1474
|
+
|
|
1475
|
+
if !@size.nil? && (@b_nullable != false)
|
|
1476
|
+
cdl_error("T9999 size_is & nullable cannot be specified simultaneously. If size is zero, pointer must be null")
|
|
1477
|
+
end
|
|
1478
|
+
end
|
|
1479
|
+
|
|
1480
|
+
def clear_max
|
|
1481
|
+
@max = nil
|
|
1482
|
+
end
|
|
1483
|
+
|
|
1484
|
+
def get_size
|
|
1485
|
+
@size
|
|
1486
|
+
end
|
|
1487
|
+
|
|
1488
|
+
def get_count
|
|
1489
|
+
@count
|
|
1490
|
+
end
|
|
1491
|
+
|
|
1492
|
+
def get_string
|
|
1493
|
+
@string
|
|
1494
|
+
end
|
|
1495
|
+
|
|
1496
|
+
#=== PtrType# size_is の最大値
|
|
1497
|
+
def get_max
|
|
1498
|
+
@max
|
|
1499
|
+
end
|
|
1500
|
+
|
|
1501
|
+
def is_nullable?
|
|
1502
|
+
return @b_nullable
|
|
1503
|
+
end
|
|
1504
|
+
|
|
1505
|
+
def get_type
|
|
1506
|
+
clone_type
|
|
1507
|
+
@type
|
|
1508
|
+
end
|
|
1509
|
+
|
|
1510
|
+
def has_pointer?
|
|
1511
|
+
true
|
|
1512
|
+
end
|
|
1513
|
+
|
|
1514
|
+
def has_sized_pointer?
|
|
1515
|
+
!@size.nil? || !@count.nil? || @string.instance_of?(Expression) || @type.has_sized_pointer?
|
|
1516
|
+
end
|
|
1517
|
+
|
|
1518
|
+
def has_unsized_string?
|
|
1519
|
+
@string == -1 || @type.has_unsized_string?
|
|
1520
|
+
end
|
|
1521
|
+
|
|
1522
|
+
def show_tree(indent)
|
|
1523
|
+
indent.times { print " " }
|
|
1524
|
+
puts "PtrType: qualifier=#{@qualifier}, nullable=#{@b_nullable} #{locale_str}"
|
|
1525
|
+
super(indent + 1)
|
|
1526
|
+
(indent + 1).times { print " " }
|
|
1527
|
+
if @size
|
|
1528
|
+
print "size=#{@size}, "
|
|
1529
|
+
else
|
|
1530
|
+
print "size=nil, "
|
|
1531
|
+
end
|
|
1532
|
+
if @max
|
|
1533
|
+
print "max=#{@size}, "
|
|
1534
|
+
else
|
|
1535
|
+
print "max=nil, "
|
|
1536
|
+
end
|
|
1537
|
+
if @count
|
|
1538
|
+
print "count=#{@count}, "
|
|
1539
|
+
else
|
|
1540
|
+
print "count=nil, "
|
|
1541
|
+
end
|
|
1542
|
+
if @string
|
|
1543
|
+
if @string.instance_of?(Expression)
|
|
1544
|
+
print "string=#{@string}\n"
|
|
1545
|
+
else
|
|
1546
|
+
print "string=yes\n"
|
|
1547
|
+
end
|
|
1548
|
+
else
|
|
1549
|
+
print "string=nil\n"
|
|
1550
|
+
end
|
|
1551
|
+
|
|
1552
|
+
(indent + 1).times { print " " }
|
|
1553
|
+
puts "type:"
|
|
1554
|
+
@type.show_tree(indent + 2)
|
|
1555
|
+
end
|
|
1556
|
+
end
|
|
1557
|
+
|
|
1558
|
+
#== DescriptorType クラス
|
|
1559
|
+
# 動的結合で渡すデスクリプタ型
|
|
1560
|
+
class DescriptorType < Type
|
|
1561
|
+
# @sinagure_nsp::NamespacePath
|
|
1562
|
+
|
|
1563
|
+
@@descriptors = {}
|
|
1564
|
+
|
|
1565
|
+
def initialize(signature_nsp)
|
|
1566
|
+
@signature_nsp = signature_nsp
|
|
1567
|
+
# check_signature ##
|
|
1568
|
+
@@descriptors[self] = false
|
|
1569
|
+
end
|
|
1570
|
+
|
|
1571
|
+
def get_type_str
|
|
1572
|
+
"Descriptor( #{@signature_nsp.get_global_name} )"
|
|
1573
|
+
end
|
|
1574
|
+
|
|
1575
|
+
def get_type_str_post
|
|
1576
|
+
""
|
|
1577
|
+
end
|
|
1578
|
+
|
|
1579
|
+
def set_qualifier(qualifier)
|
|
1580
|
+
cdl_error("T9999 '$1' cannot be specified for Descriptor", qualfier.to_s)
|
|
1581
|
+
end
|
|
1582
|
+
|
|
1583
|
+
def check
|
|
1584
|
+
end
|
|
1585
|
+
|
|
1586
|
+
def check_init(locale, ident, initializer, kind, attribute = nil)
|
|
1587
|
+
case kind
|
|
1588
|
+
when :PARAMETER
|
|
1589
|
+
# 引数は初期化できない
|
|
1590
|
+
else
|
|
1591
|
+
cdl_error2(locale, "T9999 Descriptor cannot be used for $1", kind)
|
|
1592
|
+
end
|
|
1593
|
+
end
|
|
1594
|
+
|
|
1595
|
+
def self.check_signature
|
|
1596
|
+
@@descriptors.each{|desc, val|
|
|
1597
|
+
if val != true
|
|
1598
|
+
desc.check_signature
|
|
1599
|
+
@@descriptors[desc] = true
|
|
1600
|
+
end
|
|
1601
|
+
}
|
|
1602
|
+
end
|
|
1603
|
+
|
|
1604
|
+
def check_signature
|
|
1605
|
+
# p "Desc #{@signature_nsp.to_s}"
|
|
1606
|
+
obj = Namespace.find @signature_nsp
|
|
1607
|
+
if !obj.is_a? Signature
|
|
1608
|
+
cdl_error("T9999 '$1': not signature or not found", @signature_nsp.to_s)
|
|
1609
|
+
else
|
|
1610
|
+
if obj.has_descriptor?
|
|
1611
|
+
# cdl_error( "T9999 '$1': has Descriptor in function parameter", @signature_nsp.to_s )
|
|
1612
|
+
end
|
|
1613
|
+
# @signature_nsp = obj.get_namespace_path
|
|
1614
|
+
end
|
|
1615
|
+
end
|
|
1616
|
+
|
|
1617
|
+
#== DescriptorType#
|
|
1618
|
+
def get_signature
|
|
1619
|
+
Namespace.find @signature_nsp
|
|
1620
|
+
end
|
|
1621
|
+
end
|
|
1622
|
+
|
|
1623
|
+
# 以下単体テストコード
|
|
1624
|
+
if $unit_test
|
|
1625
|
+
puts("===== Unit Test: IntType ===== (types.rb)")
|
|
1626
|
+
sizes = [8, 16, 32, 64]
|
|
1627
|
+
sizes.each{|n|
|
|
1628
|
+
int = IntType.new n
|
|
1629
|
+
printf("%8s max: %d min:%d\n", "int#{n}_t", int.get_max, int.get_min)
|
|
1630
|
+
}
|
|
1631
|
+
puts ""
|
|
1632
|
+
end
|