trxl 0.1.5 → 0.1.8
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.
- data/README +17 -7
- data/VERSION +1 -1
- data/lib/trxl.rb +1 -1
- data/lib/trxl/trxl.rb +181 -135
- data/lib/trxl/trxl_grammar.rb +1354 -1078
- data/lib/trxl/trxl_grammar.treetop +103 -82
- data/spec/trxl/conditionals_spec.rb +32 -18
- data/spec/trxl/ranges_spec.rb +13 -30
- data/spec/trxl/require_spec.rb +11 -11
- data/spec/trxl/stdlib_spec.rb +243 -52
- data/spec/trxl/strings_spec.rb +20 -0
- data/trxl.gemspec +34 -57
- metadata +40 -37
- data/.gitignore +0 -24
@@ -54,10 +54,10 @@ grammar Trxl
|
|
54
54
|
/
|
55
55
|
case_expression
|
56
56
|
/
|
57
|
-
binary_expression
|
58
|
-
/
|
59
|
-
negated_expression
|
60
|
-
/
|
57
|
+
binary_expression
|
58
|
+
/
|
59
|
+
negated_expression
|
60
|
+
/
|
61
61
|
unary_expression
|
62
62
|
end
|
63
63
|
|
@@ -74,18 +74,18 @@ grammar Trxl
|
|
74
74
|
end
|
75
75
|
}
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
rule unary_expression
|
79
79
|
require_directive
|
80
80
|
/
|
81
81
|
definition
|
82
|
-
/
|
82
|
+
/
|
83
83
|
comparative
|
84
84
|
/
|
85
85
|
additive
|
86
86
|
end
|
87
87
|
|
88
|
-
|
88
|
+
|
89
89
|
rule definition
|
90
90
|
variable space '=' space expression {
|
91
91
|
def eval(env = Environment.new)
|
@@ -97,11 +97,11 @@ grammar Trxl
|
|
97
97
|
end
|
98
98
|
}
|
99
99
|
end
|
100
|
-
|
100
|
+
|
101
101
|
|
102
102
|
rule if_expression
|
103
103
|
|
104
|
-
'if' space '(' space if_exp:expression space ')' SPACE
|
104
|
+
'if' space '(' space if_exp:expression space ')' SPACE
|
105
105
|
if_branch:statement_list space
|
106
106
|
elsif_branches:(elsif_expression_list SPACE)?
|
107
107
|
else_branch:('else' SPACE statement_list SPACE)?
|
@@ -152,20 +152,19 @@ grammar Trxl
|
|
152
152
|
case_keyword SPACE case_exp:expression SPACE
|
153
153
|
when_expression_list SPACE
|
154
154
|
'else' SPACE else_exp:statement_list SPACE
|
155
|
-
end_keyword
|
155
|
+
end_keyword
|
156
156
|
|
157
157
|
{
|
158
158
|
def eval(env = Environment.new)
|
159
159
|
case_val = case_exp.eval(env)
|
160
160
|
else_val = else_exp.eval(env)
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
CASE_STMT
|
161
|
+
|
162
|
+
Kernel.eval <<-CASE
|
163
|
+
case case_val
|
164
|
+
#{ruby_when_expressions(env)}
|
165
|
+
else #{else_val.is_a?(String) ? "'#{else_val}'" : else_val}
|
166
|
+
end
|
167
|
+
CASE
|
169
168
|
end
|
170
169
|
|
171
170
|
def ruby_when_expressions(env = Environment.new)
|
@@ -183,12 +182,21 @@ grammar Trxl
|
|
183
182
|
def eval(env = Environment.new)
|
184
183
|
condition = when_exp.eval(env)
|
185
184
|
expression = statement_list.eval(env)
|
186
|
-
{
|
185
|
+
{
|
187
186
|
# use '' instead of "" since we don't care about var replacement now
|
188
|
-
:condition => (condition
|
187
|
+
:condition => ruby_when_condition(condition),
|
189
188
|
:expression => (expression.is_a?(String) ? "'#{expression}'" : expression)
|
190
189
|
}
|
191
190
|
end
|
191
|
+
|
192
|
+
def ruby_when_condition(condition)
|
193
|
+
case condition
|
194
|
+
when nil then "nil"
|
195
|
+
when String then "'#{condition}'"
|
196
|
+
else
|
197
|
+
condition
|
198
|
+
end
|
199
|
+
end
|
192
200
|
}
|
193
201
|
end
|
194
202
|
|
@@ -232,11 +240,11 @@ grammar Trxl
|
|
232
240
|
end
|
233
241
|
}
|
234
242
|
end
|
235
|
-
|
243
|
+
|
236
244
|
rule operator
|
237
245
|
function / variable
|
238
246
|
end
|
239
|
-
|
247
|
+
|
240
248
|
rule function
|
241
249
|
'fun' formal_parameter_list space '{' space body:statement_list space '}' <Function>
|
242
250
|
end
|
@@ -275,7 +283,7 @@ grammar Trxl
|
|
275
283
|
|
276
284
|
def to_s(env = Environment.new)
|
277
285
|
'()'
|
278
|
-
end
|
286
|
+
end
|
279
287
|
}
|
280
288
|
end
|
281
289
|
|
@@ -295,7 +303,7 @@ grammar Trxl
|
|
295
303
|
def eval(env = Environment.new)
|
296
304
|
[]
|
297
305
|
end
|
298
|
-
|
306
|
+
|
299
307
|
def to_s(env = Environment.new)
|
300
308
|
'()'
|
301
309
|
end
|
@@ -338,7 +346,7 @@ grammar Trxl
|
|
338
346
|
def eval(env = Environment.new)
|
339
347
|
{}
|
340
348
|
end
|
341
|
-
|
349
|
+
|
342
350
|
def to_s(env = Environment.new)
|
343
351
|
text_value
|
344
352
|
end
|
@@ -365,7 +373,7 @@ grammar Trxl
|
|
365
373
|
def eval(env = Environment.new)
|
366
374
|
{ key.eval(env) => value.eval(env) }
|
367
375
|
end
|
368
|
-
|
376
|
+
|
369
377
|
def to_s(env = Environment.new)
|
370
378
|
text_value
|
371
379
|
end
|
@@ -388,7 +396,7 @@ grammar Trxl
|
|
388
396
|
def eval(env = Environment.new)
|
389
397
|
[]
|
390
398
|
end
|
391
|
-
|
399
|
+
|
392
400
|
def to_s(env = Environment.new)
|
393
401
|
text_value
|
394
402
|
end
|
@@ -443,7 +451,7 @@ grammar Trxl
|
|
443
451
|
end
|
444
452
|
}
|
445
453
|
end
|
446
|
-
|
454
|
+
|
447
455
|
rule comparative
|
448
456
|
operand_1:additive space operator:equality_op space operand_2:additive <BinaryOperation>
|
449
457
|
end
|
@@ -462,14 +470,14 @@ grammar Trxl
|
|
462
470
|
raise Trxl::InvalidOperationException, "Left operand is not an Array"
|
463
471
|
end
|
464
472
|
end
|
465
|
-
|
473
|
+
|
466
474
|
# override default behavior since it's not possible to push into nil
|
467
475
|
def lhs_nil_allowed?
|
468
476
|
false
|
469
477
|
end
|
470
|
-
}
|
478
|
+
}
|
471
479
|
end
|
472
|
-
|
480
|
+
|
473
481
|
rule equality_op
|
474
482
|
'==' <NilAcceptingOperator>
|
475
483
|
/
|
@@ -483,7 +491,7 @@ grammar Trxl
|
|
483
491
|
/
|
484
492
|
'>' <NilRejectingOperator>
|
485
493
|
end
|
486
|
-
|
494
|
+
|
487
495
|
rule additive
|
488
496
|
multitive tail:(space additive_op space multitive)* {
|
489
497
|
def eval(env = Environment.new)
|
@@ -498,7 +506,7 @@ grammar Trxl
|
|
498
506
|
end
|
499
507
|
}
|
500
508
|
end
|
501
|
-
|
509
|
+
|
502
510
|
rule additive_op
|
503
511
|
'+' <NilRejectingOperator>
|
504
512
|
/
|
@@ -520,7 +528,7 @@ grammar Trxl
|
|
520
528
|
end
|
521
529
|
}
|
522
530
|
end
|
523
|
-
|
531
|
+
|
524
532
|
rule multitive_op
|
525
533
|
'*' <NilRejectingOperator>
|
526
534
|
/
|
@@ -556,19 +564,19 @@ grammar Trxl
|
|
556
564
|
end
|
557
565
|
|
558
566
|
rule exponential
|
559
|
-
operand_1:primary space operator:exponential_op space operand_2:exponential <BinaryOperation>
|
567
|
+
operand_1:primary space operator:exponential_op space operand_2:exponential <BinaryOperation>
|
560
568
|
/
|
561
569
|
primary
|
562
570
|
end
|
563
571
|
|
564
572
|
rule exponential_op
|
565
|
-
'^' <NilRejectingOperator> {
|
573
|
+
'^' <NilRejectingOperator> {
|
566
574
|
def ruby_operator
|
567
575
|
:**
|
568
576
|
end
|
569
577
|
}
|
570
578
|
end
|
571
|
-
|
579
|
+
|
572
580
|
rule primary
|
573
581
|
predefined_function
|
574
582
|
/
|
@@ -580,7 +588,7 @@ grammar Trxl
|
|
580
588
|
def eval(env = Environment.new)
|
581
589
|
true
|
582
590
|
end
|
583
|
-
}
|
591
|
+
}
|
584
592
|
/
|
585
593
|
'FALSE' {
|
586
594
|
def eval(env = Environment.new)
|
@@ -692,7 +700,7 @@ grammar Trxl
|
|
692
700
|
def pattern(env = Environment.new)
|
693
701
|
primary.eval(env)
|
694
702
|
end
|
695
|
-
|
703
|
+
|
696
704
|
def match_op
|
697
705
|
'=='
|
698
706
|
end
|
@@ -728,7 +736,7 @@ grammar Trxl
|
|
728
736
|
end
|
729
737
|
|
730
738
|
|
731
|
-
rule variable
|
739
|
+
rule variable
|
732
740
|
[a-zA-Z_]+ ([0-9] / [a-zA-Z_])* {
|
733
741
|
|
734
742
|
def eval(env = Environment.new)
|
@@ -747,7 +755,7 @@ grammar Trxl
|
|
747
755
|
if env.has_key?(name)
|
748
756
|
value = env[name]
|
749
757
|
(value.is_a?(Array) || value.is_a?(Hash)) ? value.inspect : value.to_s
|
750
|
-
else
|
758
|
+
else
|
751
759
|
text_value
|
752
760
|
end
|
753
761
|
end
|
@@ -803,8 +811,8 @@ grammar Trxl
|
|
803
811
|
/
|
804
812
|
to_array_function
|
805
813
|
/
|
806
|
-
round_function
|
807
|
-
/
|
814
|
+
round_function
|
815
|
+
/
|
808
816
|
min_function
|
809
817
|
/
|
810
818
|
max_function
|
@@ -827,7 +835,7 @@ grammar Trxl
|
|
827
835
|
def eval(env = Environment.new)
|
828
836
|
to_s(env)
|
829
837
|
end
|
830
|
-
|
838
|
+
|
831
839
|
def to_s(env = Environment.new)
|
832
840
|
help = "-----------------------------------------\n"
|
833
841
|
help = " TRXL Language HELP \n"
|
@@ -853,12 +861,20 @@ grammar Trxl
|
|
853
861
|
help << "-----------------------------------------\n"
|
854
862
|
help << "6) Built in functions:\n"
|
855
863
|
help << " HELP,ENV,SIZE,SPLIT,ROUND,MIN,MAX\n"
|
856
|
-
help << " SUM,MULT,AVG, PRINT, PRINT_LINE\n"
|
857
|
-
help << " TO_INT, TO_FLOAT, TO_ARRAY\n"
|
864
|
+
help << " SUM, MULT, AVG, PRINT, PRINT_LINE\n"
|
865
|
+
help << " TO_INT, TO_FLOAT, TO_ARRAY, AVG_SUM\n"
|
866
|
+
help << " MATCHING_IDS, VALUES_OF_TYPE\n"
|
858
867
|
help << "-----------------------------------------\n"
|
859
868
|
help << "7) Standard library functions:\n"
|
860
|
-
help << "
|
861
|
-
help << "
|
869
|
+
help << " foreach_in, inject, map, select\n"
|
870
|
+
help << " reject, in_groups_of, sum_of_type\n"
|
871
|
+
help << " avg_sum_of_type, avg_range_sum_of_type\n"
|
872
|
+
help << " total_range_sum_of_type, ratio\n"
|
873
|
+
help << " year_from_date, month_from_date\n"
|
874
|
+
help << " hash_values, hash_value_sum\n"
|
875
|
+
help << " avg_hash_value_sum, hash_range_values\n"
|
876
|
+
help << " hash_range_value_sum\n"
|
877
|
+
help << " avg_hash_range_value_sum\n"
|
862
878
|
help << "-----------------------------------------\n"
|
863
879
|
help << "8) Access the current environment:\n"
|
864
880
|
help << " ENV; (your output may differ)\n"
|
@@ -921,12 +937,12 @@ grammar Trxl
|
|
921
937
|
help << " => 1\n"
|
922
938
|
help << "-----------------------------------------\n"
|
923
939
|
help << "14) Range variables and literals\n"
|
924
|
-
help << " range_including_upper = 1..5\n"
|
925
|
-
help << " => [ 1, 2, 3, 4, 5 ]\n"
|
940
|
+
help << " range_including_upper = 1..5\n"
|
941
|
+
help << " => [ 1, 2, 3, 4, 5 ]\n"
|
926
942
|
help << " SIZE(range_including_upper);\n"
|
927
943
|
help << " => 5\n"
|
928
944
|
help << " range_excluding_upper = 1...5\n"
|
929
|
-
help << " => [ 1, 2, 3, 4 ]\n"
|
945
|
+
help << " => [ 1, 2, 3, 4 ]\n"
|
930
946
|
help << " SIZE(range_excluding_upper);\n"
|
931
947
|
help << " => 4\n"
|
932
948
|
help << " SIZE([1..5);\n"
|
@@ -934,8 +950,8 @@ grammar Trxl
|
|
934
950
|
help << "-----------------------------------------\n"
|
935
951
|
help << "15) Conditional branching and recursion:\n"
|
936
952
|
help << " factorial = fun(x) {\n"
|
937
|
-
help << " if(x == 0)\n"
|
938
|
-
help << " 1\n"
|
953
|
+
help << " if(x == 0)\n"
|
954
|
+
help << " 1\n"
|
939
955
|
help << " else\n"
|
940
956
|
help << " x * factorial(x - 1)\n"
|
941
957
|
help << " end\n"
|
@@ -945,8 +961,8 @@ grammar Trxl
|
|
945
961
|
help << "-----------------------------------------\n"
|
946
962
|
help << "16) Conditional branching:\n"
|
947
963
|
help << " foo = fun(x) {\n"
|
948
|
-
help << " if(x == 0)\n"
|
949
|
-
help << " 0\n"
|
964
|
+
help << " if(x == 0)\n"
|
965
|
+
help << " 0\n"
|
950
966
|
help << " elsif(x == 1)\n"
|
951
967
|
help << " 1\n"
|
952
968
|
help << " else\n"
|
@@ -962,10 +978,11 @@ grammar Trxl
|
|
962
978
|
help << "-----------------------------------------\n"
|
963
979
|
help << "17) case expressions:\n"
|
964
980
|
help << " foo = fun(x) {\n"
|
965
|
-
help << " case x\n"
|
966
|
-
help << " when
|
967
|
-
help << " when
|
968
|
-
help << " when
|
981
|
+
help << " case x\n"
|
982
|
+
help << " when NULL then NULL\n"
|
983
|
+
help << " when 0 then 0\n"
|
984
|
+
help << " when 1 then 1\n"
|
985
|
+
help << " when 2 then 2\n"
|
969
986
|
help << " else 3\n"
|
970
987
|
help << " end\n"
|
971
988
|
help << " }\n"
|
@@ -1008,7 +1025,7 @@ grammar Trxl
|
|
1008
1025
|
rule print_line_function
|
1009
1026
|
'PRINT_LINE' space '(' space expression space ')' {
|
1010
1027
|
def eval(env = Environment.new)
|
1011
|
-
result = expression.eval(env)
|
1028
|
+
result = expression.eval(env)
|
1012
1029
|
puts (result.is_a?(Array) || result.is_a?(Hash)) ? result.inspect : result.to_s
|
1013
1030
|
end
|
1014
1031
|
}
|
@@ -1023,7 +1040,7 @@ grammar Trxl
|
|
1023
1040
|
rule print_function
|
1024
1041
|
'PRINT' space '(' space expression space ')' {
|
1025
1042
|
def eval(env = Environment.new)
|
1026
|
-
result = expression.eval(env)
|
1043
|
+
result = expression.eval(env)
|
1027
1044
|
print (result.is_a?(Array) || result.is_a?(Hash)) ? result.inspect : result.to_s
|
1028
1045
|
end
|
1029
1046
|
}
|
@@ -1101,12 +1118,12 @@ grammar Trxl
|
|
1101
1118
|
rule sum_function
|
1102
1119
|
'SUM' space '(' space expression more_expressions:( space ',' space expression)* space ')' {
|
1103
1120
|
def eval(env = Environment.new)
|
1104
|
-
evaluated_expressions(env).compact.inject(0) do |sum, val|
|
1121
|
+
evaluated_expressions(env).compact.inject(0) do |sum, val|
|
1105
1122
|
sum + if val.is_a?(Array)
|
1106
1123
|
val.flatten.compact.inject(0) { |next_sum, v| next_sum + v }
|
1107
1124
|
else
|
1108
1125
|
val
|
1109
|
-
end
|
1126
|
+
end
|
1110
1127
|
end
|
1111
1128
|
end
|
1112
1129
|
|
@@ -1131,12 +1148,12 @@ grammar Trxl
|
|
1131
1148
|
def eval(env = Environment.new)
|
1132
1149
|
values = evaluated_expressions(env).compact
|
1133
1150
|
return 0 if values.size == 0
|
1134
|
-
values.inject(1) do |sum, val|
|
1151
|
+
values.inject(1) do |sum, val|
|
1135
1152
|
sum * if val.is_a?(Array)
|
1136
1153
|
val.flatten.compact.inject(1) { |next_sum, v| next_sum * v }
|
1137
1154
|
else
|
1138
1155
|
val
|
1139
|
-
end
|
1156
|
+
end
|
1140
1157
|
end
|
1141
1158
|
end
|
1142
1159
|
|
@@ -1174,14 +1191,14 @@ grammar Trxl
|
|
1174
1191
|
|
1175
1192
|
s = values.inject(0) do |sum, next_val|
|
1176
1193
|
sum + if next_val.is_a?(Array)
|
1177
|
-
next_val.flatten.inject(0) do |next_sum, val|
|
1194
|
+
next_val.flatten.inject(0) do |next_sum, val|
|
1178
1195
|
nr_of_vals += 1 if val && (strict || (!strict && val != 0))
|
1179
1196
|
next_sum + (val || 0)
|
1180
1197
|
end
|
1181
1198
|
else
|
1182
1199
|
nr_of_vals += 1 if next_val && (strict || (!strict && next_val != 0))
|
1183
1200
|
next_val || 0
|
1184
|
-
end
|
1201
|
+
end
|
1185
1202
|
end
|
1186
1203
|
(s != 0 && nr_of_vals != 0) ? s.to_f / nr_of_vals : 0
|
1187
1204
|
end
|
@@ -1215,12 +1232,16 @@ grammar Trxl
|
|
1215
1232
|
nr_of_vals = 0
|
1216
1233
|
res = next_val.inject(0) do |next_sum, val|
|
1217
1234
|
if val.is_a?(Array)
|
1218
|
-
|
1235
|
+
if (size = val.compact.size) > 0
|
1236
|
+
next_sum + val.inject(0) { |s, v| s + (v || 0) } / size
|
1237
|
+
else
|
1238
|
+
next_sum
|
1239
|
+
end
|
1219
1240
|
else
|
1220
1241
|
nr_of_vals += 1 if val && (strict || (!strict && val != 0))
|
1221
1242
|
next_sum + (val || 0)
|
1222
1243
|
end
|
1223
|
-
end
|
1244
|
+
end
|
1224
1245
|
nr_of_vals != 0 ? res / nr_of_vals : res
|
1225
1246
|
else
|
1226
1247
|
next_val || 0
|
@@ -1239,7 +1260,7 @@ grammar Trxl
|
|
1239
1260
|
end
|
1240
1261
|
}
|
1241
1262
|
end
|
1242
|
-
|
1263
|
+
|
1243
1264
|
rule min_function
|
1244
1265
|
'MIN' space '(' space expression more_expressions:( space ',' space expression)* space ')' {
|
1245
1266
|
def eval(env = Environment.new)
|
@@ -1295,17 +1316,17 @@ grammar Trxl
|
|
1295
1316
|
end
|
1296
1317
|
|
1297
1318
|
rule values_of_type_function
|
1298
|
-
'VALUES_OF_TYPE' space '('
|
1299
|
-
space match_exp:expression space ','
|
1319
|
+
'VALUES_OF_TYPE' space '('
|
1320
|
+
space match_exp:expression space ','
|
1300
1321
|
space all_types:expression space ','
|
1301
|
-
space all_values:expression space
|
1322
|
+
space all_values:expression space
|
1302
1323
|
')' {
|
1303
1324
|
def eval(env = Environment.new)
|
1304
1325
|
types = all_types.eval(env)
|
1305
1326
|
if types.is_a?(Hash)
|
1306
1327
|
values = all_values.eval(env)
|
1307
1328
|
if values.is_a?(Hash)
|
1308
|
-
types.select { |k, v| v == match_exp.eval(env) }.map do |entry|
|
1329
|
+
types.select { |k, v| v == match_exp.eval(env) }.map do |entry|
|
1309
1330
|
values[entry[0]]
|
1310
1331
|
end
|
1311
1332
|
else
|
@@ -1325,24 +1346,24 @@ grammar Trxl
|
|
1325
1346
|
end
|
1326
1347
|
|
1327
1348
|
|
1328
|
-
|
1349
|
+
|
1329
1350
|
rule non_space_char
|
1330
1351
|
!white .
|
1331
1352
|
end
|
1332
1353
|
|
1333
|
-
|
1354
|
+
|
1334
1355
|
rule require_keyword
|
1335
1356
|
'require' !non_space_char
|
1336
1357
|
end
|
1337
|
-
|
1358
|
+
|
1338
1359
|
rule case_keyword
|
1339
1360
|
'case' !non_space_char
|
1340
1361
|
end
|
1341
|
-
|
1362
|
+
|
1342
1363
|
rule when_keyword
|
1343
1364
|
'when' !non_space_char
|
1344
1365
|
end
|
1345
|
-
|
1366
|
+
|
1346
1367
|
rule then_keyword
|
1347
1368
|
'then' !non_space_char
|
1348
1369
|
end
|
@@ -1377,13 +1398,13 @@ grammar Trxl
|
|
1377
1398
|
|
1378
1399
|
|
1379
1400
|
# whitespace
|
1380
|
-
rule white
|
1401
|
+
rule white
|
1381
1402
|
[ \r\t\n]+
|
1382
1403
|
end
|
1383
1404
|
|
1384
1405
|
# mandatory space
|
1385
1406
|
rule SPACE
|
1386
|
-
(white / comment)+
|
1407
|
+
(white / comment)+
|
1387
1408
|
end
|
1388
1409
|
|
1389
1410
|
# optional space
|
@@ -1391,4 +1412,4 @@ grammar Trxl
|
|
1391
1412
|
SPACE?
|
1392
1413
|
end
|
1393
1414
|
|
1394
|
-
end
|
1415
|
+
end
|