divine 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -14
- data/README.md +25 -0
- data/Rakefile +34 -19
- data/divine.gemspec +1 -0
- data/lib/divine.rb +3 -1
- data/lib/divine/code_generators/code_generator.rb +51 -1
- data/lib/divine/code_generators/csharp.rb +898 -0
- data/lib/divine/code_generators/java.rb +125 -13
- data/lib/divine/code_generators/javascript.rb +111 -4
- data/lib/divine/code_generators/ruby.rb +103 -9
- data/lib/divine/dsl.rb +95 -6
- data/lib/divine/graph_generator/graph_generator.rb +81 -0
- data/lib/divine/version.rb +2 -1
- data/test/basic_complex_test/basic_complex_test.rb +5 -0
- data/test/basic_complex_test/graph.jpg +0 -0
- data/test/basic_complex_test/java_test/JavaTest.java +1 -1
- data/test/basic_complex_test/ruby_test/ruby_test.rb +17 -4
- data/test/binaryTree_test/binaryTree_test.rb +5 -0
- data/test/binaryTree_test/csharp_test/csharp_test.cs +99 -0
- data/test/binaryTree_test/graph.png +0 -0
- data/test/binaryTree_test/java_test/JavaTest.java +1 -1
- data/test/binaryTree_test/ruby_test/ruby_test.rb +26 -3
- data/test/complex_test/complex_test.rb +5 -0
- data/test/complex_test/csharp_test/csharp_test.cs +109 -0
- data/test/complex_test/graph.png +0 -0
- data/test/complex_test/java_test/JavaTest.java +1 -1
- data/test/complex_test/ruby_test/ruby_test.rb +24 -1
- data/test/dynamic_int_test/csharp_test/csharp_test.cs +76 -0
- data/test/dynamic_int_test/dynamic_int_test.rb +20 -0
- data/test/dynamic_int_test/graph.jpg +0 -0
- data/test/dynamic_int_test/java_test/JavaTest.java +72 -0
- data/test/dynamic_int_test/js_test/js_test.js +54 -0
- data/test/dynamic_int_test/ruby_test/ruby_test.rb +55 -0
- data/test/ipv6_test/csharp_test/csharp_test.cs +73 -0
- data/test/ipv6_test/graph.jpg +0 -0
- data/test/ipv6_test/ipv6_test.rb +5 -0
- data/test/ipv6_test/java_test/JavaTest.java +1 -1
- data/test/ipv6_test/ruby_test/ruby_test.rb +24 -4
- data/test/lib/csharp/nunit.framework.dll +0 -0
- data/test/{java_lib → lib/java}/junit.jar +0 -0
- data/test/signed_int_test/csharp_test/csharp_test.cs +86 -0
- data/test/signed_int_test/graph.jpg +0 -0
- data/test/signed_int_test/java_test/JavaTest.java +1 -1
- data/test/signed_int_test/ruby_test/ruby_test.rb +21 -1
- data/test/signed_int_test/signed_int_test.rb +6 -0
- data/test/unify_test/unify_test.rb +17 -4
- metadata +54 -8
- data/test/signed_float_test/ruby_test/ruby_test.rb +0 -36
- data/test/signed_float_test/signed_float_test.rb +0 -14
@@ -1,15 +1,32 @@
|
|
1
1
|
module Divine
|
2
2
|
|
3
|
+
##
|
4
|
+
# * +Java Helper+ :
|
5
|
+
# Support base function needed to build Divine enviroment and classes corresponding to DSL structs
|
6
|
+
#
|
3
7
|
class JavaHelperMethods < BabelHelperMethods
|
8
|
+
|
9
|
+
#
|
10
|
+
# Return the header comment
|
11
|
+
#
|
4
12
|
def get_header_comment
|
5
13
|
get_header_comment_text.map do |s|
|
6
14
|
"// #{s}"
|
7
15
|
end.join("\n")
|
8
16
|
end
|
9
17
|
|
18
|
+
##
|
19
|
+
# Generate the base Divine Java Class
|
20
|
+
# that contains the main methods:
|
21
|
+
# * serialize
|
22
|
+
# * serialize Internal
|
23
|
+
# * deserialize
|
24
|
+
# * Read Methods
|
25
|
+
# * Write Methods
|
26
|
+
|
10
27
|
def java_base_class_template_str
|
11
28
|
<<EOS
|
12
|
-
abstract class
|
29
|
+
abstract class Divine <%= toplevel_class %> {
|
13
30
|
private static final Charset UTF8 = Charset.forName("UTF-8");
|
14
31
|
|
15
32
|
public byte[] serialize() throws IOException {
|
@@ -47,6 +64,17 @@ abstract class BabelBase <%= toplevel_class %> {
|
|
47
64
|
return (readInt32(data) << 32) | (readInt32(data) & 0xFFFFFFFFL);
|
48
65
|
}
|
49
66
|
|
67
|
+
protected long readDint63(ByteArrayInputStream data) {
|
68
|
+
int b = readInt8(data);
|
69
|
+
long val = b & 0x7F;
|
70
|
+
while((b >> 7) == 1){
|
71
|
+
b = readInt8(data);
|
72
|
+
val = val << 7;
|
73
|
+
val = val | b & 0x7F;
|
74
|
+
}
|
75
|
+
return val;
|
76
|
+
}
|
77
|
+
|
50
78
|
protected boolean readBool(ByteArrayInputStream data) {
|
51
79
|
return readInt8(data) == 1;
|
52
80
|
}
|
@@ -161,14 +189,30 @@ abstract class BabelBase <%= toplevel_class %> {
|
|
161
189
|
|
162
190
|
protected void writeSint64(long v, ByteArrayOutputStream out) {
|
163
191
|
if (v > Long.MAX_VALUE) { // Max 9,223,372,036,854,775,807
|
164
|
-
raiseError("Too large sInt64 number: " + v + ", Max = " +
|
165
|
-
}else if(v < Long.MIN_VALUE){ // Min -9,223,372,036,854,775,
|
166
|
-
raiseError("Too small sInt64 number: " + v + ", Min = " +
|
192
|
+
raiseError("Too large sInt64 number: " + v + ", Max = " + Long.MAX_VALUE);
|
193
|
+
}else if(v < Long.MIN_VALUE){ // Min -9,223,372,036,854,775,808
|
194
|
+
raiseError("Too small sInt64 number: " + v + ", Min = " + Long.MIN_VALUE);
|
167
195
|
}
|
168
196
|
writeInt32(((v >> 32) & 0xFFFFFFFFL), out);
|
169
197
|
writeInt32( (v & 0xFFFFFFFFL) , out);
|
170
198
|
}
|
171
199
|
|
200
|
+
protected void writeDint63(long v, ByteArrayOutputStream out) {
|
201
|
+
if (v > Long.MAX_VALUE) { // Max 9,223,372,036,854,775,807
|
202
|
+
raiseError("Too large Dynamic Int64 number: " + v + ", Max = " + Long.MAX_VALUE);
|
203
|
+
}else if(v < 0){ // Min 0
|
204
|
+
raiseError("Too small Dynamic Int64 number: " + v + ", Min = " + 0);
|
205
|
+
}
|
206
|
+
String[] bytes = new StringBuffer(Long.toBinaryString(v)).reverse().toString().split("(?<=\\\\G.......)");
|
207
|
+
|
208
|
+
for (int i = bytes.length - 1; i >= 0; i--){
|
209
|
+
String s = bytes[i];
|
210
|
+
s += new String(new char[7 - s.length()]).replace("\\\\0", "0") + Math.min(i, 1);
|
211
|
+
int t = Integer.parseInt(new StringBuffer(s).reverse().toString(), 2);
|
212
|
+
this.writeInt8(t, out);
|
213
|
+
}
|
214
|
+
}
|
215
|
+
|
172
216
|
protected void writeBool(boolean v, ByteArrayOutputStream out) {
|
173
217
|
writeInt8(v ? 1 : 0, out);
|
174
218
|
}
|
@@ -276,9 +320,13 @@ abstract class BabelBase <%= toplevel_class %> {
|
|
276
320
|
EOS
|
277
321
|
end
|
278
322
|
|
323
|
+
##
|
324
|
+
# Generate Java Class that corresponding to the struct definition
|
325
|
+
# * *Args* :
|
326
|
+
# - +sh+ -> Struct Name
|
279
327
|
def java_class_template(sh)
|
280
328
|
code = [
|
281
|
-
"class #{sh.name} extends
|
329
|
+
"class #{sh.name} extends Divine {",
|
282
330
|
:indent,
|
283
331
|
"",
|
284
332
|
|
@@ -354,6 +402,30 @@ EOS
|
|
354
402
|
format_src(3, 3, code)
|
355
403
|
end
|
356
404
|
|
405
|
+
##
|
406
|
+
# Generate default java data types declaration values corresponding to each DSL types:
|
407
|
+
# * DSL Type --> Corresponding Default Java Value
|
408
|
+
# * dint63 --> 0 range -> [0 - 9,223,372,036,854,775,807]
|
409
|
+
# * 1 byte: range -> [0 - 127]
|
410
|
+
# * 2 bytes: range -> [0 - 16,383]
|
411
|
+
# * 3 bytes: range -> [0 - 2,097,151]
|
412
|
+
# * 4 bytes: range -> [0 - 268,435,455]
|
413
|
+
# * 5 bytes: range -> [0 - 34,359,738,367]
|
414
|
+
# * 6 bytes: range -> [0 - 4,398,046,511,103]
|
415
|
+
# * 7 bytes: range -> [0 - 562,949,953,421,311]
|
416
|
+
# * 8 bytes: range -> [0 - 72,057,594,037,927,935]
|
417
|
+
# * 9 bytes: range -> [0 - 9,223,372,036,854,775,807]
|
418
|
+
# * int8 --> 0 Range -> [0 - 255]
|
419
|
+
# * int16 --> 0 Range -> [0 - 65535]
|
420
|
+
# * int32 --> 0L Range -> [0 - 4.294.967.295]
|
421
|
+
# * sint32 --> 0 Range -> [-2.147.483.648 - 2.147.483.647]
|
422
|
+
# * sint64 --> 0L Range -> [-9.223.372.036.854.775.808, 9.223.372.036.854.775.807]
|
423
|
+
# * string --> ""
|
424
|
+
# * ip_number--> ""
|
425
|
+
# * binary --> new Byte[0]
|
426
|
+
# * short_binary --> new Byte[0]
|
427
|
+
# * list --> new ArrayList<type>()
|
428
|
+
# * map --> new HashMap<keyType, valueType>()
|
357
429
|
|
358
430
|
def java_get_empty_declaration(types, is_reference_type = false)
|
359
431
|
if types.respond_to? :referenced_types
|
@@ -378,7 +450,7 @@ EOS
|
|
378
450
|
is_reference_type ? "new Byte[0]" : "new byte[0]"
|
379
451
|
when :int8, :int16, :sint32
|
380
452
|
"0"
|
381
|
-
when :int32, :sint64
|
453
|
+
when :int32, :sint64, :dint63
|
382
454
|
"0L"
|
383
455
|
when :string, :ip_number
|
384
456
|
"\"\""
|
@@ -391,7 +463,23 @@ EOS
|
|
391
463
|
end
|
392
464
|
end
|
393
465
|
end
|
394
|
-
|
466
|
+
|
467
|
+
##
|
468
|
+
# Generate java data types declaration corresponding to each DSL type
|
469
|
+
# * DSL Type --> Corresponding Java Type
|
470
|
+
# * int8 --> int
|
471
|
+
# * int16 --> int
|
472
|
+
# * sint32 --> int
|
473
|
+
# * int32 --> long
|
474
|
+
# * sint64 --> long
|
475
|
+
# * dint63 --> long
|
476
|
+
# * string --> String
|
477
|
+
# * ip_number--> String
|
478
|
+
# * binary --> Byte[]
|
479
|
+
# * short_binary --> Byte[]
|
480
|
+
# * list --> ArrayList<type>
|
481
|
+
# * map --> HashMap<keyType, valueType>
|
482
|
+
|
395
483
|
def java_get_type_declaration(types, is_reference_type = false)
|
396
484
|
if types.respond_to? :referenced_types
|
397
485
|
java_get_type_declaration(types.referenced_types, is_reference_type)
|
@@ -418,7 +506,7 @@ EOS
|
|
418
506
|
is_reference_type ? "Byte[]" : "byte[]"
|
419
507
|
when :int8, :int16, :sint32
|
420
508
|
is_reference_type ? "Integer" : "int"
|
421
|
-
when :int32, :sint64
|
509
|
+
when :int32, :sint64, :dint63
|
422
510
|
is_reference_type ? "Long" : "long"
|
423
511
|
when :string, :ip_number
|
424
512
|
"String"
|
@@ -431,7 +519,12 @@ EOS
|
|
431
519
|
end
|
432
520
|
end
|
433
521
|
end
|
434
|
-
|
522
|
+
|
523
|
+
##
|
524
|
+
# Generate the way of serializing different DSL types
|
525
|
+
# * *Args* :
|
526
|
+
# - +var+ -> variable name
|
527
|
+
# - +types+ -> variable type
|
435
528
|
def java_serialize_internal(var, types)
|
436
529
|
if types.respond_to? :first
|
437
530
|
case types.first
|
@@ -476,6 +569,11 @@ EOS
|
|
476
569
|
end
|
477
570
|
end
|
478
571
|
|
572
|
+
##
|
573
|
+
# Generate the way of deserializing different DSL types
|
574
|
+
# * *Args* :
|
575
|
+
# - +var+ -> variable name
|
576
|
+
# - +types+ -> variable type
|
479
577
|
def java_deserialize_internal(var, types)
|
480
578
|
if types.respond_to? :first
|
481
579
|
case types.first
|
@@ -531,8 +629,16 @@ EOS
|
|
531
629
|
end
|
532
630
|
end
|
533
631
|
|
534
|
-
|
632
|
+
##
|
633
|
+
# Responsible for generating Divine and structs classes
|
634
|
+
#
|
535
635
|
class JavaGenerator < JavaHelperMethods
|
636
|
+
|
637
|
+
##
|
638
|
+
# Generate Java class(es)
|
639
|
+
# * *Args* :
|
640
|
+
# - +structs+ -> Dictionary of structs
|
641
|
+
# - +opts+ -> Dictionary that contains generation params [file, debug, package, parent_class, target_dir]
|
536
642
|
def generate_code(structs, opts)
|
537
643
|
$debug_java = true if opts[:debug]
|
538
644
|
base_template = Erubis::Eruby.new(java_base_class_template_str)
|
@@ -548,7 +654,7 @@ EOS
|
|
548
654
|
toplevel = opts[:parent_class] || nil
|
549
655
|
toplevel = " extends #{toplevel}" if toplevel
|
550
656
|
if opts[:package]
|
551
|
-
res = [{file: "
|
657
|
+
res = [{file: "Divine.java", src: "#{java_get_begin_module(opts)}public #{base_template.result({ toplevel_class: toplevel })}"}]
|
552
658
|
for cls in src
|
553
659
|
res << {file: cls.match(/class (.*) extends/)[1]+".java", src: "#{java_get_begin_module(opts)}public #{cls}"}
|
554
660
|
end
|
@@ -557,7 +663,11 @@ EOS
|
|
557
663
|
return [{file: opts[:file], src: "#{java_get_begin_module(opts)}#{base_template.result({ toplevel_class: toplevel })}\n\n#{src.join("\n\n")}"}]
|
558
664
|
end
|
559
665
|
end
|
560
|
-
|
666
|
+
##
|
667
|
+
# Build package name and list of imports
|
668
|
+
# * *Args* :
|
669
|
+
# - +opts+ -> Dictionary that contains package name in key 'package'
|
670
|
+
#
|
561
671
|
def java_get_begin_module(opts)
|
562
672
|
str = "#{get_header_comment}\n\n"
|
563
673
|
str << "package #{opts[:package]};" if opts[:package]
|
@@ -565,7 +675,9 @@ EOS
|
|
565
675
|
str << "\n\n"
|
566
676
|
return str
|
567
677
|
end
|
568
|
-
|
678
|
+
##
|
679
|
+
# Generate list of imports needed in generated java classes
|
680
|
+
#
|
569
681
|
def get_java_imports
|
570
682
|
[
|
571
683
|
"java.io.ByteArrayInputStream",
|
@@ -6,14 +6,27 @@
|
|
6
6
|
|
7
7
|
module Divine
|
8
8
|
$debug_javascript = false
|
9
|
-
|
9
|
+
##
|
10
|
+
# * +JS Helper+ :
|
11
|
+
# Support base function needed to build base divine functions and DSL structs
|
12
|
+
#
|
10
13
|
class JavascriptHelperMethods < BabelHelperMethods
|
14
|
+
|
15
|
+
#
|
16
|
+
# Return the header comment
|
17
|
+
#
|
11
18
|
def get_header_comment
|
12
19
|
get_header_comment_text.map do |s|
|
13
20
|
"// #{s}"
|
14
21
|
end.join("\n")
|
15
22
|
end
|
16
|
-
|
23
|
+
##
|
24
|
+
# Generate the base functions of:
|
25
|
+
# * serialize
|
26
|
+
# * deserialize
|
27
|
+
# * Read Methods
|
28
|
+
# * Write Methods
|
29
|
+
|
17
30
|
def javascript_base_class_template_str
|
18
31
|
<<EOS
|
19
32
|
// ------------------------------------------------------------ DivineDataReader
|
@@ -114,6 +127,29 @@ DivineHelper.prototype.read_sint64 = function (data) {
|
|
114
127
|
}
|
115
128
|
}
|
116
129
|
|
130
|
+
DivineHelper.prototype.read_dint63 = function (data) {
|
131
|
+
var byte = this.read_int8(data)
|
132
|
+
var part1 = part2 = ""; // To hold first 32-bit and second 32-bit respectively
|
133
|
+
var bin = byte & 0x7F; // tmp To hold binary string
|
134
|
+
var numBytes = 1;
|
135
|
+
while ((byte >> 7) == 1) {
|
136
|
+
byte = this.read_int8(data)
|
137
|
+
bin = bin << 7
|
138
|
+
bin = bin | byte & 0x7F
|
139
|
+
numBytes ++;
|
140
|
+
if (numBytes == 4 && (byte >> 7) == 1){
|
141
|
+
part1 = bin.toString(2);
|
142
|
+
bin = 1; // To avoid unshifting of zero
|
143
|
+
}
|
144
|
+
}
|
145
|
+
bin = bin.toString(2);
|
146
|
+
if (bin.length > 1 && part1 != "")
|
147
|
+
bin = bin.substr(1, bin.length);
|
148
|
+
part2 = bin;
|
149
|
+
var val = parseInt(part1 + part2, 2);
|
150
|
+
return val;
|
151
|
+
}
|
152
|
+
|
117
153
|
DivineHelper.prototype.read_binary = function (data) {
|
118
154
|
return data.read(this.read_int32(data));
|
119
155
|
};
|
@@ -230,6 +266,23 @@ DivineHelper.prototype.write_sint64 = function (v, out) {
|
|
230
266
|
this.write_int32(parseInt(part2, 2), out);
|
231
267
|
}
|
232
268
|
|
269
|
+
DivineHelper.prototype.write_dint63 = function (v, out) {
|
270
|
+
var max = Math.pow(2, 53) - 1;
|
271
|
+
var min = 0;
|
272
|
+
if (v > max) // Max 9,007,199,254,740,991
|
273
|
+
this.raise_error("Too large Dynamic Int53 number: " + v + ", Max = " + max);
|
274
|
+
if (v < min) // Min 0
|
275
|
+
this.raise_error("Too small Dynamic Int53 number: " + v + ", Min = " + min);
|
276
|
+
|
277
|
+
bytes = v.toString(2).split("").reverse().join("").split(/(.{7})/).filter(function(t){if (t != "" ) return true});
|
278
|
+
for (var i = bytes.length - 1; i >= 0; i--){
|
279
|
+
var bin = bytes[i];
|
280
|
+
bin += Array(8 - bin.length).join("0") + Math.min(i,1);
|
281
|
+
var val = parseInt(bin.split("").reverse().join(""), 2);
|
282
|
+
this.write_int8(val, out);
|
283
|
+
}
|
284
|
+
}
|
285
|
+
|
233
286
|
DivineHelper.prototype.write_bool = function (v, out) {
|
234
287
|
this.write_int8(v ? 1 : 0, out)
|
235
288
|
}
|
@@ -454,6 +507,11 @@ DivineHelper.prototype.raise_error = function (msg) {
|
|
454
507
|
EOS
|
455
508
|
end
|
456
509
|
|
510
|
+
##
|
511
|
+
# Generate required functions that corresponding to the struct definition
|
512
|
+
# * *Args* :
|
513
|
+
# - +sh+ -> Struct Name
|
514
|
+
|
457
515
|
def javascript_class_template(sh)
|
458
516
|
code = [
|
459
517
|
"",
|
@@ -537,6 +595,29 @@ EOS
|
|
537
595
|
format_src(0, 3, code)
|
538
596
|
end
|
539
597
|
|
598
|
+
##
|
599
|
+
# Generate default JS data types declaration values corresponding to each DSL types:
|
600
|
+
# * DSL Type --> Corresponding Default JS Value
|
601
|
+
# * dint63 --> 0 range -> [0 - 9.007.199.254.740.991]
|
602
|
+
# * 1 byte: range -> [0 - 127]
|
603
|
+
# * 2 bytes: range -> [0 - 16,383]
|
604
|
+
# * 3 bytes: range -> [0 - 2,097,151]
|
605
|
+
# * 4 bytes: range -> [0 - 268,435,455]
|
606
|
+
# * 5 bytes: range -> [0 - 34,359,738,367]
|
607
|
+
# * 6 bytes: range -> [0 - 4,398,046,511,103]
|
608
|
+
# * 7 bytes: range -> [0 - 562,949,953,421,311]
|
609
|
+
# * 8 bytes: range -> [0 - 9.007.199.254.740.991] (limited by 53-bit)
|
610
|
+
# * int8 --> 0 Range -> [0 - 255]
|
611
|
+
# * int16 --> 0 Range -> [0 - 65535]
|
612
|
+
# * int32 --> 0 Range -> [0 - 4.294.967.295]
|
613
|
+
# * sint32 --> 0 Range -> [-2.147.483.648 - 2.147.483.647]
|
614
|
+
# * sint64 --> 0 Range -> [-9.007.199.254.740.992, 9.007.199.254.740.991] (limited by 53-bit)
|
615
|
+
# * string --> ""
|
616
|
+
# * ip_number--> ""
|
617
|
+
# * binary --> []
|
618
|
+
# * short_binary --> []
|
619
|
+
# * list --> []
|
620
|
+
# * map --> {}
|
540
621
|
|
541
622
|
def javascript_get_empty_declaration(field)
|
542
623
|
case field.type
|
@@ -544,7 +625,7 @@ EOS
|
|
544
625
|
"[]"
|
545
626
|
when :map
|
546
627
|
"{}"
|
547
|
-
when :int8, :int16, :int32, :sint32, :sint64
|
628
|
+
when :int8, :int16, :int32, :sint32, :sint64, :dint63
|
548
629
|
"0"
|
549
630
|
when :string, :ip_number
|
550
631
|
"\"\""
|
@@ -553,6 +634,12 @@ EOS
|
|
553
634
|
end
|
554
635
|
end
|
555
636
|
|
637
|
+
##
|
638
|
+
# Generate the way of serializing different DSL types
|
639
|
+
# * *Args* :
|
640
|
+
# - +var+ -> variable name
|
641
|
+
# - +types+ -> variable type
|
642
|
+
|
556
643
|
def javascript_serialize_internal(var, types)
|
557
644
|
if types.respond_to? :first
|
558
645
|
case types.first
|
@@ -600,6 +687,12 @@ EOS
|
|
600
687
|
end
|
601
688
|
end
|
602
689
|
|
690
|
+
##
|
691
|
+
# Generate the way of deserializing different DSL types
|
692
|
+
# * *Args* :
|
693
|
+
# - +var+ -> variable name
|
694
|
+
# - +types+ -> variable type
|
695
|
+
|
603
696
|
def javascript_deserialize_internal(var, types)
|
604
697
|
if types.respond_to? :first
|
605
698
|
case types.first
|
@@ -656,8 +749,18 @@ EOS
|
|
656
749
|
end
|
657
750
|
|
658
751
|
|
752
|
+
##
|
753
|
+
# Responsible for generating Divine and structs functions
|
754
|
+
#
|
659
755
|
|
660
756
|
class JavascriptGenerator < JavascriptHelperMethods
|
757
|
+
|
758
|
+
##
|
759
|
+
# Generate JS Functions
|
760
|
+
# * *Args* :
|
761
|
+
# - +structs+ -> Dictionary of structs
|
762
|
+
# - +opts+ -> Dictionary that contains generation params [file, debug, parent_class, target_dir]
|
763
|
+
|
661
764
|
def generate_code(structs, opts)
|
662
765
|
$debug_javascript = true if opts[:debug]
|
663
766
|
base_template = Erubis::Eruby.new(javascript_base_class_template_str)
|
@@ -674,11 +777,15 @@ EOS
|
|
674
777
|
toplevel = " < #{toplevel}" if toplevel
|
675
778
|
return [{file: opts[:file], src: "#{javascript_get_begin_module(opts)}#{base_template.result({ toplevel_class: toplevel })}\n\n#{src.join("\n\n")}#{javascript_get_end_module(opts)}"}]
|
676
779
|
end
|
677
|
-
|
780
|
+
|
781
|
+
#
|
782
|
+
# Build Header Comments
|
783
|
+
#
|
678
784
|
def javascript_get_begin_module(opts)
|
679
785
|
"#{get_header_comment}\n\n"
|
680
786
|
end
|
681
787
|
|
788
|
+
# Do nothing
|
682
789
|
def javascript_get_end_module(opts)
|
683
790
|
nil
|
684
791
|
end
|
@@ -1,15 +1,32 @@
|
|
1
1
|
module Divine
|
2
2
|
|
3
|
+
##
|
4
|
+
# * +Ruby Helper+ :
|
5
|
+
# Support base function needed to build Divine enviroment and classes corresponding to DSL structs
|
6
|
+
#
|
3
7
|
class RubyHelperMethods < BabelHelperMethods
|
8
|
+
|
9
|
+
#
|
10
|
+
# Return the header comment
|
11
|
+
#
|
4
12
|
def get_header_comment
|
5
13
|
get_header_comment_text.map do |s|
|
6
14
|
"# #{s}"
|
7
15
|
end.join("\n")
|
8
16
|
end
|
9
17
|
|
18
|
+
##
|
19
|
+
# Generate the base Divine Ruby Class
|
20
|
+
# that contains the main methods:
|
21
|
+
# * serialize
|
22
|
+
# * serialize Internal
|
23
|
+
# * deserialize
|
24
|
+
# * Read Methods
|
25
|
+
# * Write Methods
|
26
|
+
|
10
27
|
def ruby_base_class_template_str
|
11
28
|
%q{
|
12
|
-
class
|
29
|
+
class Divine<%= toplevel_class %>
|
13
30
|
public
|
14
31
|
def serialize
|
15
32
|
out = []
|
@@ -53,6 +70,17 @@ module Divine
|
|
53
70
|
return num
|
54
71
|
end
|
55
72
|
|
73
|
+
def read_dint63(data)
|
74
|
+
byte = read_int8(data)
|
75
|
+
val = byte & 0x7F
|
76
|
+
while (byte >> 7) == 1
|
77
|
+
byte = read_int8(data)
|
78
|
+
val = val << 7
|
79
|
+
val = val | byte & 0x7F
|
80
|
+
end
|
81
|
+
val
|
82
|
+
end
|
83
|
+
|
56
84
|
def read_bool(data)
|
57
85
|
read_int8(data) == 1
|
58
86
|
end
|
@@ -145,12 +173,26 @@ module Divine
|
|
145
173
|
v = v.to_i
|
146
174
|
max = (2** (64 - 1)) - 1
|
147
175
|
min = (2** (64 - 1) ) - (2** 64)
|
148
|
-
raise_error "Too large
|
149
|
-
raise_error "Too small
|
176
|
+
raise_error "Too large Sint64 number: #{v} , Max = #{max}" if v > max # Max 9.223.372.036.854.775.807
|
177
|
+
raise_error "Too small sInt64 number: #{v} , Min = #{min}" if v < min # Min -9.223.372.036.854.775.808
|
150
178
|
write_int32( v >> 32 & 0xFFFFFFFF, out)
|
151
179
|
write_int32( v & 0xFFFFFFFF, out)
|
152
180
|
end
|
153
181
|
|
182
|
+
def write_dint63(v, out)
|
183
|
+
v = v.to_i
|
184
|
+
max = (2** (64 - 1)) - 1
|
185
|
+
min = 0
|
186
|
+
raise_error "Too large Dynamic int63 number: #{v} , Max = #{max}" if v > max # Max 9.223.372.036.854.775.807
|
187
|
+
raise_error "Too small Dynamic int63 number: #{v} , Min = #{min}" if v < min # Min 0
|
188
|
+
|
189
|
+
bytes = v.to_s(2).reverse.split(/([01]{7})/).reject{ |t| t == ""}.each_with_index.map{ |t, i| t = t + "0"*(7-t.length) + [i,1].min.to_s}
|
190
|
+
bytes.reverse.map{ |t|
|
191
|
+
val = t.reverse.to_i 2
|
192
|
+
write_int8(val, out)
|
193
|
+
}
|
194
|
+
end
|
195
|
+
|
154
196
|
def write_bool(v, out)
|
155
197
|
write_int8(v ? 1 : 0, out)
|
156
198
|
end
|
@@ -279,10 +321,14 @@ module Divine
|
|
279
321
|
end
|
280
322
|
}
|
281
323
|
end
|
324
|
+
##
|
325
|
+
# Generate Ruby Class that corresponding to the struct definition
|
326
|
+
# * *Args* :
|
327
|
+
# - +sh+ -> Struct Name
|
282
328
|
|
283
329
|
def ruby_class_template(sh)
|
284
330
|
code = [
|
285
|
-
"class #{sh.name} <
|
331
|
+
"class #{sh.name} < Divine",
|
286
332
|
:indent,
|
287
333
|
"",
|
288
334
|
|
@@ -364,7 +410,30 @@ module Divine
|
|
364
410
|
]
|
365
411
|
format_src(0, 3, code)
|
366
412
|
end
|
367
|
-
|
413
|
+
##
|
414
|
+
# Generate default Ruby data types declaration values corresponding to each DSL types:
|
415
|
+
# * DSL Type --> Corresponding Default Ruby Value
|
416
|
+
# * dint63 --> 0 range -> [0 - 9,223,372,036,854,775,807]
|
417
|
+
# * 1 byte: range -> [0 - 127]
|
418
|
+
# * 2 bytes: range -> [0 - 16,383]
|
419
|
+
# * 3 bytes: range -> [0 - 2,097,151]
|
420
|
+
# * 4 bytes: range -> [0 - 268,435,455]
|
421
|
+
# * 5 bytes: range -> [0 - 34,359,738,367]
|
422
|
+
# * 6 bytes: range -> [0 - 4,398,046,511,103]
|
423
|
+
# * 7 bytes: range -> [0 - 562,949,953,421,311]
|
424
|
+
# * 8 bytes: range -> [0 - 72,057,594,037,927,935]
|
425
|
+
# * 9 bytes: range -> [0 - 9,223,372,036,854,775,807]
|
426
|
+
# * int8 --> 0 Range -> [0 - 255]
|
427
|
+
# * int16 --> 0 Range -> [0 - 65535]
|
428
|
+
# * int32 --> 0 Range -> [0 - 4.294.967.295]
|
429
|
+
# * sint32 --> 0 Range -> [-2.147.483.648 - 2.147.483.647]
|
430
|
+
# * sint64 --> 0 Range -> [-9.223.372.036.854.775.808, 9.223.372.036.854.775.807]
|
431
|
+
# * string --> ""
|
432
|
+
# * ip_number--> ""
|
433
|
+
# * binary --> []
|
434
|
+
# * short_binary --> []
|
435
|
+
# * list --> []
|
436
|
+
# * map --> {}
|
368
437
|
|
369
438
|
def ruby_get_empty_declaration(field)
|
370
439
|
case field.type
|
@@ -372,7 +441,7 @@ module Divine
|
|
372
441
|
"[]"
|
373
442
|
when :map
|
374
443
|
"{}"
|
375
|
-
when :int8, :int16, :int32, :sint32, :sint64
|
444
|
+
when :dint63, :int8, :int16, :int32, :sint32, :sint64
|
376
445
|
"0"
|
377
446
|
when :string, :ip_number
|
378
447
|
"\"\""
|
@@ -381,6 +450,12 @@ module Divine
|
|
381
450
|
end
|
382
451
|
end
|
383
452
|
|
453
|
+
##
|
454
|
+
# Generate the way of serializing different DSL types
|
455
|
+
# * *Args* :
|
456
|
+
# - +var+ -> variable name
|
457
|
+
# - +types+ -> variable type
|
458
|
+
|
384
459
|
def ruby_serialize_internal(var, types)
|
385
460
|
if types.respond_to? :first
|
386
461
|
case types.first
|
@@ -422,6 +497,12 @@ module Divine
|
|
422
497
|
end
|
423
498
|
end
|
424
499
|
|
500
|
+
##
|
501
|
+
# Generate the way of deserializing different DSL types
|
502
|
+
# * *Args* :
|
503
|
+
# - +var+ -> variable name
|
504
|
+
# - +types+ -> variable type
|
505
|
+
|
425
506
|
def ruby_deserialize_internal(var, types)
|
426
507
|
if types.respond_to? :first
|
427
508
|
case types.first
|
@@ -476,10 +557,17 @@ module Divine
|
|
476
557
|
end
|
477
558
|
|
478
559
|
|
479
|
-
|
560
|
+
##
|
561
|
+
# Responsible for generating Divine and structs classes
|
562
|
+
#
|
480
563
|
class RubyGenerator < RubyHelperMethods
|
481
564
|
@debug = true
|
482
|
-
|
565
|
+
##
|
566
|
+
# Generate Ruby class(es)
|
567
|
+
# * *Args* :
|
568
|
+
# - +structs+ -> Dictionary of structs
|
569
|
+
# - +opts+ -> Dictionary that contains generation params [file, module, parent_class, target_dir]
|
570
|
+
|
483
571
|
def generate_code(structs, opts)
|
484
572
|
base_template = Erubis::Eruby.new(ruby_base_class_template_str)
|
485
573
|
keys = structs.keys.sort
|
@@ -496,6 +584,11 @@ module Divine
|
|
496
584
|
return [{file: opts[:file], src: "#{get_header_comment}\n#{ruby_get_begin_module(opts)}#{base_template.result({ toplevel_class: toplevel, this: self })}\n\n#{src.join("\n\n")}#{ruby_get_end_module(opts)}"}]
|
497
585
|
end
|
498
586
|
|
587
|
+
##
|
588
|
+
# Build module name
|
589
|
+
# * *Args* :
|
590
|
+
# - +opts+ -> Dictionary contains module name in key module
|
591
|
+
|
499
592
|
def ruby_get_begin_module(opts)
|
500
593
|
if opts[:module]
|
501
594
|
"module #{opts[:module]}\n\n"
|
@@ -503,7 +596,8 @@ module Divine
|
|
503
596
|
nil
|
504
597
|
end
|
505
598
|
end
|
506
|
-
|
599
|
+
##
|
600
|
+
# Ending the module
|
507
601
|
def ruby_get_end_module(opts)
|
508
602
|
if opts[:module]
|
509
603
|
"\n\nend\n"
|