headius (owner)

Revisions

gist: 229194 Download_button fork
public
Public Clone URL: git://gist.github.com/229194.git
Embed All Files: show embed
1. arrays.patch #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
diff --git a/lib/duby/ast/literal.rb b/lib/duby/ast/literal.rb
index 4c8e9ac..b5764fe 100644
--- a/lib/duby/ast/literal.rb
+++ b/lib/duby/ast/literal.rb
@@ -3,6 +3,10 @@ module Duby::AST
     def initialize(parent, line_number, &block)
       super(parent, line_number, &block)
     end
+
+ def infer(typer)
+ @inferred_type = typer.array_type
+ end
   end
   
   class Fixnum < Node
diff --git a/lib/duby/compiler.rb b/lib/duby/compiler.rb
index 54a2b2f..e3d35b2 100644
--- a/lib/duby/compiler.rb
+++ b/lib/duby/compiler.rb
@@ -37,6 +37,12 @@ module Duby
         end
       end
     end
+
+ class Array
+ def compile(compiler, expression)
+ compiler.array(self, expression)
+ end
+ end
     
     class Body
       def compile(compiler, expression)
diff --git a/lib/duby/jvm/compiler.rb b/lib/duby/jvm/compiler.rb
index d7a528c..9758bab 100644
--- a/lib/duby/jvm/compiler.rb
+++ b/lib/duby/jvm/compiler.rb
@@ -556,6 +556,32 @@ module Duby
       def boolean(value)
         value ? @method.iconst_1 : @method.iconst_0
       end
+
+ def array(node, expression)
+ if expression
+ @method.new java::util::ArrayList
+ @method.dup
+ @method.ldc_int node.children ? node.children.size : 0
+ @method.swap
+ @method.invokespecial java::util::ArrayList, "<init>", [@method.void, @method.int]
+ @method.invokestatic java::util::Collections, "unmodifiableList", [java::util::List, java::util::List]
+
+ # elements, as expressions
+ # TODO: ensure they're all reference types!
+ node.children.each do |node|
+ @method.dup
+ node.compile(self, true)
+ @method.invokeinterface java::util::List, "add", [@method.boolean, @method.object]
+ @method.pop
+ end
+ else
+ # elements, as non-expressions
+ # TODO: ensure they're all reference types!
+ node.children.each do |node|
+ node.compile(self, false)
+ end
+ end
+ end
       
       def null
         @method.aconst_null
diff --git a/lib/duby/jvm/typer.rb b/lib/duby/jvm/typer.rb
index c65e69b..85b8b1c 100644
--- a/lib/duby/jvm/typer.rb
+++ b/lib/duby/jvm/typer.rb
@@ -42,6 +42,16 @@ module Duby
       def no_type
         Void
       end
+
+ def array_type
+ # TODO: allow other types for pre-1.2 profiles
+ type_reference("java.util.List")
+ end
+
+ def hash_type
+ # TODO: allow other types for pre-1.2 profiles
+ type_reference("java.util.Map")
+ end
       
       def learn_method_type(target_type, name, parameter_types, type, exceptions)
         static = target_type.meta?
diff --git a/lib/duby/typer.rb b/lib/duby/typer.rb
index 2d66b4a..8f1cf90 100644
--- a/lib/duby/typer.rb
+++ b/lib/duby/typer.rb
@@ -79,6 +79,16 @@ module Duby
         AST::TypeReference::NoType
       end
 
+ # to be overridden
+ def array_type
+ AST::TypeReference::NullType
+ end
+
+ # to be overridden
+ def hash_type
+ AST::TypeReference::NullType
+ end
+
       def define_type(name, superclass, interfaces)
         log "New type defined: '#{name}' < '#{superclass}'"
         known_types[name] = type_definition(name, superclass, interfaces)
 
2. sample session with literal arrays #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
~/projects/duby ➔ bin/dubyc -V -e "def foo; 'hello'; end; [foo]" # non-expression literal array
* [AST] [String] String("hello") resolved!
* [Duby::Typer] Learned method foo () on Type(dash_e meta) = Type(java.lang.String)
* [Duby::Typer] Entering type inference cycle
* [Duby::Typer] [Cycle 0]: Started...
* [Duby::Typer] [Cycle 0]: Resolved all types, exiting
* [Duby::Typer] [Cycle 0]: Complete!
* [Duby::Compiler::JVM] Starting main method
* [Duby::Compiler::JVM] Starting new method foo()
* [Duby::Compiler::JVM] Method foo() complete!
* [Duby::Compiler::JVM] Main method complete!
* [Duby::Compiler::JVM] Generating classes...
* [Duby::Compiler::JVM] dash_e
* [Duby::Compiler::JVM] ...done!
 
~/projects/duby ➔ javap -c dash_e
Compiled from dash_e
public class dash_e extends java.lang.Object{
public static void main(java.lang.String[]);
  Code:
   0: invokestatic #12; //Method foo:()Ljava/lang/String;
   3: pop
   4: return
 
public static java.lang.String foo();
  Code:
   0: ldc #10; //String hello
   2: areturn
 
public dash_e();
  Code:
   0: aload_0
   1: invokespecial #18; //Method java/lang/Object."<init>":()V
   4: return
 
}
 
~/projects/duby ➔ bin/dubyc -V -e "def foo; 'hello'; end; puts [foo]" # expression literal array
* [AST] [String] String("hello") resolved!
* [Duby::Typer] Learned method foo () on Type(dash_e meta) = Type(java.lang.String)
* [Duby::Typer] Entering type inference cycle
* [Duby::Typer] [Cycle 0]: Started...
* [Duby::Typer] [Cycle 0]: Resolved all types, exiting
* [Duby::Typer] [Cycle 0]: Complete!
* [Duby::Compiler::JVM] Starting main method
* [Duby::Compiler::JVM] Starting new method foo()
* [Duby::Compiler::JVM] Method foo() complete!
* [Duby::Compiler::JVM] Failed to locate method java.io.PrintStream.println(java.util.List)
* [Duby::Compiler::JVM] Found method java.io.PrintStream.println(java.lang.Object) from java.io.PrintStream
* [Duby::Compiler::JVM] Main method complete!
* [Duby::Compiler::JVM] Generating classes...
* [Duby::Compiler::JVM] dash_e
* [Duby::Compiler::JVM] ...done!
 
~/projects/duby ➔ javap -c dash_e
Compiled from dash_e
public class dash_e extends java.lang.Object{
public static void main(java.lang.String[]);
  Code:
   0: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream;
   3: new #18; //class java/util/ArrayList
   6: dup
   7: ldc #19; //int 1
   9: swap
   10: invokespecial #23; //Method java/util/ArrayList."<init>":(I)V
   13: invokestatic #29; //Method java/util/Collections.unmodifiableList:(Ljava/util/List;)Ljava/util/List;
   16: dup
   17: invokestatic #31; //Method foo:()Ljava/lang/String;
   20: invokeinterface #37, 2; //InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
   25: pop
   26: invokevirtual #43; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V
   29: return
 
public static java.lang.String foo();
  Code:
   0: ldc #10; //String hello
   2: areturn
 
public dash_e();
  Code:
   0: aload_0
   1: invokespecial #48; //Method java/lang/Object."<init>":()V
   4: return
 
}