code-ruby 0.5.6 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -3
- data/Gemfile.lock +11 -21
- data/README.md +2 -102
- data/bin/code +34 -16
- data/code-ruby.gemspec +5 -3
- data/lib/code/error.rb +16 -5
- data/lib/code/node/base_10.rb +4 -2
- data/lib/code/node/base_16.rb +3 -1
- data/lib/code/node/base_2.rb +3 -1
- data/lib/code/node/base_8.rb +3 -1
- data/lib/code/node/boolean.rb +4 -2
- data/lib/code/node/call.rb +35 -12
- data/lib/code/node/call_argument.rb +16 -5
- data/lib/code/node/code.rb +5 -4
- data/lib/code/node/decimal.rb +2 -0
- data/lib/code/node/{dictionnary.rb → dictionary.rb} +14 -5
- data/lib/code/node/function.rb +7 -4
- data/lib/code/node/function_parameter.rb +3 -1
- data/lib/code/node/if.rb +5 -3
- data/lib/code/node/left_operation.rb +63 -0
- data/lib/code/node/list.rb +2 -0
- data/lib/code/node/negation.rb +2 -0
- data/lib/code/node/not.rb +2 -0
- data/lib/code/node/nothing.rb +3 -1
- data/lib/code/node/number.rb +2 -0
- data/lib/code/node/right_operation.rb +70 -0
- data/lib/code/node/splat.rb +2 -0
- data/lib/code/node/square_bracket.rb +37 -0
- data/lib/code/node/statement.rb +13 -5
- data/lib/code/node/string.rb +3 -1
- data/lib/code/node/ternary.rb +5 -3
- data/lib/code/node/unary_minus.rb +2 -0
- data/lib/code/node/while.rb +6 -4
- data/lib/code/node.rb +11 -5
- data/lib/code/object/argument.rb +13 -7
- data/lib/code/object/boolean.rb +43 -5
- data/lib/code/object/class.rb +17 -0
- data/lib/code/object/context.rb +36 -0
- data/lib/code/object/decimal.rb +252 -100
- data/lib/code/object/dictionary.rb +641 -0
- data/lib/code/object/function.rb +54 -27
- data/lib/code/object/global.rb +65 -19
- data/lib/code/object/identifier_list.rb +47 -0
- data/lib/code/object/integer.rb +320 -137
- data/lib/code/object/list.rb +140 -138
- data/lib/code/object/nothing.rb +10 -4
- data/lib/code/object/number.rb +6 -1
- data/lib/code/object/range.rb +85 -88
- data/lib/code/object/ruby_function.rb +11 -6
- data/lib/code/object/string.rb +51 -48
- data/lib/code/object.rb +117 -139
- data/lib/code/parser/addition.rb +4 -2
- data/lib/code/parser/and_operator.rb +4 -2
- data/lib/code/parser/bitwise_and.rb +4 -2
- data/lib/code/parser/bitwise_or.rb +4 -2
- data/lib/code/parser/boolean.rb +3 -1
- data/lib/code/parser/call.rb +17 -11
- data/lib/code/parser/chained_call.rb +10 -22
- data/lib/code/parser/class.rb +9 -6
- data/lib/code/parser/code.rb +6 -4
- data/lib/code/parser/{dictionnary.rb → dictionary.rb} +16 -13
- data/lib/code/parser/equal.rb +9 -36
- data/lib/code/parser/equality.rb +4 -2
- data/lib/code/parser/function.rb +24 -9
- data/lib/code/parser/greater.rb +6 -3
- data/lib/code/parser/group.rb +4 -2
- data/lib/code/parser/if.rb +6 -4
- data/lib/code/parser/if_modifier.rb +5 -25
- data/lib/code/parser/left_operation.rb +40 -0
- data/lib/code/parser/list.rb +6 -5
- data/lib/code/parser/multiplication.rb +4 -2
- data/lib/code/parser/name.rb +19 -4
- data/lib/code/parser/negation.rb +4 -2
- data/lib/code/parser/not_keyword.rb +5 -3
- data/lib/code/parser/nothing.rb +3 -10
- data/lib/code/parser/number.rb +4 -2
- data/lib/code/parser/or_keyword.rb +4 -2
- data/lib/code/parser/or_operator.rb +4 -2
- data/lib/code/parser/power.rb +4 -28
- data/lib/code/parser/range.rb +4 -2
- data/lib/code/parser/rescue.rb +6 -26
- data/lib/code/parser/right_operation.rb +40 -0
- data/lib/code/parser/shift.rb +4 -2
- data/lib/code/parser/splat.rb +5 -3
- data/lib/code/parser/square_bracket.rb +48 -0
- data/lib/code/parser/statement.rb +3 -1
- data/lib/code/parser/string.rb +12 -10
- data/lib/code/parser/ternary.rb +10 -11
- data/lib/code/parser/unary_minus.rb +5 -3
- data/lib/code/parser/while.rb +5 -3
- data/lib/code/parser/whitespace.rb +2 -0
- data/lib/code/parser.rb +10 -3
- data/lib/code/ruby.rb +4 -2
- data/lib/code/type/hash.rb +38 -0
- data/lib/code/type/maybe.rb +29 -0
- data/lib/code/type/or.rb +38 -0
- data/lib/code/type/repeat.rb +38 -0
- data/lib/code/type/sig.rb +130 -0
- data/lib/code/type.rb +25 -0
- data/lib/code/version.rb +3 -0
- data/lib/code-ruby.rb +1 -2
- data/lib/code.rb +15 -16
- data/spec/code/node/call_spec.rb +39 -0
- data/spec/code/object/boolean_spec.rb +18 -0
- data/spec/code/object/decimal_spec.rb +51 -0
- data/spec/code/object/dictionary_spec.rb +98 -0
- data/spec/code/object/function_spec.rb +42 -0
- data/spec/code/object/integer_spec.rb +43 -0
- data/spec/code/object/nothing_spec.rb +14 -0
- data/spec/code/object/range_spec.rb +23 -0
- data/spec/code/parser/boolean_spec.rb +5 -10
- data/spec/code/parser/chained_call.rb +4 -5
- data/spec/code/parser/{dictionnary_spec.rb → dictionary_spec.rb} +5 -6
- data/spec/code/parser/function_spec.rb +4 -5
- data/spec/code/parser/group_spec.rb +5 -12
- data/spec/code/parser/if_modifier_spec.rb +18 -0
- data/spec/code/parser/list_spec.rb +4 -5
- data/spec/code/parser/number_spec.rb +4 -5
- data/spec/code/parser/string_spec.rb +4 -5
- data/spec/code/parser_spec.rb +22 -16
- data/spec/code/type_spec.rb +21 -0
- data/spec/code_spec.rb +171 -0
- data/spec/spec_helper.rb +1 -6
- metadata +63 -136
- data/.cherry.js +0 -21
- data/.editorconfig +0 -9
- data/.github/workflows/rspec.yml +0 -14
- data/.gitignore +0 -2
- data/.prettierrc +0 -3
- data/.tool-versions +0 -1
- data/CHANGELOG.md +0 -55
- data/LICENSE +0 -7
- data/TODO +0 -17
- data/bin/format +0 -3
- data/bin/publish +0 -19
- data/bin/template +0 -85
- data/bin/test +0 -17
- data/docs/class.code +0 -9
- data/docs/euler/1.template +0 -10
- data/docs/euler/2.template +0 -16
- data/docs/euler/3.template +0 -16
- data/docs/euler/4.template +0 -10
- data/docs/euler/5.template +0 -13
- data/docs/fibonnaci.template +0 -14
- data/docs/meetup.code +0 -12
- data/docs/precedence.template +0 -36
- data/docs/rain.code +0 -22
- data/docs/slack.code +0 -17
- data/docs/stripe.code +0 -7
- data/docs/twitter.code +0 -9
- data/language-ruby.gemspec +0 -17
- data/lib/code/node/chained_call.rb +0 -23
- data/lib/code/node/equal.rb +0 -34
- data/lib/code/node/if_modifier.rb +0 -47
- data/lib/code/node/operation.rb +0 -38
- data/lib/code/node/power.rb +0 -20
- data/lib/code/node/rescue.rb +0 -17
- data/lib/code/object/dictionnary.rb +0 -96
- data/lib/code/parser/equality_lower.rb +0 -9
- data/lib/code/parser/operation.rb +0 -35
- data/lib/language/atom.rb +0 -342
- data/lib/language/output.rb +0 -130
- data/lib/language/parser/absent/present.rb +0 -8
- data/lib/language/parser/absent.rb +0 -6
- data/lib/language/parser/end_of_input.rb +0 -6
- data/lib/language/parser/interuption.rb +0 -38
- data/lib/language/parser/not_end_of_input.rb +0 -6
- data/lib/language/parser/str/not_found.rb +0 -16
- data/lib/language/parser/str.rb +0 -6
- data/lib/language/parser.rb +0 -53
- data/lib/language-ruby.rb +0 -10
- data/lib/language.rb +0 -80
- data/lib/template/node/code_part.rb +0 -13
- data/lib/template/node/part.rb +0 -19
- data/lib/template/node/template.rb +0 -15
- data/lib/template/node/text_part.rb +0 -13
- data/lib/template/node.rb +0 -4
- data/lib/template/parser/template.rb +0 -39
- data/lib/template/parser.rb +0 -19
- data/lib/template/version.rb +0 -3
- data/lib/template-ruby.rb +0 -10
- data/lib/template.rb +0 -50
- data/spec/code/addition_spec.rb +0 -13
- data/spec/code/and_operator_spec.rb +0 -13
- data/spec/code/bitwise_and_spec.rb +0 -13
- data/spec/code/bitwise_or_spec.rb +0 -13
- data/spec/code/boolean_spec.rb +0 -13
- data/spec/code/call_spec.rb +0 -21
- data/spec/code/chained_call_spec.rb +0 -16
- data/spec/code/code_spec.rb +0 -29
- data/spec/code/dictionnary_spec.rb +0 -17
- data/spec/code/equal_spec.rb +0 -26
- data/spec/code/equality_spec.rb +0 -13
- data/spec/code/function_spec.rb +0 -18
- data/spec/code/greater_spec.rb +0 -18
- data/spec/code/group_spec.rb +0 -12
- data/spec/code/if_modifier_spec.rb +0 -20
- data/spec/code/if_spec.rb +0 -25
- data/spec/code/list_spec.rb +0 -19
- data/spec/code/multiplication_spec.rb +0 -18
- data/spec/code/negation_spec.rb +0 -20
- data/spec/code/not_keyword_spec.rb +0 -13
- data/spec/code/nothing_spec.rb +0 -17
- data/spec/code/number_spec.rb +0 -22
- data/spec/code/or_keyword_spec.rb +0 -17
- data/spec/code/or_operator_spec.rb +0 -16
- data/spec/code/parser/call_spec.rb +0 -26
- data/spec/code/power_spec.rb +0 -13
- data/spec/code/range_spec.rb +0 -16
- data/spec/code/rescue_spec.rb +0 -13
- data/spec/code/shift_spec.rb +0 -13
- data/spec/code/splat_spec.rb +0 -13
- data/spec/code/string_spec.rb +0 -27
- data/spec/code/ternary_spec.rb +0 -18
- data/spec/code/unary_minus_spec.rb +0 -13
- data/spec/code/while_spec.rb +0 -18
- data/template-ruby.gemspec +0 -19
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Code
|
4
|
+
class Node
|
5
|
+
class LeftOperation < Node
|
6
|
+
class Operator < Node
|
7
|
+
DOT = "."
|
8
|
+
COLON_COLON = "::"
|
9
|
+
|
10
|
+
attr_reader :operator, :statement
|
11
|
+
|
12
|
+
def initialize(parsed)
|
13
|
+
@operator = parsed.delete(:operator)
|
14
|
+
@statement = Statement.new(parsed.delete(:statement))
|
15
|
+
end
|
16
|
+
|
17
|
+
def call?
|
18
|
+
operator == DOT || operator == COLON_COLON
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(parsed)
|
23
|
+
@first = Statement.new(parsed.delete(:first))
|
24
|
+
@others =
|
25
|
+
parsed.delete(:others).map { |operator| Operator.new(operator) }
|
26
|
+
|
27
|
+
super(parsed)
|
28
|
+
end
|
29
|
+
|
30
|
+
def evaluate(**args)
|
31
|
+
first = @first.evaluate(**args)
|
32
|
+
|
33
|
+
@others.reduce(first) do |left, right|
|
34
|
+
if right.call?
|
35
|
+
right.statement.evaluate(**args, object: left)
|
36
|
+
else
|
37
|
+
statement = right.statement.evaluate(**args)
|
38
|
+
|
39
|
+
left.call(
|
40
|
+
**args,
|
41
|
+
operator: right.operator,
|
42
|
+
arguments: [::Code::Object::Argument.new(statement)]
|
43
|
+
)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def resolve(**args)
|
49
|
+
first = @first.resolve(**args)
|
50
|
+
|
51
|
+
list = Object::IdentifierList.new([first])
|
52
|
+
|
53
|
+
@others.each do |other|
|
54
|
+
list.code_append(
|
55
|
+
other.statement.resolve(**args, object: list.code_last)
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
list
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/code/node/list.rb
CHANGED
data/lib/code/node/negation.rb
CHANGED
data/lib/code/node/not.rb
CHANGED
data/lib/code/node/nothing.rb
CHANGED
data/lib/code/node/number.rb
CHANGED
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Code
|
4
|
+
class Node
|
5
|
+
class RightOperation < Node
|
6
|
+
EQUAL = "="
|
7
|
+
|
8
|
+
def initialize(parsed)
|
9
|
+
@left = Statement.new(parsed.delete(:left))
|
10
|
+
@operator = parsed.delete(:operator)
|
11
|
+
@right = Statement.new(parsed.delete(:right))
|
12
|
+
|
13
|
+
super(parsed)
|
14
|
+
end
|
15
|
+
|
16
|
+
def evaluate(**args)
|
17
|
+
case @operator
|
18
|
+
when "if"
|
19
|
+
if @right.evaluate(**args).truthy?
|
20
|
+
@left.evaluate(**args)
|
21
|
+
else
|
22
|
+
Object::Nothing.new
|
23
|
+
end
|
24
|
+
when "unless"
|
25
|
+
if @right.evaluate(**args).truthy?
|
26
|
+
Object::Nothing.new
|
27
|
+
else
|
28
|
+
@left.evaluate(**args)
|
29
|
+
end
|
30
|
+
when "while"
|
31
|
+
left = Object::Nothing.new
|
32
|
+
|
33
|
+
left = @left.evaluate(**args) while @right.evaluate(**args).truthy?
|
34
|
+
|
35
|
+
left
|
36
|
+
when "until"
|
37
|
+
left = Object::Nothing.new
|
38
|
+
|
39
|
+
left = @left.evaluate(**args) while @right.evaluate(**args).falsy?
|
40
|
+
|
41
|
+
left
|
42
|
+
when "rescue"
|
43
|
+
begin
|
44
|
+
@left.evaluate(**args)
|
45
|
+
rescue Error
|
46
|
+
@right.evaluate(**args)
|
47
|
+
end
|
48
|
+
when /=$/
|
49
|
+
right = @right.evaluate(**args)
|
50
|
+
left = @left.resolve(**args)
|
51
|
+
|
52
|
+
left.call(
|
53
|
+
operator: @operator,
|
54
|
+
arguments: [Object::Argument.new(right)],
|
55
|
+
**args
|
56
|
+
)
|
57
|
+
else
|
58
|
+
right = @right.evaluate(**args)
|
59
|
+
left = @left.evaluate(**args)
|
60
|
+
|
61
|
+
left.call(
|
62
|
+
operator: @operator,
|
63
|
+
arguments: [Object::Argument.new(right)],
|
64
|
+
**args
|
65
|
+
)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/code/node/splat.rb
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Code
|
4
|
+
class Node
|
5
|
+
class SquareBracket < Node
|
6
|
+
def initialize(parsed)
|
7
|
+
@left = Node::Statement.new(parsed.delete(:left))
|
8
|
+
@statements =
|
9
|
+
parsed
|
10
|
+
.delete(:statements)
|
11
|
+
.map { |statement| Node::Statement.new(statement) }
|
12
|
+
|
13
|
+
super(parsed)
|
14
|
+
end
|
15
|
+
|
16
|
+
def evaluate(**args)
|
17
|
+
left = @left.evaluate(**args)
|
18
|
+
|
19
|
+
@statements.reduce(left) do |object, statement|
|
20
|
+
object.code_fetch(statement.evaluate(**args))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def resolve(**args)
|
25
|
+
left = @left.resolve(**args)
|
26
|
+
|
27
|
+
list = Object::IdentifierList.new([left])
|
28
|
+
|
29
|
+
@statements.each do |statement|
|
30
|
+
list.code_append(statement.evaluate(**args))
|
31
|
+
end
|
32
|
+
|
33
|
+
list
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/code/node/statement.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Code
|
2
4
|
class Node
|
3
5
|
class Statement < Node
|
@@ -17,13 +19,13 @@ class Code
|
|
17
19
|
elsif parsed.key?(:list)
|
18
20
|
@statement = Node::List.new(parsed.delete(:list))
|
19
21
|
elsif parsed.key?(:dictionnary)
|
20
|
-
@statement = Node::
|
22
|
+
@statement = Node::Dictionary.new(parsed.delete(:dictionnary))
|
21
23
|
elsif parsed.key?(:chained_call)
|
22
24
|
@statement = Node::ChainedCall.new(parsed.delete(:chained_call))
|
23
|
-
elsif parsed.key?(:
|
24
|
-
@statement = Node::
|
25
|
-
elsif parsed.key?(:
|
26
|
-
@statement = Node::
|
25
|
+
elsif parsed.key?(:left_operation)
|
26
|
+
@statement = Node::LeftOperation.new(parsed.delete(:left_operation))
|
27
|
+
elsif parsed.key?(:right_operation)
|
28
|
+
@statement = Node::RightOperation.new(parsed.delete(:right_operation))
|
27
29
|
elsif parsed.key?(:function)
|
28
30
|
@statement = Node::Function.new(parsed.delete(:function))
|
29
31
|
elsif parsed.key?(:negation)
|
@@ -46,6 +48,8 @@ class Code
|
|
46
48
|
@statement = Node::While.new(parsed.delete(:while))
|
47
49
|
elsif parsed.key?(:splat)
|
48
50
|
@statement = Node::Splat.new(parsed.delete(:splat))
|
51
|
+
elsif parsed.key?(:square_bracket)
|
52
|
+
@statement = Node::SquareBracket.new(parsed.delete(:square_bracket))
|
49
53
|
end
|
50
54
|
|
51
55
|
super(parsed)
|
@@ -54,6 +58,10 @@ class Code
|
|
54
58
|
def evaluate(**args)
|
55
59
|
@statement.evaluate(**args)
|
56
60
|
end
|
61
|
+
|
62
|
+
def resolve(**args)
|
63
|
+
@statement.resolve(**args)
|
64
|
+
end
|
57
65
|
end
|
58
66
|
end
|
59
67
|
end
|
data/lib/code/node/string.rb
CHANGED
data/lib/code/node/ternary.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Code
|
2
4
|
class Node
|
3
5
|
class Ternary < Node
|
4
6
|
def initialize(parsed)
|
5
7
|
@left = Node::Statement.new(parsed.delete(:left))
|
6
8
|
@middle = Node::Statement.new(parsed.delete(:middle))
|
7
|
-
if parsed.key?(
|
8
|
-
|
9
|
-
|
9
|
+
@right = Node::Statement.new(parsed.delete(:right)) if parsed.key?(
|
10
|
+
:right
|
11
|
+
)
|
10
12
|
super(parsed)
|
11
13
|
end
|
12
14
|
|
data/lib/code/node/while.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Code
|
2
4
|
class Node
|
3
5
|
class While < Node
|
@@ -15,9 +17,9 @@ class Code
|
|
15
17
|
if @operator == WHILE_KEYWORD
|
16
18
|
last = ::Code::Object::Nothing.new
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
20
|
+
last = @body.evaluate(**args) while @statement.evaluate(
|
21
|
+
**args
|
22
|
+
).truthy?
|
21
23
|
|
22
24
|
last
|
23
25
|
elsif @operator == UNTIL_KEYWORD
|
@@ -27,7 +29,7 @@ class Code
|
|
27
29
|
|
28
30
|
last
|
29
31
|
else
|
30
|
-
raise NotImplementedError
|
32
|
+
raise NotImplementedError, @operator
|
31
33
|
end
|
32
34
|
end
|
33
35
|
end
|
data/lib/code/node.rb
CHANGED
@@ -1,13 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Code
|
2
4
|
class Node
|
3
5
|
def initialize(parsed)
|
4
|
-
|
5
|
-
|
6
|
-
|
6
|
+
return unless parsed.any?
|
7
|
+
|
8
|
+
raise NotImplementedError, "#{self.class.name}: #{parsed.inspect}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def evaluate(**_args)
|
12
|
+
raise NotImplementedError, "#{self.class.name}#evaluate"
|
7
13
|
end
|
8
14
|
|
9
|
-
def
|
10
|
-
|
15
|
+
def resolve(...)
|
16
|
+
evaluate(...)
|
11
17
|
end
|
12
18
|
end
|
13
19
|
end
|
data/lib/code/object/argument.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Code
|
2
4
|
class Object
|
3
|
-
class Argument
|
5
|
+
class Argument < Object
|
4
6
|
attr_reader :value, :name
|
5
7
|
|
6
8
|
def initialize(value, name: nil)
|
@@ -8,8 +10,12 @@ class Code
|
|
8
10
|
@name = name
|
9
11
|
end
|
10
12
|
|
11
|
-
def
|
12
|
-
|
13
|
+
def self.name
|
14
|
+
"Argument"
|
15
|
+
end
|
16
|
+
|
17
|
+
def inspect
|
18
|
+
to_s
|
13
19
|
end
|
14
20
|
|
15
21
|
def keyword?
|
@@ -20,12 +26,12 @@ class Code
|
|
20
26
|
[name, value]
|
21
27
|
end
|
22
28
|
|
23
|
-
def
|
24
|
-
|
29
|
+
def regular?
|
30
|
+
!name
|
25
31
|
end
|
26
32
|
|
27
|
-
def
|
28
|
-
|
33
|
+
def to_s
|
34
|
+
"<Argument #{value.inspect}>"
|
29
35
|
end
|
30
36
|
end
|
31
37
|
end
|
data/lib/code/object/boolean.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Code
|
2
4
|
class Object
|
3
5
|
class Boolean < ::Code::Object
|
@@ -7,20 +9,56 @@ class Code
|
|
7
9
|
@raw = raw
|
8
10
|
end
|
9
11
|
|
10
|
-
def
|
11
|
-
|
12
|
+
def self.name
|
13
|
+
"Boolean"
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(**args)
|
17
|
+
operator = args.fetch(:operator, nil)
|
18
|
+
arguments = args.fetch(:arguments, [])
|
19
|
+
value = arguments.first&.value
|
20
|
+
|
21
|
+
case operator.to_s
|
22
|
+
when "&", "bitwise_and"
|
23
|
+
sig(args) { Boolean }
|
24
|
+
code_bitwise_and(value)
|
25
|
+
when "^", "bitwise_xor"
|
26
|
+
sig(args) { Boolean }
|
27
|
+
code_bitwise_xor(value)
|
28
|
+
when "|", "bitwise_or"
|
29
|
+
sig(args) { Boolean }
|
30
|
+
code_bitwise_or(value)
|
31
|
+
else
|
32
|
+
super
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def code_bitwise_and(value)
|
37
|
+
Boolean.new(raw & value.raw)
|
38
|
+
end
|
39
|
+
|
40
|
+
def code_bitwise_or(value)
|
41
|
+
Boolean.new(raw | value.raw)
|
42
|
+
end
|
43
|
+
|
44
|
+
def code_bitwise_xor(value)
|
45
|
+
Boolean.new(raw ^ value.raw)
|
46
|
+
end
|
47
|
+
|
48
|
+
def inspect
|
49
|
+
to_s
|
12
50
|
end
|
13
51
|
|
14
52
|
def succ
|
15
|
-
|
53
|
+
Boolean.new(!raw)
|
16
54
|
end
|
17
55
|
|
18
56
|
def to_s
|
19
57
|
raw.to_s
|
20
58
|
end
|
21
59
|
|
22
|
-
def
|
23
|
-
|
60
|
+
def truthy?
|
61
|
+
raw
|
24
62
|
end
|
25
63
|
end
|
26
64
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Code
|
4
|
+
class Object
|
5
|
+
class Context < Dictionary
|
6
|
+
attr_reader :parent
|
7
|
+
|
8
|
+
def initialize(raw = {}, parent: nil)
|
9
|
+
@raw = raw
|
10
|
+
@parent = parent
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.name
|
14
|
+
"Context"
|
15
|
+
end
|
16
|
+
|
17
|
+
def lookup!(identifier)
|
18
|
+
if code_has_key?(identifier).truthy?
|
19
|
+
self
|
20
|
+
elsif parent?
|
21
|
+
parent.lookup!(identifier)
|
22
|
+
else
|
23
|
+
raise Code::Error::Undefined, "#{identifier} is not defined"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def merge(other)
|
28
|
+
Context.new(raw.merge(other.raw), parent: parent || other.parent)
|
29
|
+
end
|
30
|
+
|
31
|
+
def parent?
|
32
|
+
!!parent
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|