houndstooth 0.1.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.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.rspec +1 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +11 -0
  6. data/Gemfile.lock +49 -0
  7. data/README.md +99 -0
  8. data/bin/houndstooth.rb +183 -0
  9. data/fuzz/cases/x.rb +8 -0
  10. data/fuzz/cases/y.rb +8 -0
  11. data/fuzz/cases/z.rb +22 -0
  12. data/fuzz/ruby.dict +64 -0
  13. data/fuzz/run +21 -0
  14. data/lib/houndstooth/environment/builder.rb +260 -0
  15. data/lib/houndstooth/environment/type_parser.rb +149 -0
  16. data/lib/houndstooth/environment/types/basic/type.rb +85 -0
  17. data/lib/houndstooth/environment/types/basic/type_instance.rb +54 -0
  18. data/lib/houndstooth/environment/types/compound/union_type.rb +72 -0
  19. data/lib/houndstooth/environment/types/defined/base_defined_type.rb +23 -0
  20. data/lib/houndstooth/environment/types/defined/defined_type.rb +137 -0
  21. data/lib/houndstooth/environment/types/defined/pending_defined_type.rb +14 -0
  22. data/lib/houndstooth/environment/types/method/method.rb +79 -0
  23. data/lib/houndstooth/environment/types/method/method_type.rb +144 -0
  24. data/lib/houndstooth/environment/types/method/parameters.rb +53 -0
  25. data/lib/houndstooth/environment/types/method/special_constructor_method.rb +15 -0
  26. data/lib/houndstooth/environment/types/special/instance_type.rb +9 -0
  27. data/lib/houndstooth/environment/types/special/self_type.rb +9 -0
  28. data/lib/houndstooth/environment/types/special/type_parameter_placeholder.rb +38 -0
  29. data/lib/houndstooth/environment/types/special/untyped_type.rb +11 -0
  30. data/lib/houndstooth/environment/types/special/void_type.rb +12 -0
  31. data/lib/houndstooth/environment/types.rb +3 -0
  32. data/lib/houndstooth/environment.rb +74 -0
  33. data/lib/houndstooth/errors.rb +53 -0
  34. data/lib/houndstooth/instructions.rb +698 -0
  35. data/lib/houndstooth/interpreter/const_internal.rb +148 -0
  36. data/lib/houndstooth/interpreter/objects.rb +142 -0
  37. data/lib/houndstooth/interpreter/runtime.rb +309 -0
  38. data/lib/houndstooth/interpreter.rb +7 -0
  39. data/lib/houndstooth/semantic_node/control_flow.rb +218 -0
  40. data/lib/houndstooth/semantic_node/definitions.rb +253 -0
  41. data/lib/houndstooth/semantic_node/identifiers.rb +308 -0
  42. data/lib/houndstooth/semantic_node/keywords.rb +45 -0
  43. data/lib/houndstooth/semantic_node/literals.rb +226 -0
  44. data/lib/houndstooth/semantic_node/operators.rb +126 -0
  45. data/lib/houndstooth/semantic_node/parameters.rb +108 -0
  46. data/lib/houndstooth/semantic_node/send.rb +349 -0
  47. data/lib/houndstooth/semantic_node/super.rb +12 -0
  48. data/lib/houndstooth/semantic_node.rb +119 -0
  49. data/lib/houndstooth/stdlib.rb +6 -0
  50. data/lib/houndstooth/type_checker.rb +462 -0
  51. data/lib/houndstooth.rb +53 -0
  52. data/spec/ast_to_node_spec.rb +889 -0
  53. data/spec/environment_spec.rb +323 -0
  54. data/spec/instructions_spec.rb +291 -0
  55. data/spec/integration_spec.rb +785 -0
  56. data/spec/interpreter_spec.rb +170 -0
  57. data/spec/self_spec.rb +7 -0
  58. data/spec/spec_helper.rb +50 -0
  59. data/test/ruby_interpreter_test.rb +162 -0
  60. data/types/stdlib.htt +170 -0
  61. metadata +110 -0
@@ -0,0 +1,170 @@
1
+ RSpec.describe Houndstooth::Interpreter do
2
+ Iptr = Houndstooth::Interpreter
3
+
4
+ def interpret(code, local=nil)
5
+ env = Houndstooth::Environment.new
6
+ Houndstooth::Stdlib.add_types(env)
7
+
8
+ Houndstooth.process_file('(test)', code, env)
9
+
10
+ block = code_to_block(code)
11
+ runtime = Iptr::Runtime.new(env: env)
12
+ runtime.execute_block(
13
+ block,
14
+ self_type: nil,
15
+ self_object: nil,
16
+ lexical_context: Houndstooth::Environment::BaseDefinedType.new,
17
+ type_arguments: {},
18
+ )
19
+
20
+ if Houndstooth::Errors.errors.any?
21
+ raise "Errors occurred during interpretation:\n#{Houndstooth::Errors.errors.map(&:format).join("\n")}"
22
+ end
23
+
24
+ if local
25
+ [env, runtime.variables.find { |var, t| var.ruby_identifier == local }[1]]
26
+ else
27
+ [env, runtime]
28
+ end
29
+ end
30
+
31
+ it 'can unwrap primitive values' do
32
+ env = Houndstooth::Environment.new
33
+ Houndstooth::Stdlib.add_types(env)
34
+
35
+ # Unwrap where value given
36
+ known_int = Iptr::InterpreterObject.new(
37
+ type: env.resolve_type('Integer'),
38
+ env: env,
39
+ primitive_value: [true, 3],
40
+ )
41
+ expect(known_int.unwrap_primitive_value).to eq 3
42
+
43
+ # Unwrap where value not given (e.g. created with .new)
44
+ default_int = Iptr::InterpreterObject.new(
45
+ type: env.resolve_type('Integer'),
46
+ env: env,
47
+ )
48
+ expect(default_int.unwrap_primitive_value).to eq 0
49
+
50
+ # Can't unwrap non-primitive
51
+ expect do
52
+ Iptr::InterpreterObject.new(
53
+ type: env.resolve_type('Object'),
54
+ env: env,
55
+ ).unwrap_primitive_value
56
+ end.to raise_error(RuntimeError)
57
+ end
58
+
59
+ it 'assigns objects truthiness' do
60
+ env = Houndstooth::Environment.new
61
+ Houndstooth::Stdlib.add_types(env)
62
+
63
+ fals = Iptr::InterpreterObject.new(
64
+ type: env.resolve_type('FalseClass'),
65
+ env: env,
66
+ )
67
+ expect(fals.truthy?).to eq false
68
+
69
+ nl = Iptr::InterpreterObject.new(
70
+ type: env.resolve_type('NilClass'),
71
+ env: env,
72
+ )
73
+ expect(nl.truthy?).to eq false
74
+
75
+ tru = Iptr::InterpreterObject.new(
76
+ type: env.resolve_type('TrueClass'),
77
+ env: env,
78
+ )
79
+ expect(tru.truthy?).to eq true
80
+
81
+ int = Iptr::InterpreterObject.new(
82
+ type: env.resolve_type('Integer'),
83
+ env: env,
84
+ )
85
+ expect(int.truthy?).to eq true
86
+ end
87
+
88
+ it 'can execute basic literal evaluations' do
89
+ env, x = interpret('x = 3', 'x')
90
+ expect(x).to m(Iptr::InterpreterObject,
91
+ type: env.resolve_type('Integer'),
92
+ primitive_value: [true, 3]
93
+ )
94
+ end
95
+
96
+ it 'can send to const internal methods' do
97
+ env, x = interpret('x = 2 + 3', 'x')
98
+ expect(x).to m(Iptr::InterpreterObject,
99
+ type: env.resolve_type('Integer'),
100
+ primitive_value: [true, 5]
101
+ )
102
+ end
103
+
104
+ it 'recurses into definitions' do
105
+ env, x = interpret('class X; class Y; x = 3; end; end', 'x')
106
+ expect(x).to m(Iptr::InterpreterObject,
107
+ type: env.resolve_type('Integer'),
108
+ primitive_value: [true, 3]
109
+ )
110
+ end
111
+
112
+ it 'can call const methods defined in Ruby' do
113
+ # No parameters
114
+ env, x = interpret('
115
+ module X
116
+ #: () -> Integer
117
+ #!const
118
+ def self.good_enough_pi
119
+ 3
120
+ end
121
+ end
122
+
123
+ x = X.good_enough_pi
124
+ ', 'x')
125
+ expect(x).to m(Iptr::InterpreterObject,
126
+ type: env.resolve_type('Integer'),
127
+ primitive_value: [true, 3]
128
+ )
129
+
130
+ # Parameters
131
+ env, x = interpret('
132
+ module X
133
+ #: (Integer, Integer) -> Integer
134
+ #!const
135
+ def self.add_two(x, y)
136
+ x + y
137
+ end
138
+ end
139
+
140
+ x = X.add_two(2, 3)
141
+ ', 'x')
142
+ expect(x).to m(Iptr::InterpreterObject,
143
+ type: env.resolve_type('Integer'),
144
+ primitive_value: [true, 5]
145
+ )
146
+
147
+ # Working `self`
148
+ env, x = interpret('
149
+ module X
150
+ #: (Integer, Integer, Integer) -> Integer
151
+ #!const
152
+ def self.add_three(x, y, z)
153
+ add_two(add_two(x, y), z)
154
+ end
155
+
156
+ #: (Integer, Integer) -> Integer
157
+ #!const
158
+ def self.add_two(x, y)
159
+ x + y
160
+ end
161
+ end
162
+
163
+ x = X.add_three(1, 2, 3)
164
+ ', 'x')
165
+ expect(x).to m(Iptr::InterpreterObject,
166
+ type: env.resolve_type('Integer'),
167
+ primitive_value: [true, 6]
168
+ )
169
+ end
170
+ end
data/spec/self_spec.rb ADDED
@@ -0,0 +1,7 @@
1
+ # RSpec.describe 'self-test' do
2
+ # it 'does not fail when trying to parse this project' do
3
+ # Dir[File.join(__dir__, '..', '**', '*.rb')].each do |file|
4
+ # code_to_semantic_node(File.read(file))
5
+ # end
6
+ # end
7
+ # end
@@ -0,0 +1,50 @@
1
+ require 'simplecov'
2
+ SimpleCov.start if defined?(RSpec)
3
+
4
+ require_relative '../lib/houndstooth'
5
+
6
+ RSpec.configure do |config|
7
+ config.expect_with :rspec do |expectations|
8
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
9
+ end
10
+
11
+ config.mock_with :rspec do |mocks|
12
+ mocks.verify_partial_doubles = true
13
+ end
14
+
15
+ config.shared_context_metadata_behavior = :apply_to_host_groups
16
+
17
+ config.before :each do
18
+ Houndstooth::Errors.reset
19
+ end
20
+
21
+ config.after :each do
22
+ if Houndstooth::Errors.errors.any?
23
+ errors = Houndstooth::Errors.errors.map { |e| e.format }.join("\n")
24
+ raise "Errors occurred during test:\n#{errors}"
25
+ end
26
+ end
27
+ end if defined?(RSpec)
28
+
29
+ def m(type, **attrs)
30
+ if attrs.length > 0
31
+ be_a(type) & have_attributes(**attrs)
32
+ else
33
+ be_a(type)
34
+ end
35
+ end
36
+
37
+ def code_to_semantic_node(code)
38
+ buffer = Parser::Source::Buffer.new("arg")
39
+ buffer.source = code
40
+
41
+ ast_node, comments = Parser::Ruby30.new.parse_with_comments(buffer)
42
+ $comments = comments
43
+ Houndstooth::SemanticNode.from_ast(ast_node)
44
+ end
45
+
46
+ def code_to_block(code)
47
+ block = I::InstructionBlock.new(has_scope: true, parent: nil)
48
+ code_to_semantic_node(code).to_instructions(block)
49
+ block
50
+ end
@@ -0,0 +1,162 @@
1
+ require_relative '../lib/houndstooth'
2
+ require_relative '../spec/spec_helper' # contains code_to_X methods
3
+
4
+ def run(command)
5
+ out = `#{command}`
6
+ abort "command failed: #{command}" unless $?.success?
7
+ out
8
+ end
9
+
10
+ # Perform a sparse checkout of the Ruby repository to grab bootstraptest
11
+ ruby_dir = File.join(__dir__, "ruby")
12
+ if Dir.exist?(ruby_dir)
13
+ puts "Ruby directory already exists, skipping checkout"
14
+ else
15
+ puts "Sparse-checking out Ruby..."
16
+ Dir.mkdir(ruby_dir)
17
+ Dir.chdir(ruby_dir) do
18
+ run("git init")
19
+ run("git remote add -f origin https://github.com/ruby/ruby.git")
20
+ run("git config core.sparseCheckout true")
21
+ File.write(File.join(ruby_dir, ".git", "info", "sparse-checkout"), "bootstraptest/")
22
+ run("git pull origin master")
23
+ end
24
+ end
25
+
26
+ I = Houndstooth::Instructions
27
+
28
+ # Required for Houndstooth.process_file, which expects to be run from the binary
29
+ def abort_on_error!
30
+ if Houndstooth::Errors.errors.any?
31
+ raise "Errors occurred during interpretation:\n#{Houndstooth::Errors.errors.map(&:format).join("\n")}"
32
+ end
33
+ end
34
+
35
+ def interpreter_execute(code)
36
+ # Create environment
37
+ env = Houndstooth::Environment.new
38
+ Houndstooth::Stdlib.add_types(env)
39
+
40
+ # Process input
41
+ Houndstooth.process_file('(test)', code, env)
42
+
43
+ # Process and evaluate input
44
+ block = code_to_block(code)
45
+ runtime = Houndstooth::Interpreter::Runtime.new(env: env)
46
+ runtime.execute_block(
47
+ block,
48
+ self_type: nil,
49
+ self_object: nil,
50
+ lexical_context: Houndstooth::Environment::BaseDefinedType.new,
51
+ type_arguments: {},
52
+ )
53
+
54
+ # If an error occurred, throw
55
+ abort_on_error!
56
+
57
+ # Get return value
58
+ runtime.variables[block.instructions.last.result]
59
+ end
60
+
61
+ $bootstrap_test_passes = Hash.new { |h, k| h[k] = [] }
62
+ $bootstrap_test_failures = Hash.new { |h, k| h[k] = [] }
63
+ $bootstrap_test_crashes = Hash.new { |h, k| h[k] = [] }
64
+ $bootstrap_test_unimplemented = Hash.new { |h, k| h[k] = [] }
65
+
66
+ module BootstrapTestHarness
67
+ def self.clear_errors
68
+ Houndstooth::Errors.errors.clear
69
+ end
70
+
71
+ def self.target_platform
72
+ ""
73
+ end
74
+
75
+ def self.assert_equal(expected_result, code, *_)
76
+ clear_errors
77
+
78
+ actual_result = interpreter_execute(code)
79
+ if actual_result.ruby_inspect == expected_result
80
+ $bootstrap_test_passes[$bootstrap_test_current_file] << [expected_result, code]
81
+ else
82
+ $bootstrap_test_failures[$bootstrap_test_current_file] << [expected_result, actual_result.ruby_inspect, code]
83
+ end
84
+ rescue => e
85
+ $bootstrap_test_crashes[$bootstrap_test_current_file] << [expected_result, code]
86
+ end
87
+
88
+ def self.assert_match(matcher, code, *_)
89
+ clear_errors
90
+
91
+ actual_result = interpreter_execute(code)
92
+ if matcher === actual_result.ruby_inspect
93
+ $bootstrap_test_passes[$bootstrap_test_current_file] << [matcher, code]
94
+ else
95
+ $bootstrap_test_failures[$bootstrap_test_current_file] << [matcher, actual_result, code]
96
+ end
97
+ rescue
98
+ $bootstrap_test_crashes[$bootstrap_test_current_file] << [matcher, code]
99
+ end
100
+
101
+ def self.assert_not_match(matcher, code, *_)
102
+ clear_errors
103
+
104
+ actual_result = interpreter_execute(code)
105
+ if !(matcher === actual_result.ruby_inspect)
106
+ $bootstrap_test_passes[$bootstrap_test_current_file] << [matcher, code]
107
+ else
108
+ $bootstrap_test_failures[$bootstrap_test_current_file] << [matcher, actual_result, code]
109
+ end
110
+ rescue
111
+ $bootstrap_test_crashes[$bootstrap_test_current_file] << [matcher, code]
112
+ end
113
+
114
+ def self.assert_normal_exit(code, message="(normal exit)", *_)
115
+ clear_errors
116
+ interpreter_execute(code)
117
+ rescue
118
+ $bootstrap_test_crashes[$bootstrap_test_current_file] << [message, code]
119
+ end
120
+
121
+ def self.assert_valid_syntax(code, *_)
122
+ clear_errors
123
+ assert_normal_exit(code, "(valid syntax)")
124
+ end
125
+
126
+ def self.assert_finish(code, *_)
127
+ clear_errors
128
+ assert_normal_exit(code, "(finish)")
129
+ end
130
+
131
+ def self.method_missing(*a)
132
+ $bootstrap_test_unimplemented[$bootstrap_test_current_file] << a
133
+ end
134
+ end
135
+
136
+ files = Dir[File.join(ruby_dir, "bootstraptest", "test_*.rb")]
137
+ files.each do |file|
138
+ puts file
139
+ test = File.read(file)
140
+ $bootstrap_test_current_file = file
141
+ BootstrapTestHarness.instance_eval(test, file)
142
+ end
143
+
144
+ puts
145
+ puts "== RESULTS =="
146
+ puts
147
+ files.each do |file|
148
+ print File.split(file)[1]
149
+ print ": "
150
+ print "#{$bootstrap_test_passes[file].length} passed, "
151
+ print "#{$bootstrap_test_failures[file].length} failed, "
152
+ print "#{$bootstrap_test_crashes[file].length} crashed, "
153
+ print "#{$bootstrap_test_unimplemented[file].length} unimplemented"
154
+ puts
155
+ end
156
+
157
+ puts
158
+ puts "== TOTALS =="
159
+ puts "Passes: #{$bootstrap_test_passes.values.map(&:length).sum}"
160
+ puts "Failures: #{$bootstrap_test_failures.values.map(&:length).sum}"
161
+ puts "Crashes: #{$bootstrap_test_crashes.values.map(&:length).sum}"
162
+ puts "Unimplemented tests: #{$bootstrap_test_unimplemented.values.map(&:length).sum}"
data/types/stdlib.htt ADDED
@@ -0,0 +1,170 @@
1
+ # Useful reference:
2
+ # https://tiagodev.wordpress.com/2013/04/16/eigenclasses-for-lunch-the-ruby-object-model/
3
+
4
+ #!magic basicobject
5
+ class BasicObject
6
+ #: () -> void
7
+ def initialize; end
8
+
9
+ #: (Class) -> Boolean
10
+ def is_a?(_); end
11
+ end
12
+
13
+ class Class < Module
14
+ #: () -> Class
15
+ def superclass; end
16
+
17
+ #: () -> void
18
+ def initialize; end
19
+
20
+ #: () -> Object
21
+ # Special case of `new` being defined as a method rather than magically - this only affects the
22
+ # rather rare usage `Class.new.new`, not anything else e.g. `Object.new`
23
+ def new; end
24
+ end
25
+
26
+ class Object < BasicObject
27
+ #: () -> String
28
+ def inspect; end
29
+
30
+ #: (Object) -> Boolean
31
+ def ==(other); end
32
+ end
33
+
34
+ class Module
35
+ #: () -> Array[Module]
36
+ def nesting; end
37
+
38
+ # The RBS syntax doesn't support any nicer way of doing this :(
39
+ #: [ R] (Symbol) { () -> R } -> Symbol
40
+ #: [A1, R] (Symbol) { (A1) -> R } -> Symbol
41
+ #: [A1, A2, R] (Symbol) { (A1, A2) -> R } -> Symbol
42
+ #: [A1, A2, A3, R] (Symbol) { (A1, A2, A3) -> R } -> Symbol
43
+ #: [A1, A2, A3, A4, R] (Symbol) { (A1, A2, A3, A4) -> R } -> Symbol
44
+ #: [A1, A2, A3, A4, A5, R] (Symbol) { (A1, A2, A3, A4, A5) -> R } -> Symbol
45
+ #: [A1, A2, A3, A4, A5, A6, R] (Symbol) { (A1, A2, A3, A4, A5, A6) -> R } -> Symbol
46
+ #: [A1, A2, A3, A4, A5, A6, A7, R] (Symbol) { (A1, A2, A3, A4, A5, A6, A7) -> R } -> Symbol
47
+ #: [A1, A2, A3, A4, A5, A6, A7, A8, R] (Symbol) { (A1, A2, A3, A4, A5, A6, A7, A8) -> R } -> Symbol
48
+ #: [A1, A2, A3, A4, A5, A6, A7, A8, A9, R] (Symbol) { (A1, A2, A3, A4, A5, A6, A7, A8, A9) -> R } -> Symbol
49
+ #: [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, R] (Symbol) { (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) -> R } -> Symbol
50
+ #!const required_internal
51
+ def define_method(name, *); end
52
+
53
+ #: [T] (Symbol) -> void
54
+ #!const required_internal
55
+ def attr_reader(name); end
56
+
57
+ #: [T] (Symbol) -> void
58
+ #!const required_internal
59
+ def attr_writer(name); end
60
+
61
+ # TODO: Method visibility setters are only supported in their argument-taking form
62
+
63
+ #: (Symbol) -> void
64
+ #!const required_internal
65
+ def private(name); end
66
+
67
+ #: (Symbol) -> void
68
+ #!const required_internal
69
+ def protected(name); end
70
+ end
71
+
72
+ class Numeric
73
+ #: (Numeric) -> Numeric
74
+ #!const internal
75
+ def +(other); end
76
+
77
+ #: (Numeric) -> Boolean
78
+ def >(other); end
79
+
80
+ #: (Numeric) -> Boolean
81
+ def >=(other); end
82
+
83
+ #: (Numeric) -> Boolean
84
+ def <(other); end
85
+
86
+ #: (Numeric) -> Boolean
87
+ def <=(other); end
88
+ end
89
+
90
+ class Integer < Numeric
91
+ #: (Integer) -> Integer
92
+ #: (Float) -> Float
93
+ #!const internal
94
+ def +(other); end
95
+
96
+ #: () { (Integer) -> void } -> Integer
97
+ #!const internal
98
+ def times; end
99
+
100
+ #: () -> Integer
101
+ def abs; end
102
+ end
103
+
104
+ class Float < Numeric
105
+ #: (Integer) -> Float
106
+ #: (Float) -> Float
107
+ #!const internal
108
+ def +(other); end
109
+
110
+ #: () -> Float
111
+ def abs; end
112
+ end
113
+
114
+ class String
115
+ #: (String) -> String
116
+ #!const internal
117
+ def +(other); end
118
+
119
+ #: () -> Integer
120
+ def length; end
121
+
122
+ #: () -> Symbol
123
+ #!const internal
124
+ def to_sym; end
125
+ end
126
+
127
+ class Symbol; end
128
+
129
+ #!param T
130
+ class Array
131
+ #: () -> void
132
+ #!const internal
133
+ def initialize; end
134
+
135
+ #: (T) -> Array[T]
136
+ #!const internal
137
+ def <<(item); end
138
+
139
+ # TODO: should be nilable
140
+ #: (Integer) -> T
141
+ def [](index); end
142
+
143
+ #: () -> Integer
144
+ def length; end
145
+
146
+ #: () { (T) -> void } -> Array[T]
147
+ #!const internal
148
+ def each; end
149
+ end
150
+
151
+ # Doesn't actually exist, but we need some kind of boolean type
152
+ class Boolean; end
153
+ class TrueClass < Boolean; end
154
+ class FalseClass < Boolean; end
155
+
156
+ class NilClass; end
157
+
158
+ class Kernel
159
+ #: (?Float) -> Float
160
+ #: (Integer) -> Integer
161
+ def self.rand(max=nil); end
162
+
163
+ #!const internal
164
+ #: (?untyped) -> void
165
+ def self.puts(message=nil); end
166
+
167
+ #!const internal
168
+ #: (?untyped) -> void
169
+ def self.print(message=nil); end
170
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: houndstooth
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Aaron Christiansen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-04-28 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ - aaronc20000@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".gitignore"
21
+ - ".rspec"
22
+ - ".ruby-version"
23
+ - Gemfile
24
+ - Gemfile.lock
25
+ - README.md
26
+ - bin/houndstooth.rb
27
+ - fuzz/cases/x.rb
28
+ - fuzz/cases/y.rb
29
+ - fuzz/cases/z.rb
30
+ - fuzz/ruby.dict
31
+ - fuzz/run
32
+ - lib/houndstooth.rb
33
+ - lib/houndstooth/environment.rb
34
+ - lib/houndstooth/environment/builder.rb
35
+ - lib/houndstooth/environment/type_parser.rb
36
+ - lib/houndstooth/environment/types.rb
37
+ - lib/houndstooth/environment/types/basic/type.rb
38
+ - lib/houndstooth/environment/types/basic/type_instance.rb
39
+ - lib/houndstooth/environment/types/compound/union_type.rb
40
+ - lib/houndstooth/environment/types/defined/base_defined_type.rb
41
+ - lib/houndstooth/environment/types/defined/defined_type.rb
42
+ - lib/houndstooth/environment/types/defined/pending_defined_type.rb
43
+ - lib/houndstooth/environment/types/method/method.rb
44
+ - lib/houndstooth/environment/types/method/method_type.rb
45
+ - lib/houndstooth/environment/types/method/parameters.rb
46
+ - lib/houndstooth/environment/types/method/special_constructor_method.rb
47
+ - lib/houndstooth/environment/types/special/instance_type.rb
48
+ - lib/houndstooth/environment/types/special/self_type.rb
49
+ - lib/houndstooth/environment/types/special/type_parameter_placeholder.rb
50
+ - lib/houndstooth/environment/types/special/untyped_type.rb
51
+ - lib/houndstooth/environment/types/special/void_type.rb
52
+ - lib/houndstooth/errors.rb
53
+ - lib/houndstooth/instructions.rb
54
+ - lib/houndstooth/interpreter.rb
55
+ - lib/houndstooth/interpreter/const_internal.rb
56
+ - lib/houndstooth/interpreter/objects.rb
57
+ - lib/houndstooth/interpreter/runtime.rb
58
+ - lib/houndstooth/semantic_node.rb
59
+ - lib/houndstooth/semantic_node/control_flow.rb
60
+ - lib/houndstooth/semantic_node/definitions.rb
61
+ - lib/houndstooth/semantic_node/identifiers.rb
62
+ - lib/houndstooth/semantic_node/keywords.rb
63
+ - lib/houndstooth/semantic_node/literals.rb
64
+ - lib/houndstooth/semantic_node/operators.rb
65
+ - lib/houndstooth/semantic_node/parameters.rb
66
+ - lib/houndstooth/semantic_node/send.rb
67
+ - lib/houndstooth/semantic_node/super.rb
68
+ - lib/houndstooth/stdlib.rb
69
+ - lib/houndstooth/type_checker.rb
70
+ - spec/ast_to_node_spec.rb
71
+ - spec/environment_spec.rb
72
+ - spec/instructions_spec.rb
73
+ - spec/integration_spec.rb
74
+ - spec/interpreter_spec.rb
75
+ - spec/self_spec.rb
76
+ - spec/spec_helper.rb
77
+ - test/ruby_interpreter_test.rb
78
+ - types/stdlib.htt
79
+ homepage: https://github.com/AaronC81/houndstooth
80
+ licenses:
81
+ - MIT
82
+ metadata: {}
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubygems_version: 3.2.22
99
+ signing_key:
100
+ specification_version: 4
101
+ summary: Experimental type checker
102
+ test_files:
103
+ - spec/ast_to_node_spec.rb
104
+ - spec/environment_spec.rb
105
+ - spec/instructions_spec.rb
106
+ - spec/integration_spec.rb
107
+ - spec/interpreter_spec.rb
108
+ - spec/self_spec.rb
109
+ - spec/spec_helper.rb
110
+ - test/ruby_interpreter_test.rb