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