Class: Compiler
- Inherits:
-
Object
- Object
- Compiler
- Defined in:
- lib/compiler.rb
Instance Attribute Summary collapse
-
#errors ⇒ Object
readonly
Returns the value of attribute errors.
-
#runtime ⇒ Object
readonly
Returns the value of attribute runtime.
Instance Method Summary collapse
- #add_error(error) ⇒ Object
- #check_case(type, initial_case, ast) ⇒ Object
- #check_type_nodes(member_type_ast, member_type_def) ⇒ Object
- #check_type_param_count(ast, expected_count) ⇒ Object
- #check_type_unique(ast) ⇒ Object
- #check_unique(type, old_def, new_ast) ⇒ Object
- #compile(filename) ⇒ Object
- #compile_ast(runtime, ast) ⇒ Object
- #compile_direction(direction_ast) ⇒ Object
- #compile_enum(enum_ast) ⇒ Object
- #compile_file(filename) ⇒ Object
- #compile_include(include_ast) ⇒ Object
- #compile_message(direction_def, message_ast) ⇒ Object
- #compile_node(node_ast) ⇒ Object
- #compile_sequence(sequence_ast) ⇒ Object
- #compile_step(step_ast) ⇒ Object
- #compile_struct(struct_ast) ⇒ Object
- #get_member_type(nodes_to_check, member_type_ast) ⇒ Object
- #get_type(ast, raise_error) ⇒ Object
-
#initialize ⇒ Compiler
constructor
A new instance of Compiler.
Constructor Details
#initialize ⇒ Compiler
Returns a new instance of Compiler.
20 21 22 23 24 |
# File 'lib/compiler.rb', line 20 def initialize @errors = [] = 0 = 0 end |
Instance Attribute Details
#errors ⇒ Object (readonly)
Returns the value of attribute errors.
18 19 20 |
# File 'lib/compiler.rb', line 18 def errors @errors end |
#runtime ⇒ Object (readonly)
Returns the value of attribute runtime.
18 19 20 |
# File 'lib/compiler.rb', line 18 def runtime @runtime end |
Instance Method Details
#add_error(error) ⇒ Object
285 286 287 |
# File 'lib/compiler.rb', line 285 def add_error error @errors.push error end |
#check_case(type, initial_case, ast) ⇒ Object
257 258 259 260 261 262 263 |
# File 'lib/compiler.rb', line 257 def check_case type, initial_case, ast if type == 'node_nick' and initial_case != ast.nickname[0].char_case add_error InitialCaseError.new type, initial_case, ast elsif initial_case != ast.name[0].char_case add_error InitialCaseError.new type, initial_case, ast end end |
#check_type_nodes(member_type_ast, member_type_def) ⇒ Object
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/compiler.rb', line 230 def check_type_nodes member_type_ast, member_type_def return if @runtime == member_type_def.runtime @runtime.nodes.each do |n| external_node = member_type_def.runtime.nodes.find { |node| n.name == node.name } if external_node == nil add_error CorrespondingNodeNotFoundError.new member_type_def, n.name return end if external_node.language != n.language add_error NodeLanguageMismatchError.new member_type_def, n, external_node return end end end |
#check_type_param_count(ast, expected_count) ⇒ Object
281 282 283 |
# File 'lib/compiler.rb', line 281 def check_type_param_count ast, expected_count add_error TypeParamCountMismatchError.new ast, expected_count if ast.params.length != expected_count end |
#check_type_unique(ast) ⇒ Object
265 266 267 268 269 270 271 272 273 274 |
# File 'lib/compiler.rb', line 265 def check_type_unique ast type_def, _ = self.get_type ast, false return if type_def == nil if type_def.is_a? BuiltinTypeDef add_error BuiltinNameConflictError.new ast else self.check_unique 'type', type_def, ast end end |
#check_unique(type, old_def, new_ast) ⇒ Object
276 277 278 279 |
# File 'lib/compiler.rb', line 276 def check_unique type, old_def, new_ast return if old_def == nil add_error DuplicateDefError.new type, old_def.name, old_def.ast, new_ast end |
#compile(filename) ⇒ Object
26 27 28 |
# File 'lib/compiler.rb', line 26 def compile filename @runtime = self.compile_file filename end |
#compile_ast(runtime, ast) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/compiler.rb', line 44 def compile_ast runtime, ast @runtime = runtime ast.each do |decl| begin case decl when IncludeDecl compile_include decl when EnumDecl compile_enum decl when NodeDecl compile_node decl when StructDecl compile_struct decl when DirectionDecl compile_direction decl when SequenceDecl compile_sequence decl end rescue CompilerError => e @errors.push e end end end |
#compile_direction(direction_ast) ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/compiler.rb', line 114 def compile_direction direction_ast client = @runtime.nodes[direction_ast.client] if client == nil add_error NodeNotFoundError.new direction_ast, direction_ast.client return end server = @runtime.nodes[direction_ast.server] if server == nil add_error NodeNotFoundError.new direction_ast, direction_ast.server return end if client == server add_error ClientServerSameError.new direction_ast return end += 1000 = 0 old_direction = @runtime.get_direction client, direction_ast.direction, server self.check_unique 'direction', old_direction, direction_ast direction_def = DirectionDef.new direction_ast, client, server direction_ast..each do || self.check_case 'message', :upper, self.check_unique 'message', direction_def.[.name], direction_def. self. direction_def, end @runtime.add_direction direction_def end |
#compile_enum(enum_ast) ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/compiler.rb', line 78 def compile_enum enum_ast self.check_case 'enum', :upper, enum_ast self.check_type_unique enum_ast enum_def = EnumTypeDef.new enum_ast enum_ast.elements.each do |element_ast| self.check_case 'enum element', :upper, element_ast self.check_unique 'enum element', enum_def.elements[element_ast.name], element_ast element_def = EnumElementDef.new element_ast enum_def.add_element element_def end @runtime.add_enum enum_def end |
#compile_file(filename) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/compiler.rb', line 30 def compile_file filename content = File.read filename, encoding: 'utf-8' tokens = Lexer::lex content, filename begin ast = Parser::parse tokens rescue RLTK::NotInLanguage => e add_error UnexpectedTokenError.new e.current return end runtime = Runtime.new filename self.compile_ast runtime, ast runtime end |
#compile_include(include_ast) ⇒ Object
68 69 70 71 72 73 74 75 76 |
# File 'lib/compiler.rb', line 68 def compile_include include_ast filename = include_ast.filename + '.b' if not File.exists? filename add_error IncludeFileNotFoundError.new filename, include_ast.position return end include_runtime = self.compile_file filename @runtime.add_include include_runtime end |
#compile_message(direction_def, message_ast) ⇒ Object
147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/compiler.rb', line 147 def direction_def, += 1 = MessageDef.new , + .members.each do |member_ast| self.check_case 'message member', :lower, member_ast self.check_unique 'message member', .get_member(member_ast.name), member_ast nodes_to_check = [direction_def.client, direction_def.server] member_type_def = self.get_member_type nodes_to_check, member_ast.type member_def = MemberDef.new member_ast, member_type_def .add_member member_def end end |
#compile_node(node_ast) ⇒ Object
91 92 93 94 95 96 97 98 |
# File 'lib/compiler.rb', line 91 def compile_node node_ast self.check_case 'node', :upper, node_ast self.check_case 'node_nick', :upper, node_ast self.check_unique 'node', @runtime.nodes[node_ast.name], node_ast self.check_unique 'node', @runtime.nodes[node_ast.nickname], node_ast node_def = NodeDef.new node_ast @runtime.add_node node_def end |
#compile_sequence(sequence_ast) ⇒ Object
162 163 164 165 166 167 168 169 170 |
# File 'lib/compiler.rb', line 162 def compile_sequence sequence_ast self.check_case 'sequence', :upper, sequence_ast self.check_unique 'sequence', @runtime.get_sequence(sequence_ast.name), sequence_ast sequence_def = SequenceDef.new sequence_ast sequence_ast.steps.each do |step_ast| sequence_def.add_step self.compile_step step_ast end @runtime.add_sequence sequence_def end |
#compile_step(step_ast) ⇒ Object
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/compiler.rb', line 172 def compile_step step_ast client = @runtime.nodes[step_ast.client] if client == nil add_error NodeNotFoundError.new step_ast, step_ast.client return nil end server = @runtime.nodes[step_ast.server] if server == nil add_error NodeNotFoundError.new step_ast, step_ast.server return nil end if client == server add_error ClientServerSameError.new step_ast return nil end direction_def = @runtime.get_direction client, step_ast.direction, server if direction_def == nil add_error DirectionNotFoundError.new step_ast, client, step_ast.direction, server return nil end = direction_def.[step_ast.] if == nil add_error MessageNotFoundError.new step_ast, direction_def return nil end StepDef.new step_ast, direction_def, end |
#compile_struct(struct_ast) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/compiler.rb', line 100 def compile_struct struct_ast self.check_case 'struct', :upper, struct_ast self.check_type_unique struct_ast struct_def = StructTypeDef.new struct_ast struct_ast.members.each do |member_ast| self.check_case 'struct member', :lower, member_ast self.check_unique 'struct member', struct_def.get_member(member_ast.name), member_ast member_type_def = self.get_member_type @runtime.nodes.values, member_ast.type member_def = MemberDef.new member_ast, member_type_def struct_def.add_member member_def end @runtime.add_struct struct_def end |
#get_member_type(nodes_to_check, member_type_ast) ⇒ Object
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/compiler.rb', line 205 def get_member_type nodes_to_check, member_type_ast type_def, runtime = self.get_type member_type_ast, true return nil if type_def == nil params = [] case type_def.name when 'List' self.check_type_param_count member_type_ast, 1 params.push self.get_member_type nodes_to_check, member_type_ast.params[0] when 'Set' self.check_type_param_count member_type_ast, 1 params.push self.get_member_type nodes_to_check, member_type_ast.params[0] when 'Map' self.check_type_param_count member_type_ast, 2 params.push self.get_member_type nodes_to_check, member_type_ast.params[0] params.push self.get_member_type nodes_to_check, member_type_ast.params[1] else self.check_type_param_count member_type_ast, 0 end member_type_def = TypeInstanceDef.new member_type_ast, type_def, params, runtime self.check_type_nodes member_type_ast, member_type_def member_type_def end |
#get_type(ast, raise_error) ⇒ Object
247 248 249 250 251 252 253 254 255 |
# File 'lib/compiler.rb', line 247 def get_type ast, raise_error return nil if ast == nil type_def, runtime = @runtime.get_type ast.name return type_def, runtime if type_def != nil add_error TypeNotFoundError.new ast, ast.name if raise_error return type_def, runtime end |