houndstooth 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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