thaip 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: '053683a92e0c8d3aef39eaa0acdbd4250201541612e3e80121066accda05abd8'
4
+ data.tar.gz: 34e9692dbe01b7a60d408dc649814c22d0cc31a5bc8ab56ca58af2ac1a32aa04
5
+ SHA512:
6
+ metadata.gz: 2ec7085583013ef659ca2aa571323de75e655774315ec0fbe41d60c4eab0d1c032bdb60293144b22da8d325c651bcfbfbeb89a0d632eef92f35383335375b46f
7
+ data.tar.gz: cb3a585213967a2bfbbeebee959d1d0c117345a8e7d6dc90c8f2564f28efa1613bf716fabb58975a6892bfdbdc2bca000987af83b60ccbfa8a70af1e8c9d6ccd
data/lib/thaip.rb ADDED
@@ -0,0 +1,5 @@
1
+ module Thaip
2
+ end
3
+
4
+ require 'thaip/make_struct'
5
+ require 'thaip/type_def'
@@ -0,0 +1,40 @@
1
+ class MakeStruct
2
+ class CustomStruct
3
+ def initialize(**argkw)
4
+ unknown_keys = argkw.keys - __acceptable_keys
5
+ raise "Unknown ctor keys: #{unknown_keys}" unless unknown_keys.empty?
6
+
7
+ __acceptable_keys.each do |key|
8
+ instance_variable_set("@#{key}", argkw.fetch(key, __default_value(key)))
9
+ end
10
+ end
11
+
12
+ private
13
+
14
+ def __ctor_args
15
+ self
16
+ .class
17
+ .ancestors
18
+ .find { |klass| klass.instance_variables.include?(:@__ctor_args) }
19
+ .instance_variable_get(:@__ctor_args)
20
+ end
21
+
22
+ def __acceptable_keys
23
+ keys = __ctor_args[0] + __ctor_args[1].keys
24
+ end
25
+
26
+ def __default_value(key)
27
+ __ctor_args[1][key]
28
+ end
29
+ end
30
+
31
+ class << self
32
+ def [](*args, **argkw)
33
+ x = argkw
34
+ Class.new(CustomStruct) do
35
+ @__ctor_args = [args, argkw]
36
+ (args + argkw.keys).each(&method(:attr_accessor))
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,133 @@
1
+ class TypeDef
2
+ class DataContainer
3
+ def initialize(name)
4
+ @name = name
5
+ @members = []
6
+
7
+ Object.const_set(name, self)
8
+ end
9
+
10
+ def to_s
11
+ "<#{@name}>"
12
+ end
13
+
14
+ def inspect
15
+ to_s
16
+ end
17
+
18
+ def with(name, *args, **argkw)
19
+ DataConstructor.new(name, self, *args, **argkw)
20
+ self
21
+ end
22
+ end
23
+
24
+ class DataConstructor
25
+ attr_accessor :vals
26
+
27
+ def initialize(name, data_container, *args, **argkw)
28
+ @name = name
29
+ @data_container = data_container
30
+ @vals = {}
31
+ @args = args
32
+ @argkw = argkw
33
+
34
+ Object.const_set(name, self)
35
+ end
36
+
37
+ def to_s
38
+ "<#{@name}#{@vals.map { |k, v| " #{k}:#{v}"}.join}>"
39
+ end
40
+ alias_method :inspect, :to_s
41
+
42
+ def type
43
+ @data_container
44
+ end
45
+
46
+ def is_a?(a_type)
47
+ if a_type.respond_to?(:__class) && a_type.__class == DataConstructor
48
+ return self.class == a_type.class
49
+ end
50
+
51
+ a_type === type
52
+ end
53
+
54
+ def ===(other)
55
+ return is_a?(other) if other.is_a?(DataContainer)
56
+
57
+ is_a?(other.type)
58
+ end
59
+
60
+ def new(*args, **kwargs)
61
+ self_clone = clone
62
+ self_clone.vals = {}
63
+
64
+ @args.zip(args).each_with_index do |(type, arg), index|
65
+ raise "Expected type <#{type}> for value <#{arg}>" unless arg.nil? || arg.is_a?(type)
66
+
67
+ key = "#{type}-#{index}"
68
+ self_clone.vals[key] = arg
69
+ end
70
+
71
+ @argkw.each do |k, type|
72
+ raise "Expected type <#{type}> for value <#{kwargs[k]}>" unless kwargs[k].nil? || kwargs[k].is_a?(type)
73
+
74
+ self_clone.vals[k] = kwargs[k]
75
+ end
76
+
77
+ self_clone
78
+ end
79
+
80
+ def value
81
+ @vals.values[0]
82
+ end
83
+
84
+ def defined?(name)
85
+ return true if @vals.key?(name)
86
+ super(name)
87
+ end
88
+
89
+ def method_missing(name, *args)
90
+ if name.to_s.end_with?('=')
91
+ key = name.to_s[0..-2].to_sym
92
+ return super(name, *args) unless @vals.key?(key)
93
+
94
+ type = @argkw[key]
95
+ value = args[0]
96
+ raise "Expected type <#{type}> for value <#{value}>" unless value.nil? || value.is_a?(type)
97
+
98
+ @vals[key] = value
99
+ else
100
+ return super(name, *args) unless @vals.key?(name)
101
+
102
+ @vals[name]
103
+ end
104
+ end
105
+
106
+ def [](index)
107
+ raise "Index out of bounds" if index >= @vals.size
108
+ @vals.values[index]
109
+ end
110
+
111
+ def []=(index, val)
112
+ raise "Index out of bounds" if index >= @vals.size
113
+
114
+ # TODO add typecheck
115
+ @vals[@vals.keys[index]] = val
116
+ end
117
+
118
+ alias_method :__class, :class
119
+ def class
120
+ @name
121
+ end
122
+ end
123
+
124
+ def self.data(name)
125
+ DataContainer.new(name)
126
+ end
127
+
128
+ class << self
129
+ def [](name)
130
+ DataContainer.new(name)
131
+ end
132
+ end
133
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: thaip
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - itarato
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-02-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description:
28
+ email: it.arato@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - lib/thaip.rb
34
+ - lib/thaip/make_struct.rb
35
+ - lib/thaip/type_def.rb
36
+ homepage: https://github.com/itarato/prototyper
37
+ licenses:
38
+ - GPL-3.0-or-later
39
+ metadata: {}
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: 2.6.0
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubygems_version: 3.1.2
56
+ signing_key:
57
+ specification_version: 4
58
+ summary: Thaip
59
+ test_files: []