t-ruby 0.0.40 → 0.0.41
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 +4 -4
- data/lib/t_ruby/compiler.rb +107 -4
- data/lib/t_ruby/ir.rb +7 -3
- data/lib/t_ruby/parser.rb +181 -6
- data/lib/t_ruby/string_utils.rb +80 -0
- data/lib/t_ruby/version.rb +1 -1
- data/lib/t_ruby.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6a7c7a93e1498a150b541ea7f7838c08435a33ead72774b7e4c0b8ead951e9d3
|
|
4
|
+
data.tar.gz: 1fbfb9ea6b276e130ef04891f39d691e362d5352dc4f0209b00009105f13c3a0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 82cbc96204194f51b65f484aeda25383e285ce902c325e269766e77871e9dccacc548111e864ba2bfb27ca48fc69c7e22c5a0b1eee8e7c25e4763417ffe2c8fe
|
|
7
|
+
data.tar.gz: ed5f8ad72344e624e8a95d1e9a48078e0f6679d914f978974e0117b75bbc11ce2fbe08ece39360b20ce777ef5c5c333f37376f216272c1e6aa983eb18585fc92
|
data/lib/t_ruby/compiler.rb
CHANGED
|
@@ -505,6 +505,7 @@ module TRuby
|
|
|
505
505
|
params = []
|
|
506
506
|
current = ""
|
|
507
507
|
depth = 0
|
|
508
|
+
brace_depth = 0
|
|
508
509
|
|
|
509
510
|
params_str.each_char do |char|
|
|
510
511
|
case char
|
|
@@ -514,9 +515,16 @@ module TRuby
|
|
|
514
515
|
when ">", "]", ")"
|
|
515
516
|
depth -= 1
|
|
516
517
|
current += char
|
|
518
|
+
when "{"
|
|
519
|
+
brace_depth += 1
|
|
520
|
+
current += char
|
|
521
|
+
when "}"
|
|
522
|
+
brace_depth -= 1
|
|
523
|
+
current += char
|
|
517
524
|
when ","
|
|
518
|
-
if depth.zero?
|
|
519
|
-
|
|
525
|
+
if depth.zero? && brace_depth.zero?
|
|
526
|
+
cleaned = clean_param(current.strip)
|
|
527
|
+
params.concat(Array(cleaned)) if cleaned
|
|
520
528
|
current = ""
|
|
521
529
|
else
|
|
522
530
|
current += char
|
|
@@ -526,12 +534,39 @@ module TRuby
|
|
|
526
534
|
end
|
|
527
535
|
end
|
|
528
536
|
|
|
529
|
-
|
|
537
|
+
cleaned = clean_param(current.strip) unless current.empty?
|
|
538
|
+
params.concat(Array(cleaned)) if cleaned
|
|
530
539
|
params.join(", ")
|
|
531
540
|
end
|
|
532
541
|
|
|
533
542
|
# Clean a single parameter (remove type annotation, preserve default value)
|
|
543
|
+
# Returns String or Array of Strings (for keyword args group)
|
|
534
544
|
def clean_param(param)
|
|
545
|
+
param = param.strip
|
|
546
|
+
return nil if param.empty?
|
|
547
|
+
|
|
548
|
+
# 1. 더블 스플랫: **name: Type -> **name
|
|
549
|
+
if param.start_with?("**")
|
|
550
|
+
match = param.match(/^\*\*(\w+)(?::\s*.+)?$/)
|
|
551
|
+
return "**#{match[1]}" if match
|
|
552
|
+
|
|
553
|
+
return param
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
# 2. 키워드 인자 그룹: { ... } 또는 { ... }: InterfaceName
|
|
557
|
+
if param.start_with?("{")
|
|
558
|
+
return clean_keyword_args_group(param)
|
|
559
|
+
end
|
|
560
|
+
|
|
561
|
+
# 3. Hash 리터럴: name: { ... } -> name
|
|
562
|
+
if param.match?(/^\w+:\s*\{/)
|
|
563
|
+
match = param.match(/^(\w+):\s*\{.+\}(?::\s*\w+)?$/)
|
|
564
|
+
return match[1] if match
|
|
565
|
+
|
|
566
|
+
return param
|
|
567
|
+
end
|
|
568
|
+
|
|
569
|
+
# 4. 일반 파라미터: name: Type = value -> name = value 또는 name: Type -> name
|
|
535
570
|
# Match: name: Type = value (with default value)
|
|
536
571
|
if (match = param.match(/^(#{TRuby::IDENTIFIER_CHAR}+)\s*:\s*.+?\s*(=\s*.+)$/))
|
|
537
572
|
"#{match[1]} #{match[2]}"
|
|
@@ -543,15 +578,83 @@ module TRuby
|
|
|
543
578
|
end
|
|
544
579
|
end
|
|
545
580
|
|
|
581
|
+
# 키워드 인자 그룹을 Ruby 키워드 인자로 변환
|
|
582
|
+
# { name: String, age: Integer = 0 } -> name:, age: 0
|
|
583
|
+
# { name:, age: 0 }: UserParams -> name:, age: 0
|
|
584
|
+
def clean_keyword_args_group(param)
|
|
585
|
+
# { ... }: InterfaceName 또는 { ... } 형태 파싱
|
|
586
|
+
interface_match = param.match(/^\{(.+)\}\s*:\s*\w+\s*$/)
|
|
587
|
+
inline_match = param.match(/^\{(.+)\}\s*$/) unless interface_match
|
|
588
|
+
|
|
589
|
+
inner_content = if interface_match
|
|
590
|
+
interface_match[1]
|
|
591
|
+
elsif inline_match
|
|
592
|
+
inline_match[1]
|
|
593
|
+
else
|
|
594
|
+
return param
|
|
595
|
+
end
|
|
596
|
+
|
|
597
|
+
# 내부 파라미터 분리
|
|
598
|
+
parts = split_nested_content(inner_content)
|
|
599
|
+
keyword_params = []
|
|
600
|
+
|
|
601
|
+
parts.each do |part|
|
|
602
|
+
part = part.strip
|
|
603
|
+
next if part.empty?
|
|
604
|
+
|
|
605
|
+
if interface_match
|
|
606
|
+
# interface 참조: name: default_value 또는 name:
|
|
607
|
+
if (match = part.match(/^(\w+):\s*(.*)$/))
|
|
608
|
+
name = match[1]
|
|
609
|
+
default_value = match[2].strip
|
|
610
|
+
keyword_params << if default_value.empty?
|
|
611
|
+
"#{name}:"
|
|
612
|
+
else
|
|
613
|
+
"#{name}: #{default_value}"
|
|
614
|
+
end
|
|
615
|
+
end
|
|
616
|
+
elsif (match = part.match(/^(\w+):\s*(.+)$/))
|
|
617
|
+
# 인라인 타입: name: Type = default 또는 name: Type
|
|
618
|
+
name = match[1]
|
|
619
|
+
type_and_default = match[2].strip
|
|
620
|
+
|
|
621
|
+
# Type = default 분리
|
|
622
|
+
default_value = extract_default_value(type_and_default)
|
|
623
|
+
keyword_params << if default_value
|
|
624
|
+
"#{name}: #{default_value}"
|
|
625
|
+
else
|
|
626
|
+
"#{name}:"
|
|
627
|
+
end
|
|
628
|
+
end
|
|
629
|
+
end
|
|
630
|
+
|
|
631
|
+
keyword_params
|
|
632
|
+
end
|
|
633
|
+
|
|
634
|
+
# 중첩된 내용을 콤마로 분리
|
|
635
|
+
def split_nested_content(content)
|
|
636
|
+
StringUtils.split_by_comma(content)
|
|
637
|
+
end
|
|
638
|
+
|
|
639
|
+
# 타입과 기본값에서 기본값만 추출
|
|
640
|
+
def extract_default_value(type_and_default)
|
|
641
|
+
StringUtils.extract_default_value(type_and_default)
|
|
642
|
+
end
|
|
643
|
+
|
|
546
644
|
# Erase return type annotations
|
|
547
645
|
def erase_return_types(source)
|
|
548
646
|
result = source.dup
|
|
549
647
|
|
|
550
|
-
# Remove return type: ): Type or ): Type<Foo> etc.
|
|
648
|
+
# Remove return type after parentheses: ): Type or ): Type<Foo> etc.
|
|
551
649
|
result.gsub!(/\)\s*:\s*[^\n]+?(?=\s*$)/m) do |_match|
|
|
552
650
|
")"
|
|
553
651
|
end
|
|
554
652
|
|
|
653
|
+
# Remove return type for methods without parentheses: def method_name: Type
|
|
654
|
+
result.gsub!(/^(\s*#{TRuby::VISIBILITY_PATTERN}def\s+#{TRuby::METHOD_NAME_PATTERN})\s*:\s*[^\n]+?(?=\s*$)/m) do |_match|
|
|
655
|
+
::Regexp.last_match(1)
|
|
656
|
+
end
|
|
657
|
+
|
|
555
658
|
result
|
|
556
659
|
end
|
|
557
660
|
end
|
data/lib/t_ruby/ir.rb
CHANGED
|
@@ -147,15 +147,19 @@ module TRuby
|
|
|
147
147
|
|
|
148
148
|
# Method parameter
|
|
149
149
|
class Parameter < Node
|
|
150
|
-
attr_accessor :name, :type_annotation, :default_value, :kind
|
|
150
|
+
attr_accessor :name, :type_annotation, :default_value, :kind, :interface_ref
|
|
151
151
|
|
|
152
|
-
# kind: :required, :optional, :rest, :keyrest, :block
|
|
153
|
-
|
|
152
|
+
# kind: :required, :optional, :rest, :keyrest, :block, :keyword
|
|
153
|
+
# :keyword - 키워드 인자 (구조분해): { name: String } → def foo(name:)
|
|
154
|
+
# :keyrest - 더블 스플랫: **opts: Type → def foo(**opts)
|
|
155
|
+
# interface_ref - interface 참조 타입 (예: }: UserParams 부분)
|
|
156
|
+
def initialize(name:, type_annotation: nil, default_value: nil, kind: :required, interface_ref: nil, **opts)
|
|
154
157
|
super(**opts)
|
|
155
158
|
@name = name
|
|
156
159
|
@type_annotation = type_annotation
|
|
157
160
|
@default_value = default_value
|
|
158
161
|
@kind = kind
|
|
162
|
+
@interface_ref = interface_ref
|
|
159
163
|
end
|
|
160
164
|
end
|
|
161
165
|
|
data/lib/t_ruby/parser.rb
CHANGED
|
@@ -244,18 +244,36 @@ module TRuby
|
|
|
244
244
|
param_list = split_params(params_str)
|
|
245
245
|
|
|
246
246
|
param_list.each do |param|
|
|
247
|
-
|
|
248
|
-
|
|
247
|
+
param = param.strip
|
|
248
|
+
|
|
249
|
+
# 1. 더블 스플랫: **name: Type
|
|
250
|
+
if param.start_with?("**")
|
|
251
|
+
param_info = parse_double_splat_parameter(param)
|
|
252
|
+
parameters << param_info if param_info
|
|
253
|
+
# 2. 키워드 인자 그룹: { ... } 또는 { ... }: InterfaceName
|
|
254
|
+
elsif param.start_with?("{")
|
|
255
|
+
keyword_params = parse_keyword_args_group(param)
|
|
256
|
+
parameters.concat(keyword_params) if keyword_params
|
|
257
|
+
# 3. Hash 리터럴: name: { ... }
|
|
258
|
+
elsif param.match?(/^\w+:\s*\{/)
|
|
259
|
+
param_info = parse_hash_literal_parameter(param)
|
|
260
|
+
parameters << param_info if param_info
|
|
261
|
+
# 4. 일반 위치 인자: name: Type 또는 name: Type = default
|
|
262
|
+
else
|
|
263
|
+
param_info = parse_single_parameter(param)
|
|
264
|
+
parameters << param_info if param_info
|
|
265
|
+
end
|
|
249
266
|
end
|
|
250
267
|
|
|
251
268
|
parameters
|
|
252
269
|
end
|
|
253
270
|
|
|
254
271
|
def split_params(params_str)
|
|
255
|
-
# Handle nested generics
|
|
272
|
+
# Handle nested generics, braces, brackets
|
|
256
273
|
result = []
|
|
257
274
|
current = ""
|
|
258
275
|
depth = 0
|
|
276
|
+
brace_depth = 0
|
|
259
277
|
|
|
260
278
|
params_str.each_char do |char|
|
|
261
279
|
case char
|
|
@@ -265,8 +283,14 @@ module TRuby
|
|
|
265
283
|
when ">", "]", ")"
|
|
266
284
|
depth -= 1
|
|
267
285
|
current += char
|
|
286
|
+
when "{"
|
|
287
|
+
brace_depth += 1
|
|
288
|
+
current += char
|
|
289
|
+
when "}"
|
|
290
|
+
brace_depth -= 1
|
|
291
|
+
current += char
|
|
268
292
|
when ","
|
|
269
|
-
if depth.zero?
|
|
293
|
+
if depth.zero? && brace_depth.zero?
|
|
270
294
|
result << current.strip
|
|
271
295
|
current = ""
|
|
272
296
|
else
|
|
@@ -281,8 +305,10 @@ module TRuby
|
|
|
281
305
|
result
|
|
282
306
|
end
|
|
283
307
|
|
|
284
|
-
|
|
285
|
-
|
|
308
|
+
# 더블 스플랫 파라미터 파싱: **opts: Type
|
|
309
|
+
def parse_double_splat_parameter(param)
|
|
310
|
+
# **name: Type
|
|
311
|
+
match = param.match(/^\*\*(\w+)(?::\s*(.+?))?$/)
|
|
286
312
|
return nil unless match
|
|
287
313
|
|
|
288
314
|
param_name = match[1]
|
|
@@ -291,6 +317,155 @@ module TRuby
|
|
|
291
317
|
result = {
|
|
292
318
|
name: param_name,
|
|
293
319
|
type: type_str,
|
|
320
|
+
kind: :keyrest,
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if type_str
|
|
324
|
+
type_result = @type_parser.parse(type_str)
|
|
325
|
+
result[:ir_type] = type_result[:type] if type_result[:success]
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
result
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
# 키워드 인자 그룹 파싱: { name: String, age: Integer = 0 } 또는 { name:, age: 0 }: InterfaceName
|
|
332
|
+
def parse_keyword_args_group(param)
|
|
333
|
+
# { ... }: InterfaceName 형태 확인
|
|
334
|
+
# 또는 { ... } 만 있는 형태 (인라인 타입)
|
|
335
|
+
interface_match = param.match(/^\{(.+)\}\s*:\s*(\w+)\s*$/)
|
|
336
|
+
inline_match = param.match(/^\{(.+)\}\s*$/) unless interface_match
|
|
337
|
+
|
|
338
|
+
if interface_match
|
|
339
|
+
inner_content = interface_match[1]
|
|
340
|
+
interface_name = interface_match[2]
|
|
341
|
+
parse_keyword_args_with_interface(inner_content, interface_name)
|
|
342
|
+
elsif inline_match
|
|
343
|
+
inner_content = inline_match[1]
|
|
344
|
+
parse_keyword_args_inline(inner_content)
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
# interface 참조 키워드 인자 파싱: { name:, age: 0 }: UserParams
|
|
349
|
+
def parse_keyword_args_with_interface(inner_content, interface_name)
|
|
350
|
+
parameters = []
|
|
351
|
+
parts = split_keyword_args(inner_content)
|
|
352
|
+
|
|
353
|
+
parts.each do |part|
|
|
354
|
+
part = part.strip
|
|
355
|
+
next if part.empty?
|
|
356
|
+
|
|
357
|
+
# name: default_value 또는 name: 형태
|
|
358
|
+
next unless part.match?(/^(\w+):\s*(.*)$/)
|
|
359
|
+
|
|
360
|
+
match = part.match(/^(\w+):\s*(.*)$/)
|
|
361
|
+
param_name = match[1]
|
|
362
|
+
default_value = match[2].strip
|
|
363
|
+
default_value = nil if default_value.empty?
|
|
364
|
+
|
|
365
|
+
parameters << {
|
|
366
|
+
name: param_name,
|
|
367
|
+
type: nil, # interface에서 타입을 가져옴
|
|
368
|
+
default_value: default_value,
|
|
369
|
+
kind: :keyword,
|
|
370
|
+
interface_ref: interface_name,
|
|
371
|
+
}
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
parameters
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
# 인라인 타입 키워드 인자 파싱: { name: String, age: Integer = 0 }
|
|
378
|
+
def parse_keyword_args_inline(inner_content)
|
|
379
|
+
parameters = []
|
|
380
|
+
parts = split_keyword_args(inner_content)
|
|
381
|
+
|
|
382
|
+
parts.each do |part|
|
|
383
|
+
part = part.strip
|
|
384
|
+
next if part.empty?
|
|
385
|
+
|
|
386
|
+
# name: Type = default 또는 name: Type 형태
|
|
387
|
+
next unless part.match?(/^(\w+):\s*(.+)$/)
|
|
388
|
+
|
|
389
|
+
match = part.match(/^(\w+):\s*(.+)$/)
|
|
390
|
+
param_name = match[1]
|
|
391
|
+
type_and_default = match[2].strip
|
|
392
|
+
|
|
393
|
+
# Type = default 분리
|
|
394
|
+
type_str, default_value = split_type_and_default(type_and_default)
|
|
395
|
+
|
|
396
|
+
result = {
|
|
397
|
+
name: param_name,
|
|
398
|
+
type: type_str,
|
|
399
|
+
default_value: default_value,
|
|
400
|
+
kind: :keyword,
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if type_str
|
|
404
|
+
type_result = @type_parser.parse(type_str)
|
|
405
|
+
result[:ir_type] = type_result[:type] if type_result[:success]
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
parameters << result
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
parameters
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
# 키워드 인자 내부를 콤마로 분리 (중첩된 제네릭/배열/해시 고려)
|
|
415
|
+
def split_keyword_args(content)
|
|
416
|
+
StringUtils.split_by_comma(content)
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
# 타입과 기본값 분리: "String = 0" -> ["String", "0"]
|
|
420
|
+
def split_type_and_default(type_and_default)
|
|
421
|
+
StringUtils.split_type_and_default(type_and_default)
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
# Hash 리터럴 파라미터 파싱: config: { host: String, port: Integer }
|
|
425
|
+
def parse_hash_literal_parameter(param)
|
|
426
|
+
# name: { ... } 또는 name: { ... }: InterfaceName
|
|
427
|
+
match = param.match(/^(\w+):\s*(\{.+\})(?::\s*(\w+))?$/)
|
|
428
|
+
return nil unless match
|
|
429
|
+
|
|
430
|
+
param_name = match[1]
|
|
431
|
+
hash_type = match[2]
|
|
432
|
+
interface_name = match[3]
|
|
433
|
+
|
|
434
|
+
result = {
|
|
435
|
+
name: param_name,
|
|
436
|
+
type: interface_name || hash_type,
|
|
437
|
+
kind: :required,
|
|
438
|
+
hash_type_def: hash_type, # 원본 해시 타입 정의 저장
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
result[:interface_ref] = interface_name if interface_name
|
|
442
|
+
|
|
443
|
+
result
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
def parse_single_parameter(param)
|
|
447
|
+
# name: Type = default 또는 name: Type 또는 name
|
|
448
|
+
# 기본값이 있는 경우 먼저 처리
|
|
449
|
+
type_str = nil
|
|
450
|
+
default_value = nil
|
|
451
|
+
|
|
452
|
+
if param.include?(":")
|
|
453
|
+
match = param.match(/^(\w+):\s*(.+)$/)
|
|
454
|
+
return nil unless match
|
|
455
|
+
|
|
456
|
+
param_name = match[1]
|
|
457
|
+
type_and_default = match[2].strip
|
|
458
|
+
type_str, default_value = split_type_and_default(type_and_default)
|
|
459
|
+
else
|
|
460
|
+
# 타입 없이 이름만 있는 경우
|
|
461
|
+
param_name = param.strip
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
result = {
|
|
465
|
+
name: param_name,
|
|
466
|
+
type: type_str,
|
|
467
|
+
default_value: default_value,
|
|
468
|
+
kind: default_value ? :optional : :required,
|
|
294
469
|
}
|
|
295
470
|
|
|
296
471
|
# Parse type with combinator
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module TRuby
|
|
4
|
+
# 문자열 파싱을 위한 공통 유틸리티 모듈
|
|
5
|
+
# 파서와 컴파일러에서 공유하는 중첩 괄호 처리 로직
|
|
6
|
+
module StringUtils
|
|
7
|
+
module_function
|
|
8
|
+
|
|
9
|
+
# 중첩된 괄호를 고려하여 콤마로 문자열 분리
|
|
10
|
+
# @param content [String] 분리할 문자열
|
|
11
|
+
# @return [Array<String>] 분리된 문자열 배열
|
|
12
|
+
def split_by_comma(content)
|
|
13
|
+
result = []
|
|
14
|
+
current = ""
|
|
15
|
+
depth = 0
|
|
16
|
+
|
|
17
|
+
content.each_char do |char|
|
|
18
|
+
case char
|
|
19
|
+
when "<", "[", "(", "{"
|
|
20
|
+
depth += 1
|
|
21
|
+
current += char
|
|
22
|
+
when ">", "]", ")", "}"
|
|
23
|
+
depth -= 1
|
|
24
|
+
current += char
|
|
25
|
+
when ","
|
|
26
|
+
if depth.zero?
|
|
27
|
+
result << current.strip
|
|
28
|
+
current = ""
|
|
29
|
+
else
|
|
30
|
+
current += char
|
|
31
|
+
end
|
|
32
|
+
else
|
|
33
|
+
current += char
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
result << current.strip unless current.empty?
|
|
38
|
+
result
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# 타입과 기본값 분리: "String = 0" -> ["String", "0"]
|
|
42
|
+
# 중첩된 괄호 내부의 = 는 무시
|
|
43
|
+
# @param type_and_default [String] "Type = default" 형태의 문자열
|
|
44
|
+
# @return [Array] [type_str, default_value] 또는 [type_str, nil]
|
|
45
|
+
def split_type_and_default(type_and_default)
|
|
46
|
+
depth = 0
|
|
47
|
+
equals_pos = nil
|
|
48
|
+
|
|
49
|
+
type_and_default.each_char.with_index do |char, i|
|
|
50
|
+
case char
|
|
51
|
+
when "<", "[", "(", "{"
|
|
52
|
+
depth += 1
|
|
53
|
+
when ">", "]", ")", "}"
|
|
54
|
+
depth -= 1
|
|
55
|
+
when "="
|
|
56
|
+
if depth.zero?
|
|
57
|
+
equals_pos = i
|
|
58
|
+
break
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
if equals_pos
|
|
64
|
+
type_str = type_and_default[0...equals_pos].strip
|
|
65
|
+
default_value = type_and_default[(equals_pos + 1)..].strip
|
|
66
|
+
[type_str, default_value]
|
|
67
|
+
else
|
|
68
|
+
[type_and_default, nil]
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# 기본값만 추출 (타입은 버림)
|
|
73
|
+
# @param type_and_default [String] "Type = default" 형태의 문자열
|
|
74
|
+
# @return [String, nil] 기본값 또는 nil
|
|
75
|
+
def extract_default_value(type_and_default)
|
|
76
|
+
_, default_value = split_type_and_default(type_and_default)
|
|
77
|
+
default_value
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
data/lib/t_ruby/version.rb
CHANGED
data/lib/t_ruby.rb
CHANGED
|
@@ -5,6 +5,7 @@ require_relative "t_ruby/version_checker"
|
|
|
5
5
|
require_relative "t_ruby/config"
|
|
6
6
|
|
|
7
7
|
# Core infrastructure (must be loaded first)
|
|
8
|
+
require_relative "t_ruby/string_utils"
|
|
8
9
|
require_relative "t_ruby/ir"
|
|
9
10
|
require_relative "t_ruby/parser_combinator"
|
|
10
11
|
require_relative "t_ruby/smt_solver"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: t-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.41
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Y. Fred Kim
|
|
@@ -61,6 +61,7 @@ files:
|
|
|
61
61
|
- lib/t_ruby/parser_combinator.rb
|
|
62
62
|
- lib/t_ruby/runtime_validator.rb
|
|
63
63
|
- lib/t_ruby/smt_solver.rb
|
|
64
|
+
- lib/t_ruby/string_utils.rb
|
|
64
65
|
- lib/t_ruby/type_alias_registry.rb
|
|
65
66
|
- lib/t_ruby/type_checker.rb
|
|
66
67
|
- lib/t_ruby/type_env.rb
|