loxxy 0.0.16 → 0.0.17
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/.rubocop.yml +1 -1
- data/CHANGELOG.md +16 -1
- data/README.md +9 -12
- data/lib/loxxy/ast/all_lox_nodes.rb +3 -1
- data/lib/loxxy/ast/ast_builder.rb +12 -1
- data/lib/loxxy/ast/ast_visitor.rb +10 -2
- data/lib/loxxy/ast/lox_binary_expr.rb +1 -1
- data/lib/loxxy/ast/lox_unary_expr.rb +27 -0
- data/lib/loxxy/back_end/engine.rb +13 -3
- data/lib/loxxy/datatype/builtin_datatype.rb +28 -0
- data/lib/loxxy/datatype/false.rb +14 -8
- data/lib/loxxy/datatype/lx_string.rb +0 -14
- data/lib/loxxy/datatype/nil.rb +12 -6
- data/lib/loxxy/datatype/number.rb +44 -6
- data/lib/loxxy/datatype/true.rb +1 -9
- data/lib/loxxy/front_end/grammar.rb +1 -1
- data/lib/loxxy/version.rb +1 -1
- data/spec/interpreter_spec.rb +57 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6eed6a7de54b89c276b0f098cd7d824f26c0ce9ba957d4fb9e3a4d12e6dfbc4f
|
4
|
+
data.tar.gz: ba7c00f11c5b69322aec0d447c2fef9cf6d6d74b2ea7bb16096581508a786427
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b2c3826f085ce3f723cdbc70c3bdc3563817270985a321db05f97ca1ff81971bf872db49631d3fa20580932f7a0e2910bf3c6c84daf7873cdcd1f04c3392a99
|
7
|
+
data.tar.gz: 4e3d075facaf9c370d78f3f3ac89b7226e375eb32064535e3401c5ef52b8ca43c9d4c6cfb8f027b4037c7baa7c5945b0fd0dbe1e8b1e580fc732c4a38f7c57c6
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
## [0.0.17] - 2021-01-12
|
2
|
+
- The interpreter can evaluate all arithmetic and comparison operations.
|
3
|
+
- It implements `==`, `!=` and the unary operations `!`, `-`
|
4
|
+
|
5
|
+
## Added
|
6
|
+
- Class `AST::LoxUnaryExpr`
|
7
|
+
- Method `AST::ASTBuilder#reduce_unary_expr` to support the evaluation of `!` and ``-@`
|
8
|
+
- Method `Ast::ASTVisitor#visit_unnary_expr` for visiting unary expressions
|
9
|
+
- Method `Backend::Engine#after_unary_expr` evaluating an unary expression
|
10
|
+
- In class `Datatype::BuiltinDatatype` the methods `falsey?`, `truthy?`, `!`, `!=`
|
11
|
+
- In class `Datatype::Number`the methods `<`, `<=`, ´>´, `>=` and `-@`
|
12
|
+
|
13
|
+
## Changed
|
14
|
+
- File `README.md` updated.
|
15
|
+
|
1
16
|
## [0.0.16] - 2021-01-11
|
2
17
|
- The interpreter can evaluate product and division of two numbers.
|
3
18
|
- It also implements equality `==` and inequality `!=` operators
|
@@ -36,7 +51,7 @@
|
|
36
51
|
- The interpreter can evaluate addition of numbers and string concatenation
|
37
52
|
|
38
53
|
## Added
|
39
|
-
- Method `Ast::ASTVisitor
|
54
|
+
- Method `Ast::ASTVisitor#visit_binary_expr` for visiting binary expressions
|
40
55
|
- Method `Ast::LoxBinaryExpr#accept` for visitor pattern
|
41
56
|
- Method `BackEnd::Engine#after_binary_expr` to trigger execution of binary operator
|
42
57
|
- `Boolean` class hierarchy: added methos `true?` and `false?` to ease spec test writing
|
data/README.md
CHANGED
@@ -154,21 +154,16 @@ The parser knows all the __Lox__ reserved keywords:
|
|
154
154
|
and, class, else, false, fun, for, if, nil, or,
|
155
155
|
print, return, super, this, true, var, while
|
156
156
|
```
|
157
|
-
Of these, the interpreter implements: `false`, `nil`, `true`
|
157
|
+
Of these, the interpreter implements: `false`, `nil`, `print`, `true`
|
158
158
|
|
159
159
|
### Operators and Special Chars
|
160
160
|
#### Operators
|
161
|
-
The
|
161
|
+
The __loxxy__ interpreter supports all the __Lox__ unary and binary operators:
|
162
162
|
- Arithmetic operators: `+`, `-`, `*`, `/`
|
163
163
|
- Comparison operators: `>`, `>=`, `<`, `<=`
|
164
164
|
- Equality operators: `==`, `!=`
|
165
|
-
|
166
|
-
|
167
|
-
`+` (addition of two numbers or string concatenation)
|
168
|
-
`-` (difference between two numbers)
|
169
|
-
`*` (product of two numbers)
|
170
|
-
`/` (division of two number)
|
171
|
-
`==` and `!=` (in)equality testing of two Lox values
|
165
|
+
- Unary negate (change sign): `-`
|
166
|
+
- Unary not: `!`
|
172
167
|
|
173
168
|
#### Delimiters
|
174
169
|
The parser knows all the __Lox__ grouping delimiters:
|
@@ -196,9 +191,11 @@ loxxy supports all the standard __Lox__ datatypes:
|
|
196
191
|
### Implemented expressions
|
197
192
|
Loxxy implements expressions:
|
198
193
|
- Plain literals only; or,
|
199
|
-
-
|
194
|
+
- (In)equality testing between two values; or,
|
195
|
+
- Basic arithmetic operations (`+`, `-`, `*`, `/`, `unary -`); or,
|
196
|
+
- Comparison between two numbers; or,
|
200
197
|
- Concatenation of two strings,
|
201
|
-
-
|
198
|
+
- Negation `!`
|
202
199
|
|
203
200
|
### Implemented statements
|
204
201
|
Loxxy implements the following statements:
|
@@ -206,7 +203,7 @@ Loxxy implements the following statements:
|
|
206
203
|
- Print statement
|
207
204
|
|
208
205
|
```javascript
|
209
|
-
// Print statement with nested concatenation
|
206
|
+
// Print statement with nested string concatenation
|
210
207
|
print "Hello" + ", " + "world!";
|
211
208
|
```
|
212
209
|
|
@@ -15,7 +15,6 @@ module Loxxy
|
|
15
15
|
# @return [Hash{String => String}]
|
16
16
|
Name2special = {
|
17
17
|
'AND' => 'and',
|
18
|
-
'BANG' => '!',
|
19
18
|
'BANG_EQUAL' => '!=',
|
20
19
|
'COMMA' => ',',
|
21
20
|
'DOT' => '.',
|
@@ -36,6 +35,11 @@ module Loxxy
|
|
36
35
|
'SLASH' => '/',
|
37
36
|
'STAR' => '*'
|
38
37
|
}.freeze
|
38
|
+
|
39
|
+
Name2unary = {
|
40
|
+
'BANG' => '!',
|
41
|
+
'MINUS' => '-@'
|
42
|
+
}.freeze
|
39
43
|
end # defined
|
40
44
|
|
41
45
|
attr_reader :strict
|
@@ -231,6 +235,13 @@ module Loxxy
|
|
231
235
|
reduce_binary_plus_end(production, range, tokens, theChildren)
|
232
236
|
end
|
233
237
|
|
238
|
+
# rule('unary' => 'unaryOp unary')
|
239
|
+
def reduce_unary_expr(_production, _range, tokens, theChildren)
|
240
|
+
operator = Name2unary[theChildren[0].symbol.name].to_sym
|
241
|
+
operand = theChildren[1]
|
242
|
+
LoxUnaryExpr.new(tokens[0].position, operator, operand)
|
243
|
+
end
|
244
|
+
|
234
245
|
# rule('primary' => 'FALSE' | TRUE').as 'literal_expr'
|
235
246
|
def reduce_literal_expr(_production, _range, _tokens, theChildren)
|
236
247
|
first_child = theChildren.first
|
@@ -51,7 +51,7 @@ module Loxxy
|
|
51
51
|
broadcast(:after_ptree, aParseTree)
|
52
52
|
end
|
53
53
|
|
54
|
-
# Visit event. The visitor is about to visit a print statement
|
54
|
+
# Visit event. The visitor is about to visit a print statement.
|
55
55
|
# @param aPrintStmt [AST::LOXPrintStmt] the print statement node to visit
|
56
56
|
def visit_print_stmt(aPrintStmt)
|
57
57
|
broadcast(:before_print_stmt, aPrintStmt)
|
@@ -59,7 +59,7 @@ module Loxxy
|
|
59
59
|
broadcast(:after_print_stmt, aPrintStmt)
|
60
60
|
end
|
61
61
|
|
62
|
-
# Visit event. The visitor is about to visit a
|
62
|
+
# Visit event. The visitor is about to visit a binary expression.
|
63
63
|
# @param aBinaryExpr [AST::LOXBinaryExpr] the binary expression node to visit
|
64
64
|
def visit_binary_expr(aBinaryExpr)
|
65
65
|
broadcast(:before_binary_expr, aBinaryExpr)
|
@@ -67,6 +67,14 @@ module Loxxy
|
|
67
67
|
broadcast(:after_binary_expr, aBinaryExpr)
|
68
68
|
end
|
69
69
|
|
70
|
+
# Visit event. The visitor is about to visit an unary expression.
|
71
|
+
# @param anUnaryExpr [AST::anUnaryExpr] unary expression node to visit
|
72
|
+
def visit_unary_expr(anUnaryExpr)
|
73
|
+
broadcast(:before_unary_expr, anUnaryExpr)
|
74
|
+
traverse_subnodes(anUnaryExpr)
|
75
|
+
broadcast(:after_unary_expr, anUnaryExpr)
|
76
|
+
end
|
77
|
+
|
70
78
|
# Visit event. The visitor is visiting the
|
71
79
|
# given terminal node containing a datatype object.
|
72
80
|
# @param aLiteralExpr [AST::LoxLiteralExpr] the leaf node to visit.
|
@@ -5,7 +5,7 @@ require_relative 'lox_compound_expr'
|
|
5
5
|
module Loxxy
|
6
6
|
module Ast
|
7
7
|
class LoxBinaryExpr < LoxCompoundExpr
|
8
|
-
# @return [Symbol]
|
8
|
+
# @return [Symbol] message name to be sent to receiver
|
9
9
|
attr_reader :operator
|
10
10
|
|
11
11
|
# @param aPosition [Rley::Lexical::Position] Position of the entry in the input stream.
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lox_compound_expr'
|
4
|
+
|
5
|
+
module Loxxy
|
6
|
+
module Ast
|
7
|
+
class LoxUnaryExpr < LoxCompoundExpr
|
8
|
+
# @return [Symbol] message name to be sent to receiver
|
9
|
+
attr_reader :operator
|
10
|
+
|
11
|
+
# @param aPosition [Rley::Lexical::Position] Position of the entry in the input stream.
|
12
|
+
# @param operand [Loxxy::Ast::LoxNode]
|
13
|
+
def initialize(aPosition, anOperator, operand)
|
14
|
+
super(aPosition, [operand])
|
15
|
+
@operator = anOperator
|
16
|
+
end
|
17
|
+
|
18
|
+
# Part of the 'visitee' role in Visitor design pattern.
|
19
|
+
# @param visitor [Ast::ASTVisitor] the visitor
|
20
|
+
def accept(visitor)
|
21
|
+
visitor.visit_unary_expr(self)
|
22
|
+
end
|
23
|
+
|
24
|
+
alias operands subnodes
|
25
|
+
end # class
|
26
|
+
end # module
|
27
|
+
end # module
|
@@ -22,7 +22,7 @@ module Loxxy
|
|
22
22
|
@stack = []
|
23
23
|
end
|
24
24
|
|
25
|
-
# Given an abstract syntax parse tree visitor,
|
25
|
+
# Given an abstract syntax parse tree visitor, launch the visit
|
26
26
|
# and execute the visit events in the output stream.
|
27
27
|
# @param aVisitor [AST::ASTVisitor]
|
28
28
|
# @return [Loxxy::Datatype::BuiltinDatatype]
|
@@ -44,8 +44,7 @@ module Loxxy
|
|
44
44
|
op = aBinaryExpr.operator
|
45
45
|
operand2 = stack.pop
|
46
46
|
operand1 = stack.pop
|
47
|
-
|
48
|
-
if implemented && operand1.respond_to?(op)
|
47
|
+
if operand1.respond_to?(op)
|
49
48
|
stack.push operand1.send(op, operand2)
|
50
49
|
else
|
51
50
|
msg1 = "`#{op}': Unimplemented operator for a #{operand1.class}."
|
@@ -53,6 +52,17 @@ module Loxxy
|
|
53
52
|
end
|
54
53
|
end
|
55
54
|
|
55
|
+
def after_unary_expr(anUnaryExpr)
|
56
|
+
op = anUnaryExpr.operator
|
57
|
+
operand = stack.pop
|
58
|
+
if operand.respond_to?(op)
|
59
|
+
stack.push operand.send(op)
|
60
|
+
else
|
61
|
+
msg1 = "`#{op}': Unimplemented operator for a #{operand1.class}."
|
62
|
+
raise StandardError, msg1
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
56
66
|
# @param literalExpr [Ast::LoxLiteralExpr]
|
57
67
|
def before_literal_expr(literalExpr)
|
58
68
|
stack.push(literalExpr.literal)
|
@@ -14,6 +14,34 @@ module Loxxy
|
|
14
14
|
@value = validated_value(aValue)
|
15
15
|
end
|
16
16
|
|
17
|
+
# Is the value considered falsey in Lox?
|
18
|
+
# Rule: false and nil are falsey and everything else is truthy.
|
19
|
+
# This test used in conditional statements (i.e. if, while)
|
20
|
+
def falsey?
|
21
|
+
false # Default implementation
|
22
|
+
end
|
23
|
+
|
24
|
+
# Is the value considered truthy in Lox?
|
25
|
+
# Rule: false and nil are falsey and everything else is truthy.
|
26
|
+
# This test used in conditional statements (i.e. if, while)
|
27
|
+
def truthy?
|
28
|
+
true # Default implementation
|
29
|
+
end
|
30
|
+
|
31
|
+
# Negation ('not')
|
32
|
+
# Returns a boolean with opposite truthiness value.
|
33
|
+
# @return [Datatype::Boolean]
|
34
|
+
def !
|
35
|
+
falsey? ? True.instance : False.instance
|
36
|
+
end
|
37
|
+
|
38
|
+
# Check for inequality of this object with another Lox object
|
39
|
+
# @param other [Datatype::BuiltinDatatype, Object]
|
40
|
+
# @return [Datatype::Boolean]
|
41
|
+
def !=(other)
|
42
|
+
!(self == other)
|
43
|
+
end
|
44
|
+
|
17
45
|
# Method called from Lox to obtain the text representation of the boolean.
|
18
46
|
# @return [String]
|
19
47
|
def to_str
|
data/lib/loxxy/datatype/false.rb
CHANGED
@@ -20,6 +20,20 @@ module Loxxy
|
|
20
20
|
true
|
21
21
|
end
|
22
22
|
|
23
|
+
# Is the value considered falsey in Lox?
|
24
|
+
# Rule: false and nil are falsey and everything else is truthy.
|
25
|
+
# This test used in conditional statements (i.e. if, while)
|
26
|
+
def falsey?
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
30
|
+
# Is the value considered truthy in Lox?
|
31
|
+
# Rule: false and nil are falsey and everything else is truthy.
|
32
|
+
# This test used in conditional statements (i.e. if, while)
|
33
|
+
def truthy?
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
23
37
|
# Check for equality of a Lox False with another Lox object
|
24
38
|
# @param other [Datatype::BuiltinDatatype, FalseClass, Object]
|
25
39
|
# @return [Datatype::Boolean]
|
@@ -27,14 +41,6 @@ module Loxxy
|
|
27
41
|
falsey = other.kind_of?(False) || other.kind_of?(FalseClass)
|
28
42
|
falsey ? True.instance : False.instance
|
29
43
|
end
|
30
|
-
|
31
|
-
# Check for inequality of a Lox False with another Lox object
|
32
|
-
# @param other [Datatype::BuiltinDatatype, FalseClass, Object]
|
33
|
-
# @return [Datatype::Boolean]
|
34
|
-
def !=(other)
|
35
|
-
falsey = other.kind_of?(False) || other.kind_of?(FalseClass)
|
36
|
-
falsey ? False.instance : True.instance
|
37
|
-
end
|
38
44
|
end # class
|
39
45
|
|
40
46
|
False.instance.freeze # Make the sole instance immutable
|
@@ -21,20 +21,6 @@ module Loxxy
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
# Check the inequality of a Lox String with another Lox object.
|
25
|
-
# @param other [Datatype::LxString, String, Object]
|
26
|
-
# @return [Datatype::Boolean]
|
27
|
-
def !=(other)
|
28
|
-
case other
|
29
|
-
when LXString
|
30
|
-
(value != other.value) ? True.instance : False.instance
|
31
|
-
when String
|
32
|
-
(value != other) ? True.instance : False.instance
|
33
|
-
else
|
34
|
-
True.instance
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
24
|
# Perform the concatenation of two Lox stings or
|
39
25
|
# one Lox string and a Ruby String
|
40
26
|
# @param other [Loxxy::Datatype::LXString, String]
|
data/lib/loxxy/datatype/nil.rb
CHANGED
@@ -22,12 +22,18 @@ module Loxxy
|
|
22
22
|
is_nil ? True.instance : False.instance
|
23
23
|
end
|
24
24
|
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
def
|
29
|
-
|
30
|
-
|
25
|
+
# Is the value considered falsey in Lox?
|
26
|
+
# Rule: false and nil are falsey and everything else is truthy.
|
27
|
+
# This test used in conditional statements (i.e. if, while)
|
28
|
+
def falsey?
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
# Is the value considered truthy in Lox?
|
33
|
+
# Rule: false and nil are falsey and everything else is truthy.
|
34
|
+
# This test used in conditional statements (i.e. if, while)
|
35
|
+
def truthy?
|
36
|
+
false
|
31
37
|
end
|
32
38
|
|
33
39
|
# Method called from Lox to obtain the text representation of nil.
|
@@ -71,6 +71,12 @@ module Loxxy
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
+
# Unary minus (return value with changed sign)
|
75
|
+
# @return [Loxxy::Datatype::Number]
|
76
|
+
def -@
|
77
|
+
self.class.new(-value)
|
78
|
+
end
|
79
|
+
|
74
80
|
# Check the equality of a Lox number object with another object
|
75
81
|
# @param other [Datatype::BuiltinDatatype, Numeric, Object]
|
76
82
|
# @return [Datatype::Boolean]
|
@@ -85,20 +91,52 @@ module Loxxy
|
|
85
91
|
end
|
86
92
|
end
|
87
93
|
|
88
|
-
# Check
|
89
|
-
# @param other [Datatype::
|
94
|
+
# Check whether this Lox number has a greater value than given argument.
|
95
|
+
# @param other [Datatype::Number, Numeric]
|
96
|
+
# @return [Datatype::Boolean]
|
97
|
+
def >(other)
|
98
|
+
case other
|
99
|
+
when Number
|
100
|
+
(value > other.value) ? True.instance : False.instance
|
101
|
+
when Numeric
|
102
|
+
(value > other) ? True.instance : False.instance
|
103
|
+
else
|
104
|
+
msg = "'>': Operands must be numbers."
|
105
|
+
raise StandardError, msg
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Check whether this Lox number has a greater or equal value
|
110
|
+
# than given argument.
|
111
|
+
# @param other [Datatype::Number, Numeric]
|
90
112
|
# @return [Datatype::Boolean]
|
91
|
-
def
|
113
|
+
def >=(other)
|
92
114
|
case other
|
93
115
|
when Number
|
94
|
-
(value
|
116
|
+
(value >= other.value) ? True.instance : False.instance
|
95
117
|
when Numeric
|
96
|
-
(value
|
118
|
+
(value >= other) ? True.instance : False.instance
|
97
119
|
else
|
98
|
-
|
120
|
+
msg = "'>': Operands must be numbers."
|
121
|
+
raise StandardError, msg
|
99
122
|
end
|
100
123
|
end
|
101
124
|
|
125
|
+
# Check whether this Lox number has a lesser value than given argument.
|
126
|
+
# @param other [Datatype::Number, Numeric]
|
127
|
+
# @return [Datatype::Boolean]
|
128
|
+
def <(other)
|
129
|
+
!(self >= other)
|
130
|
+
end
|
131
|
+
|
132
|
+
# Check whether this Lox number has a lesser or equal value
|
133
|
+
# than given argument.
|
134
|
+
# @param other [Datatype::Number, Numeric]
|
135
|
+
# @return [Datatype::Boolean]
|
136
|
+
def <=(other)
|
137
|
+
!(self > other)
|
138
|
+
end
|
139
|
+
|
102
140
|
protected
|
103
141
|
|
104
142
|
def validated_value(aValue)
|
data/lib/loxxy/datatype/true.rb
CHANGED
@@ -20,21 +20,13 @@ module Loxxy
|
|
20
20
|
true
|
21
21
|
end
|
22
22
|
|
23
|
-
# Check for equality of a Lox True with another Lox object
|
23
|
+
# Check for equality of a Lox True with another Lox object / Ruby true
|
24
24
|
# @param other [Datatype::True, TrueClass, Object]
|
25
25
|
# @return [Datatype::Boolean]
|
26
26
|
def ==(other)
|
27
27
|
thruthy = other.kind_of?(True) || other.kind_of?(TrueClass)
|
28
28
|
thruthy ? True.instance : False.instance
|
29
29
|
end
|
30
|
-
|
31
|
-
# Check for inequality of a Lox True with another Lox object
|
32
|
-
# @param other [Datatype::BuiltinDatatype, TrueClass, Object]
|
33
|
-
# @return [Datatype::Boolean]
|
34
|
-
def !=(other)
|
35
|
-
thruthy = other.kind_of?(True) || other.kind_of?(TrueClass)
|
36
|
-
thruthy ? False.instance : True.instance
|
37
|
-
end
|
38
30
|
end # class
|
39
31
|
|
40
32
|
True.instance.freeze # Make the sole instance immutable
|
@@ -121,7 +121,7 @@ module Loxxy
|
|
121
121
|
rule('multiplicative_plus' => 'multOp unary').as 'multiplicative_plus_end'
|
122
122
|
rule('multOp' => 'SLASH')
|
123
123
|
rule('multOp' => 'STAR')
|
124
|
-
rule('unary' => 'unaryOp unary')
|
124
|
+
rule('unary' => 'unaryOp unary').as 'unary_expr'
|
125
125
|
rule('unary' => 'call')
|
126
126
|
rule('unaryOp' => 'BANG')
|
127
127
|
rule('unaryOp' => 'MINUS')
|
data/lib/loxxy/version.rb
CHANGED
data/spec/interpreter_spec.rb
CHANGED
@@ -107,6 +107,63 @@ module Loxxy
|
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
110
|
+
it 'should evaluate a comparison of two numbers' do
|
111
|
+
[
|
112
|
+
['1 < 2;', true],
|
113
|
+
['2 < 2;', false],
|
114
|
+
['2 < 1;', false],
|
115
|
+
['1 <= 2;', true],
|
116
|
+
['2 <= 2;', true],
|
117
|
+
['2 <= 1;', false],
|
118
|
+
['1 > 2;', false],
|
119
|
+
['2 > 2;', false],
|
120
|
+
['2 > 1;', true],
|
121
|
+
['1 >= 2;', false],
|
122
|
+
['2 >= 2;', true],
|
123
|
+
['2 >= 1;', true],
|
124
|
+
['0 < -0;', false],
|
125
|
+
['-0 < 0;', false],
|
126
|
+
['0 > -0;', false],
|
127
|
+
['-0 > 0;', false],
|
128
|
+
['0 <= -0;', true],
|
129
|
+
['-0 <= 0;', true],
|
130
|
+
['0 >= -0;', true],
|
131
|
+
['-0 >= 0;', true]
|
132
|
+
].each do |(source, predicted)|
|
133
|
+
lox = Loxxy::Interpreter.new
|
134
|
+
result = lox.evaluate(source)
|
135
|
+
expect(result.value == predicted).to be_truthy
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'should evaluate the change sign of a number' do
|
140
|
+
[
|
141
|
+
['- 3;', -3],
|
142
|
+
['- - 3;', 3],
|
143
|
+
['- - - 3;', -3]
|
144
|
+
].each do |(source, predicted)|
|
145
|
+
lox = Loxxy::Interpreter.new
|
146
|
+
result = lox.evaluate(source)
|
147
|
+
expect(result.value == predicted).to be_truthy
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'should evaluate the negation of an object' do
|
152
|
+
[
|
153
|
+
['!true;', false],
|
154
|
+
['!false;', true],
|
155
|
+
['!!true;', true],
|
156
|
+
['!123;', false],
|
157
|
+
['!0;', false],
|
158
|
+
['!nil;', true],
|
159
|
+
['!"";', false]
|
160
|
+
].each do |(source, predicted)|
|
161
|
+
lox = Loxxy::Interpreter.new
|
162
|
+
result = lox.evaluate(source)
|
163
|
+
expect(result.value == predicted).to be_truthy
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
110
167
|
it 'should print the hello world message' do
|
111
168
|
expect { subject.evaluate(hello_world) }.not_to raise_error
|
112
169
|
expect(sample_cfg[:ostream].string).to eq('Hello, world!')
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: loxxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.17
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitri Geshef
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-01-
|
11
|
+
date: 2021-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rley
|
@@ -93,6 +93,7 @@ files:
|
|
93
93
|
- lib/loxxy/ast/lox_node.rb
|
94
94
|
- lib/loxxy/ast/lox_noop_expr.rb
|
95
95
|
- lib/loxxy/ast/lox_print_stmt.rb
|
96
|
+
- lib/loxxy/ast/lox_unary_expr.rb
|
96
97
|
- lib/loxxy/back_end/engine.rb
|
97
98
|
- lib/loxxy/datatype/all_datatypes.rb
|
98
99
|
- lib/loxxy/datatype/boolean.rb
|