mirah 0.0.4-java
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +15 -0
- data/README.txt +51 -0
- data/Rakefile +86 -0
- data/bin/duby +10 -0
- data/bin/dubyc +10 -0
- data/bin/dubyp +10 -0
- data/bin/jrubyp +36 -0
- data/bin/mirah +9 -0
- data/bin/mirah.cmd +1 -0
- data/bin/mirahc +9 -0
- data/bin/mirahc.cmd +1 -0
- data/bin/mirahp +9 -0
- data/bin/mirahp.cmd +1 -0
- data/examples/ant/example-build.xml +7 -0
- data/examples/appengine/Rakefile +19 -0
- data/examples/appengine/Readme +29 -0
- data/examples/appengine/src/org/mirah/MirahApp.mirah +57 -0
- data/examples/appengine/src/org/mirah/list.dhtml +15 -0
- data/examples/appengine/war/WEB-INF/lib/dubydatastore.jar +0 -0
- data/examples/bintrees.mirah +66 -0
- data/examples/construction.mirah +8 -0
- data/examples/dynamic.mirah +17 -0
- data/examples/edb.mirah +3 -0
- data/examples/fib.mirah +16 -0
- data/examples/fields.mirah +22 -0
- data/examples/fractal.mirah +55 -0
- data/examples/java_thing.mirah +13 -0
- data/examples/plugins/appengine/Rakefile +55 -0
- data/examples/plugins/appengine/lib/com/google/appengine/ext/duby/db/datastore.rb +375 -0
- data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/Model.duby +336 -0
- data/examples/plugins/appengine/test/com/google/appengine/ext/duby/db/ModelTest.duby +113 -0
- data/examples/simple_class.mirah +12 -0
- data/examples/sort_closure.mirah +7 -0
- data/examples/swing.mirah +20 -0
- data/examples/tak.mirah +15 -0
- data/examples/test.edb +9 -0
- data/examples/wiki/Rakefile +18 -0
- data/examples/wiki/src/org/mirah/wiki/MirahWiki.duby +324 -0
- data/examples/wiki/src/org/mirah/wiki/edit.eduby.html +42 -0
- data/examples/wiki/src/org/mirah/wiki/error.eduby.html +2 -0
- data/examples/wiki/src/org/mirah/wiki/layout.eduby.html +69 -0
- data/examples/wiki/src/org/mirah/wiki/parser.eduby.html +7 -0
- data/examples/wiki/src/org/mirah/wiki/view.eduby.html +15 -0
- data/examples/wiki/war/WEB-INF/classes/test/HeredocContext.class +0 -0
- data/examples/wiki/war/WEB-INF/classes/test/MirahParser.class +0 -0
- data/examples/wiki/war/WEB-INF/lib/appengine-api.jar +0 -0
- data/examples/wiki/war/WEB-INF/lib/dubydatastore.jar +0 -0
- data/examples/wiki/war/WEB-INF/lib/jmeta-runtime.jar +0 -0
- data/examples/wiki/war/WEB-INF/lib/pegdown-stubs.jar +0 -0
- data/examples/wiki/war/WEB-INF/pegdown.jar +0 -0
- data/examples/wiki/war/app.yaml +21 -0
- data/examples/wiki/war/public/favicon.ico +0 -0
- data/examples/wiki/war/public/images/appengine_duby.png +0 -0
- data/examples/wiki/war/public/images/back.gif +0 -0
- data/examples/wiki/war/public/images/dir.gif +0 -0
- data/examples/wiki/war/public/images/file.gif +0 -0
- data/examples/wiki/war/public/javascripts/prettify.js +61 -0
- data/examples/wiki/war/public/robots.txt +0 -0
- data/examples/wiki/war/public/stylesheets/main.css +156 -0
- data/examples/wiki/war/public/stylesheets/prettify.css +1 -0
- data/examples/wiki/war/public/stylesheets/sh_style.css +66 -0
- data/examples/wiki/war/public/stylesheets/source.css +21 -0
- data/examples/wiki/war/public/wmd/images/bg-fill.png +0 -0
- data/examples/wiki/war/public/wmd/images/bg.png +0 -0
- data/examples/wiki/war/public/wmd/images/blockquote.png +0 -0
- data/examples/wiki/war/public/wmd/images/bold.png +0 -0
- data/examples/wiki/war/public/wmd/images/code.png +0 -0
- data/examples/wiki/war/public/wmd/images/h1.png +0 -0
- data/examples/wiki/war/public/wmd/images/hr.png +0 -0
- data/examples/wiki/war/public/wmd/images/img.png +0 -0
- data/examples/wiki/war/public/wmd/images/italic.png +0 -0
- data/examples/wiki/war/public/wmd/images/link.png +0 -0
- data/examples/wiki/war/public/wmd/images/ol.png +0 -0
- data/examples/wiki/war/public/wmd/images/redo.png +0 -0
- data/examples/wiki/war/public/wmd/images/separator.png +0 -0
- data/examples/wiki/war/public/wmd/images/ul.png +0 -0
- data/examples/wiki/war/public/wmd/images/undo.png +0 -0
- data/examples/wiki/war/public/wmd/images/wmd-on.png +0 -0
- data/examples/wiki/war/public/wmd/images/wmd.png +0 -0
- data/examples/wiki/war/public/wmd/showdown.js +421 -0
- data/examples/wiki/war/public/wmd/wmd-base.js +1799 -0
- data/examples/wiki/war/public/wmd/wmd-plus.js +311 -0
- data/examples/wiki/war/public/wmd/wmd.js +73 -0
- data/javalib/JRubyParser.jar +0 -0
- data/javalib/dynalang-invoke-0.1.jar +0 -0
- data/javalib/mirah-bootstrap.jar +0 -0
- data/javalib/mirah-parser.jar +0 -0
- data/lib/duby.rb +2 -0
- data/lib/mirah.rb +338 -0
- data/lib/mirah/appengine_tasks.rb +146 -0
- data/lib/mirah/ast.rb +615 -0
- data/lib/mirah/ast/call.rb +307 -0
- data/lib/mirah/ast/class.rb +311 -0
- data/lib/mirah/ast/flow.rb +364 -0
- data/lib/mirah/ast/intrinsics.rb +470 -0
- data/lib/mirah/ast/literal.rb +154 -0
- data/lib/mirah/ast/local.rb +89 -0
- data/lib/mirah/ast/method.rb +360 -0
- data/lib/mirah/ast/scope.rb +208 -0
- data/lib/mirah/ast/structure.rb +226 -0
- data/lib/mirah/ast/type.rb +130 -0
- data/lib/mirah/compiler.rb +341 -0
- data/lib/mirah/env.rb +33 -0
- data/lib/mirah/jvm/base.rb +258 -0
- data/lib/mirah/jvm/compiler.rb +885 -0
- data/lib/mirah/jvm/method_lookup.rb +203 -0
- data/lib/mirah/jvm/source_compiler.rb +737 -0
- data/lib/mirah/jvm/source_generator/builder.rb +444 -0
- data/lib/mirah/jvm/source_generator/loops.rb +110 -0
- data/lib/mirah/jvm/source_generator/precompile.rb +188 -0
- data/lib/mirah/jvm/source_generator/typer.rb +11 -0
- data/lib/mirah/jvm/typer.rb +151 -0
- data/lib/mirah/jvm/types.rb +416 -0
- data/lib/mirah/jvm/types/basic_types.rb +33 -0
- data/lib/mirah/jvm/types/boolean.rb +17 -0
- data/lib/mirah/jvm/types/enumerable.rb +65 -0
- data/lib/mirah/jvm/types/extensions.rb +86 -0
- data/lib/mirah/jvm/types/factory.rb +186 -0
- data/lib/mirah/jvm/types/floats.rb +86 -0
- data/lib/mirah/jvm/types/integers.rb +171 -0
- data/lib/mirah/jvm/types/intrinsics.rb +376 -0
- data/lib/mirah/jvm/types/literals.rb +74 -0
- data/lib/mirah/jvm/types/methods.rb +614 -0
- data/lib/mirah/jvm/types/number.rb +143 -0
- data/lib/mirah/nbcompiler.rb +29 -0
- data/lib/mirah/plugin/edb.rb +29 -0
- data/lib/mirah/plugin/gwt.rb +173 -0
- data/lib/mirah/plugin/java.rb +55 -0
- data/lib/mirah/transform.rb +266 -0
- data/lib/mirah/transform2.rb +728 -0
- data/lib/mirah/typer.rb +407 -0
- data/lib/mirah_task.rb +107 -0
- data/test/test_ast.rb +359 -0
- data/test/test_compilation.rb +112 -0
- data/test/test_env.rb +42 -0
- data/test/test_gwt.rb +58 -0
- data/test/test_java_typer.rb +183 -0
- data/test/test_javac_compiler.rb +63 -0
- data/test/test_jvm_compiler.rb +2607 -0
- data/test/test_typer.rb +221 -0
- metadata +235 -0
@@ -0,0 +1,208 @@
|
|
1
|
+
module Duby
|
2
|
+
module AST
|
3
|
+
module Scoped
|
4
|
+
def scope
|
5
|
+
@scope ||= begin
|
6
|
+
scope = parent
|
7
|
+
until scope.nil? || scope.class.include?(Scope)
|
8
|
+
scope = scope.parent
|
9
|
+
end
|
10
|
+
scope
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def containing_scope
|
15
|
+
scope = self.scope.static_scope
|
16
|
+
while !scope.shadowed?(name) && scope.parent && scope.parent.include?(name)
|
17
|
+
scope = scope.parent
|
18
|
+
end
|
19
|
+
scope
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module Scope
|
24
|
+
include Scoped
|
25
|
+
attr_writer :static_scope, :type_scope
|
26
|
+
def static_scope
|
27
|
+
@static_scope ||= StaticScope.new(self)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module ClassScoped
|
32
|
+
def class_scope
|
33
|
+
@class_scope ||= begin
|
34
|
+
scope = parent
|
35
|
+
scope = scope.parent until scope.nil? || ClassDefinition === scope
|
36
|
+
scope
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class StaticScope
|
42
|
+
java_import 'java.util.LinkedHashMap'
|
43
|
+
attr_reader :parent
|
44
|
+
attr_writer :self_type, :self_node, :package
|
45
|
+
|
46
|
+
def initialize(node, parent=nil)
|
47
|
+
@scope_node = node
|
48
|
+
@vars = {}
|
49
|
+
@var_types = {}
|
50
|
+
@parent = parent
|
51
|
+
@children = {}
|
52
|
+
@imports = {}
|
53
|
+
@search_packages = []
|
54
|
+
@shadowed = {}
|
55
|
+
end
|
56
|
+
|
57
|
+
def <<(name)
|
58
|
+
@vars[name] = true
|
59
|
+
end
|
60
|
+
|
61
|
+
def shadow(name)
|
62
|
+
@shadowed[name] = @vars[name] = true
|
63
|
+
end
|
64
|
+
|
65
|
+
def shadowed?(name)
|
66
|
+
@shadowed[name]
|
67
|
+
end
|
68
|
+
|
69
|
+
def locals
|
70
|
+
@vars.keys
|
71
|
+
end
|
72
|
+
|
73
|
+
def local_type(name)
|
74
|
+
@var_types[name]
|
75
|
+
end
|
76
|
+
|
77
|
+
def learn_local_type(name, type)
|
78
|
+
return unless type
|
79
|
+
existing_type = local_type(name)
|
80
|
+
if existing_type
|
81
|
+
unless existing_type.assignable_from?(type)
|
82
|
+
raise Duby::Typer::InferenceError.new(
|
83
|
+
"Can't assign #{type.full_name} to " \
|
84
|
+
"variable of type #{existing_type.full_name}")
|
85
|
+
end
|
86
|
+
existing_type
|
87
|
+
elsif type
|
88
|
+
@var_types[name] = type
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def include?(name, include_parent=true)
|
93
|
+
@vars.include?(name) ||
|
94
|
+
(include_parent && parent && parent.include?(name))
|
95
|
+
end
|
96
|
+
|
97
|
+
def captured?(name)
|
98
|
+
if !include?(name, false)
|
99
|
+
return false
|
100
|
+
elsif parent && parent.include?(name)
|
101
|
+
return true
|
102
|
+
else
|
103
|
+
return children.any? {|child| child.include?(name, false)}
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def children
|
108
|
+
@children.keys
|
109
|
+
end
|
110
|
+
|
111
|
+
def add_child(scope)
|
112
|
+
@children[scope] = true
|
113
|
+
end
|
114
|
+
|
115
|
+
def remove_child(scope)
|
116
|
+
@children.delete(scope)
|
117
|
+
end
|
118
|
+
|
119
|
+
def parent=(parent)
|
120
|
+
@parent.remove_child(self) if @parent
|
121
|
+
parent.add_child(self)
|
122
|
+
@parent = parent
|
123
|
+
end
|
124
|
+
|
125
|
+
def outer_scope
|
126
|
+
node = @scope_node.scope
|
127
|
+
node && node.static_scope
|
128
|
+
end
|
129
|
+
|
130
|
+
def self_type
|
131
|
+
if @self_type.nil? && parent
|
132
|
+
@self_type = parent.self_type
|
133
|
+
end
|
134
|
+
@self_type
|
135
|
+
end
|
136
|
+
|
137
|
+
def self_node
|
138
|
+
if @self_node.nil? && parent
|
139
|
+
@self_node = parent.self_node
|
140
|
+
end
|
141
|
+
@self_node
|
142
|
+
end
|
143
|
+
|
144
|
+
def binding_type(defining_class=nil, duby=nil)
|
145
|
+
@binding_type ||= begin
|
146
|
+
if parent
|
147
|
+
parent.binding_type(defining_class, duby)
|
148
|
+
else
|
149
|
+
name = "#{defining_class.name}$#{duby.tmp}"
|
150
|
+
factory = Duby::AST.type_factory
|
151
|
+
if factory
|
152
|
+
factory.declare_type(@scope_node, name)
|
153
|
+
else
|
154
|
+
Duby::AST::TypeReference.new(name, false, false)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def binding_type=(type)
|
161
|
+
if parent
|
162
|
+
parent.binding_type = type
|
163
|
+
else
|
164
|
+
@binding_type = type
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def has_binding?
|
169
|
+
@binding_type != nil || (parent && parent.has_binding?)
|
170
|
+
end
|
171
|
+
|
172
|
+
def package
|
173
|
+
@package || outer_scope.package
|
174
|
+
end
|
175
|
+
|
176
|
+
def fetch_imports(map)
|
177
|
+
parent_scope = outer_scope
|
178
|
+
parent_scope.fetch_imports(map) if parent_scope
|
179
|
+
|
180
|
+
map.update(@imports)
|
181
|
+
end
|
182
|
+
|
183
|
+
def fetch_packages(list)
|
184
|
+
parent_scope = outer_scope
|
185
|
+
parent_scope.fetch_packages(list) if parent_scope
|
186
|
+
|
187
|
+
list.concat(@search_packages)
|
188
|
+
end
|
189
|
+
|
190
|
+
def imports
|
191
|
+
@cached_imports ||= fetch_imports({})
|
192
|
+
end
|
193
|
+
|
194
|
+
def search_packages
|
195
|
+
@cached_packages ||= fetch_packages([])
|
196
|
+
end
|
197
|
+
|
198
|
+
def import(full_name, short_name)
|
199
|
+
return if full_name == short_name
|
200
|
+
if short_name == '*'
|
201
|
+
@search_packages << full_name.sub(/\.\*$/, '')
|
202
|
+
else
|
203
|
+
@imports[short_name] = full_name
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
@@ -0,0 +1,226 @@
|
|
1
|
+
module Duby::AST
|
2
|
+
class Body < Node
|
3
|
+
def initialize(parent, line_number, &block)
|
4
|
+
super(parent, line_number, &block)
|
5
|
+
end
|
6
|
+
|
7
|
+
# Type of a block is the type of its final element
|
8
|
+
def infer(typer)
|
9
|
+
unless @inferred_type
|
10
|
+
@typer ||= typer
|
11
|
+
@self_type ||= typer.self_type
|
12
|
+
if children.size == 0
|
13
|
+
@inferred_type = typer.no_type
|
14
|
+
else
|
15
|
+
children.each {|child| @inferred_type = typer.infer(child)}
|
16
|
+
end
|
17
|
+
|
18
|
+
if @inferred_type
|
19
|
+
resolved!
|
20
|
+
else
|
21
|
+
typer.defer(self)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
@inferred_type
|
26
|
+
end
|
27
|
+
|
28
|
+
def <<(node)
|
29
|
+
super
|
30
|
+
if @typer
|
31
|
+
orig_self = @typer.self_type
|
32
|
+
@typer.known_types['self'] = @self_type
|
33
|
+
@typer.infer(node)
|
34
|
+
@typer.known_types['self'] = orig_self
|
35
|
+
end
|
36
|
+
self
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# class << self
|
41
|
+
class ClassAppendSelf < Body
|
42
|
+
include Scope
|
43
|
+
include Scoped
|
44
|
+
|
45
|
+
def initialize(parent, line_number, &block)
|
46
|
+
super(parent, line_number, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
def infer(typer)
|
50
|
+
static_scope.self_type = scope.static_scope.self_type.meta
|
51
|
+
super
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class ScopedBody < Body
|
56
|
+
include Scope
|
57
|
+
include Scoped
|
58
|
+
|
59
|
+
def infer(typer)
|
60
|
+
static_scope.self_type ||= typer.self_type
|
61
|
+
super
|
62
|
+
end
|
63
|
+
|
64
|
+
def inspect_children(indent=0)
|
65
|
+
indent_str = ' ' * indent
|
66
|
+
str = ''
|
67
|
+
if static_scope.self_node
|
68
|
+
str << "\n#{indent_str}self:\n" << static_scope.self_node.inspect(indent + 1)
|
69
|
+
end
|
70
|
+
str << "\n#{indent_str}body:" << super(indent + 1)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class Block < Node
|
75
|
+
include Scoped
|
76
|
+
include Scope
|
77
|
+
include Java::DubyLangCompiler::Block
|
78
|
+
child :args
|
79
|
+
child :body
|
80
|
+
|
81
|
+
def initialize(parent, position, &block)
|
82
|
+
super(parent, position) do
|
83
|
+
static_scope.parent = scope.static_scope
|
84
|
+
yield(self) if block_given?
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def prepare(typer, method)
|
89
|
+
duby = typer.transformer
|
90
|
+
interface = method.argument_types[-1]
|
91
|
+
outer_class = scope.defining_class
|
92
|
+
binding = scope.binding_type(duby)
|
93
|
+
name = "#{outer_class.name}$#{duby.tmp}"
|
94
|
+
klass = duby.define_closure(position, name, outer_class)
|
95
|
+
klass.interfaces = [interface]
|
96
|
+
klass.define_constructor(position,
|
97
|
+
['binding', binding]) do |c|
|
98
|
+
duby.eval("@binding = binding", '-', c, 'binding')
|
99
|
+
end
|
100
|
+
|
101
|
+
# TODO We need a special scope here that allows access to the
|
102
|
+
# outer class.
|
103
|
+
static_scope.self_type = typer.infer(klass)
|
104
|
+
|
105
|
+
add_methods(klass, binding, typer)
|
106
|
+
|
107
|
+
call = parent
|
108
|
+
instance = Call.new(call, position, 'new')
|
109
|
+
instance.target = Constant.new(call, position, name)
|
110
|
+
instance.parameters = [
|
111
|
+
BindingReference.new(instance, position, binding)
|
112
|
+
]
|
113
|
+
call.parameters << instance
|
114
|
+
call.block = nil
|
115
|
+
typer.infer(instance)
|
116
|
+
end
|
117
|
+
|
118
|
+
def add_methods(klass, binding, typer)
|
119
|
+
found_def = false
|
120
|
+
body.each do |node|
|
121
|
+
if node.kind_of?(MethodDefinition)
|
122
|
+
found_def = true
|
123
|
+
node.static_scope = static_scope
|
124
|
+
node.binding_type = binding
|
125
|
+
klass.append_node(node)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
build_method(klass, binding, typer) unless found_def
|
129
|
+
end
|
130
|
+
|
131
|
+
def build_method(klass, binding, typer)
|
132
|
+
# find all methods which would not otherwise be on java.lang.Object
|
133
|
+
impl_methods = find_methods(klass.interfaces).select do |m|
|
134
|
+
begin
|
135
|
+
obj_m = java.lang.Object.java_class.java_method m.name, *m.parameter_types
|
136
|
+
rescue NameError
|
137
|
+
# not found on Object
|
138
|
+
next true
|
139
|
+
end
|
140
|
+
# found on Object
|
141
|
+
next false
|
142
|
+
end
|
143
|
+
|
144
|
+
raise "Multiple abstract methods found; cannot use block" if impl_methods.size > 1
|
145
|
+
impl_methods.each do |method|
|
146
|
+
mdef = klass.define_method(position,
|
147
|
+
method.name,
|
148
|
+
method.return_type,
|
149
|
+
args.dup)
|
150
|
+
mdef.static_scope = static_scope
|
151
|
+
mdef.body = body.dup
|
152
|
+
mdef.binding_type = binding
|
153
|
+
typer.infer(mdef.body)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def find_methods(interfaces)
|
158
|
+
methods = []
|
159
|
+
interfaces = interfaces.dup
|
160
|
+
until interfaces.empty?
|
161
|
+
interface = interfaces.pop
|
162
|
+
methods += interface.declared_instance_methods.select {|m| m.abstract?}
|
163
|
+
interfaces.concat(interface.interfaces)
|
164
|
+
end
|
165
|
+
methods
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
class BindingReference < Node
|
170
|
+
def initialize(parent, position, type)
|
171
|
+
super(parent, position)
|
172
|
+
@inferred_type = type
|
173
|
+
end
|
174
|
+
|
175
|
+
def infer(typer)
|
176
|
+
resolved! unless resolved?
|
177
|
+
@inferred_type
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
class Noop < Node
|
182
|
+
def infer(typer)
|
183
|
+
resolved!
|
184
|
+
@inferred_type ||= typer.no_type
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
class Script < Node
|
189
|
+
include Scope
|
190
|
+
include Binding
|
191
|
+
child :body
|
192
|
+
|
193
|
+
attr_accessor :defining_class
|
194
|
+
attr_reader :filename
|
195
|
+
|
196
|
+
def initialize(parent, line_number, &block)
|
197
|
+
super(parent, line_number, &block)
|
198
|
+
@package = ""
|
199
|
+
end
|
200
|
+
|
201
|
+
def infer(typer)
|
202
|
+
resolve_if(typer) do
|
203
|
+
typer.set_filename(self, filename)
|
204
|
+
@defining_class ||= begin
|
205
|
+
static_scope.self_type = typer.self_type
|
206
|
+
end
|
207
|
+
typer.infer(body)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def filename=(filename)
|
212
|
+
@filename = filename
|
213
|
+
if Script.explicit_packages
|
214
|
+
static_scope.package = ''
|
215
|
+
else
|
216
|
+
package = File.dirname(@filename).tr('/', '.')
|
217
|
+
package.sub! /^\.+/, ''
|
218
|
+
static_scope.package = package
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
class << self
|
223
|
+
attr_accessor :explicit_packages
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
module Duby::AST
|
2
|
+
class Import < Node
|
3
|
+
include Scoped
|
4
|
+
attr_accessor :short
|
5
|
+
attr_accessor :long
|
6
|
+
def initialize(parent, line_number, short, long)
|
7
|
+
@short = short
|
8
|
+
@long = long
|
9
|
+
super(parent, line_number, [])
|
10
|
+
scope.static_scope.import(long, short)
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
"Import(#{short} = #{long})"
|
15
|
+
end
|
16
|
+
|
17
|
+
def infer(typer)
|
18
|
+
begin
|
19
|
+
typer.type_reference(scope, @long)
|
20
|
+
rescue NameError => ex
|
21
|
+
typer.known_types[short] = Duby::AST.error_type
|
22
|
+
raise ex
|
23
|
+
end
|
24
|
+
typer.no_type
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
defmacro('import') do |transformer, fcall, parent|
|
29
|
+
case fcall.parameters.size
|
30
|
+
when 1
|
31
|
+
node = fcall.parameters[0]
|
32
|
+
case node
|
33
|
+
when String
|
34
|
+
long = node.literal
|
35
|
+
short = long[(long.rindex('.') + 1)..-1]
|
36
|
+
when Call
|
37
|
+
case node.parameters.size
|
38
|
+
when 0
|
39
|
+
pieces = [node.name]
|
40
|
+
while Call === node
|
41
|
+
node = node.target
|
42
|
+
pieces << node.name
|
43
|
+
end
|
44
|
+
long = pieces.reverse.join '.'
|
45
|
+
short = pieces[0]
|
46
|
+
when 1
|
47
|
+
arg = node.parameters[0]
|
48
|
+
unless (FunctionalCall === arg &&
|
49
|
+
arg.name == 'as' && arg.parameters.size == 1)
|
50
|
+
raise Duby::TransformError.new("unknown import syntax", fcall)
|
51
|
+
end
|
52
|
+
short = arg.parameters[0].name
|
53
|
+
pieces = [node.name]
|
54
|
+
while Call === node
|
55
|
+
node = node.target
|
56
|
+
pieces << node.name
|
57
|
+
end
|
58
|
+
long = pieces.reverse.join '.'
|
59
|
+
else
|
60
|
+
raise Duby::TransformError.new("unknown import syntax", fcall)
|
61
|
+
end
|
62
|
+
else
|
63
|
+
raise Duby::TransformError.new("unknown import syntax", fcall)
|
64
|
+
end
|
65
|
+
when 2
|
66
|
+
short = fcall.parameters[0].literal
|
67
|
+
long = fcall.parameters[1].literal
|
68
|
+
else
|
69
|
+
raise Duby::TransformError.new("unknown import syntax", fcall)
|
70
|
+
end
|
71
|
+
Import.new(parent, fcall.position, short, long)
|
72
|
+
end
|
73
|
+
|
74
|
+
defmacro('package') do |transformer, fcall, parent|
|
75
|
+
node = fcall.parameters[0]
|
76
|
+
block = fcall.block
|
77
|
+
case node
|
78
|
+
when String
|
79
|
+
name = node.literal
|
80
|
+
when Call
|
81
|
+
pieces = [node.name]
|
82
|
+
block ||= node.block
|
83
|
+
while Call === node
|
84
|
+
node = node.target
|
85
|
+
pieces << node.name
|
86
|
+
block ||= node.block
|
87
|
+
end
|
88
|
+
name = pieces.reverse.join '.'
|
89
|
+
when FunctionalCall
|
90
|
+
name = node.name
|
91
|
+
block ||= node.block
|
92
|
+
else
|
93
|
+
raise Duby::TransformError.new("unknown package syntax", fcall)
|
94
|
+
end
|
95
|
+
if block
|
96
|
+
raise Duby::TransformError.new("unknown package syntax", block)
|
97
|
+
new_scope = ScopedBody.new(parent, fcall.position)
|
98
|
+
new_scope.static_scope.package = name
|
99
|
+
new_scope << block.body
|
100
|
+
else
|
101
|
+
fcall.scope.static_scope.package = name
|
102
|
+
Noop.new(parent, fcall.position)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
class EmptyArray < Node
|
107
|
+
attr_accessor :size
|
108
|
+
attr_accessor :component_type
|
109
|
+
child :type_node
|
110
|
+
child :size
|
111
|
+
|
112
|
+
def initialize(*args)
|
113
|
+
super(*args)
|
114
|
+
end
|
115
|
+
|
116
|
+
def infer(typer)
|
117
|
+
resolve_if(typer) do
|
118
|
+
@component_type = type_node.type_reference(typer)
|
119
|
+
typer.infer(size)
|
120
|
+
typer.type_reference(nil, @component_type, true)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
class Builtin < Node
|
126
|
+
def infer(typer)
|
127
|
+
resolve_if(typer) {Duby::AST.type(nil, 'mirah.impl.Builtin')}
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|