mirah 0.1.4-java → 0.2.0-java
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +0 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/History.txt +531 -0
- data/README.md +23 -10
- data/Rakefile +239 -156
- data/TODO.md +71 -10
- data/bin/mirah +1 -1
- data/bin/mirahc +1 -1
- data/dist/mirahc.jar +0 -0
- data/examples/bintrees.mirah +2 -2
- data/examples/construction.mirah +2 -2
- data/examples/fields.mirah +1 -1
- data/examples/fractal.mirah +1 -1
- data/examples/fractal.rb +70 -0
- data/examples/interfaces.mirah +1 -1
- data/examples/java_thing.mirah +1 -1
- data/examples/macros/square.mirah +3 -3
- data/examples/macros/square_int.mirah +3 -3
- data/examples/macros/string_each_char.mirah +6 -6
- data/examples/rosettacode/100-doors.mirah +0 -2
- data/examples/rosettacode/count-occurrences-of-a-substring.mirah +3 -3
- data/examples/rosettacode/empty-string.mirah +1 -1
- data/examples/rosettacode/fizz-buzz.mirah +4 -4
- data/examples/rosettacode/is-string-numeric.mirah +7 -7
- data/examples/rosettacode/palindrome.mirah +2 -2
- data/examples/rosettacode/reverse-a-string.mirah +1 -1
- data/examples/rosettacode/rot-13.mirah +1 -1
- data/examples/{edb.mirah → rosettacode/simple_character_math.mirah} +13 -4
- data/examples/rosettacode/string-case.mirah +2 -2
- data/examples/rosettacode/string-length.mirah +1 -1
- data/examples/swing.mirah +9 -14
- data/extensions_and_macros.md +117 -0
- data/lib/mirah.rb +1 -1
- data/lib/mirah/errors.rb +3 -1
- data/lib/mirah/transform/ast_ext.rb +3 -2
- data/lib/mirah/util/process_errors.rb +1 -2
- data/lib/mirah/version.rb +1 -1
- data/test/A.class +0 -0
- data/test/core/util/jvm_version_test.rb +10 -0
- data/test/core/util/mirah_arguments_test.rb +51 -4
- data/test/fixtures/cp1251_test.mirah +7 -0
- data/test/fixtures/org/foo/AbstractExecutorJava8.java +30 -0
- data/test/fixtures/org/foo/ClassWithSelfReferencingTypeParameter.java +24 -0
- data/test/fixtures/org/foo/InnerInterfaceClass.java +12 -0
- data/test/fixtures/org/foo/IntAnno.class +0 -0
- data/test/fixtures/org/foo/TypeFixtureJava8.java +10 -0
- data/test/fixtures/utf8_test.mirah +7 -0
- data/test/jvm/access_levels_test.rb +31 -0
- data/test/jvm/annotations_test.rb +3 -6
- data/test/jvm/blocks_test.rb +303 -120
- data/test/jvm/cast_test.rb +123 -50
- data/test/jvm/closure_test.rb +242 -0
- data/test/jvm/constructors_test.rb +1 -3
- data/test/jvm/example_test.rb +6 -2
- data/test/jvm/extensions/array_extensions_test.rb +181 -0
- data/test/jvm/extensions/collection_extensions_test.rb +195 -0
- data/test/jvm/{enumerable_test.rb → extensions/enumerable_test.rb} +81 -13
- data/test/jvm/extensions/hash_extensions_test.rb +56 -0
- data/test/jvm/extensions/list_extensions_test.rb +143 -0
- data/test/jvm/extensions/lock_extensions_test.rb +43 -0
- data/test/jvm/{numeric_extensions_test.rb → extensions/numeric_extensions_test.rb} +0 -0
- data/test/jvm/extensions/numeric_operators_test.rb +86 -0
- data/test/jvm/extensions/object_extensions_test.rb +122 -0
- data/test/jvm/{string_builder_extensions_test.rb → extensions/string_builder_extensions_test.rb} +0 -0
- data/test/jvm/{string_extensions_test.rb → extensions/string_extensions_test.rb} +57 -4
- data/test/jvm/generics_test.rb +14 -6
- data/test/jvm/import_test.rb +38 -1
- data/test/jvm/interface_test.rb +17 -0
- data/test/jvm/jvm_commands_test.rb +9 -0
- data/test/jvm/jvm_compiler_test.rb +568 -43
- data/test/jvm/macros_test.rb +343 -19
- data/test/jvm/main_method_test.rb +1 -3
- data/test/jvm/new_backend_test_helper.rb +54 -7
- data/test/jvm/rescue_test.rb +20 -5
- data/test/jvm/static_fields_test.rb +52 -10
- data/test/jvm/{mirror_compilation_test_helper.rb → string_test.rb} +10 -9
- data/test/jvm/varargs_test.rb +6 -16
- data/test/mirrors/base_type_test.rb +20 -7
- data/test/mirrors/bytecode_mirror_test.rb +8 -3
- data/test/mirrors/generics_test.rb +89 -10
- data/test/mirrors/member_test.rb +1 -1
- data/test/mirrors/method_lookup_test.rb +10 -3
- data/test/mirrors/mirrors_test.rb +20 -20
- data/test/mirrors/simple_async_mirror_loader_test.rb +1 -1
- data/test/mirrors/simple_mirror_loader_test.rb +1 -1
- data/test/newMirahClass$Closure2.class +0 -0
- data/test/newMirahClass.class +0 -0
- data/test/test_helper.rb +8 -1
- metadata +31 -16
- data/bin/bundler +0 -16
- data/bin/rake +0 -16
- data/examples/ant/example-build.xml~ +0 -7
- data/examples/test.edb +0 -9
- data/lib/mirah/compiler.rb +0 -67
- data/lib/mirah/parser.rb +0 -224
- data/lib/mirah/util/delegate.rb +0 -65
- data/test/jvm/list_extensions_test.rb +0 -23
data/TODO.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
- missing import should always show up in the summary of errors. eg
|
2
|
+
|
3
|
+
ERROR import X
|
4
|
+
ERROR fn X(1) doesn't exist
|
5
|
+
|
6
|
+
ERROR can't find type for import X
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
-- if a macro has a bug, the stacktrace is ugly
|
11
|
+
|
1
12
|
|
2
13
|
|
3
14
|
The TODO list of DOOM
|
@@ -31,6 +42,8 @@ Dist
|
|
31
42
|
|
32
43
|
Compiler Internals Improvements
|
33
44
|
======================
|
45
|
+
- add generic warnings / error message facility
|
46
|
+
-- right now we've got errors and they're ok. but it'd be better if we had something better.
|
34
47
|
- make Mirror type systems addDefaultImports more obvious
|
35
48
|
- faster mirah compiler build: src => class is tricky, I could make src => jar, jar => jar tho
|
36
49
|
- switch to minitest
|
@@ -51,6 +64,7 @@ Compiler Internals Improvements
|
|
51
64
|
- clean up javalib dir
|
52
65
|
- don't use 1.5 as java compile target
|
53
66
|
- make it obvious when ASTs have been dropped during macro expansion
|
67
|
+
- add timing to phases
|
54
68
|
|
55
69
|
- break compiler into phases
|
56
70
|
---------------
|
@@ -62,15 +76,19 @@ Compiler Internals Improvements
|
|
62
76
|
- load type systems
|
63
77
|
- load types for System, & predefs maybe?
|
64
78
|
- load scoped macros / extensions
|
79
|
+
|
65
80
|
# typer
|
66
81
|
- visit script body / class bodies, skipping method bodies
|
67
82
|
- compile macros
|
68
83
|
- visit method bodies
|
84
|
+
|
69
85
|
# finishs resolving typer wip
|
70
86
|
- resolve proxies
|
71
87
|
- change captured locals into binding fields
|
88
|
+
|
72
89
|
# clean up / compiler prep
|
73
90
|
- clean ast up
|
91
|
+
|
74
92
|
# compile
|
75
93
|
|
76
94
|
- maybe after parse, check built files to see if they need to be rebuilt, and ignore them otherwise
|
@@ -88,6 +106,10 @@ Warnings / Logging
|
|
88
106
|
|
89
107
|
- improve duplicate name/sig error when multiple method defs w/ same sig mirah#273
|
90
108
|
- code sources from macro expansion should know both the macro location and the invoke location and report both on errors so that users know where to look to debug
|
109
|
+
- -v should only show the version, it currently says no main method too. :/
|
110
|
+
- add -Werror where warnings become errors
|
111
|
+
- make block mirror type string a little nicer somehow
|
112
|
+
eg Can't find method java.util.concurrent.locks.ReentrantLock.synchronize(org.mirah.jvm.mirrors.BlockType)
|
91
113
|
|
92
114
|
Parser
|
93
115
|
======
|
@@ -97,25 +119,53 @@ Parser
|
|
97
119
|
|
98
120
|
Features
|
99
121
|
==========
|
122
|
+
- each macro for Maps
|
100
123
|
- Reflection Macros
|
101
124
|
- AST formatter that converts back to something the parser can parse
|
102
125
|
- default toString?
|
103
126
|
- default hashCode / equals
|
104
|
-
- change == to use equals
|
105
127
|
- default val/no type that defers to indy
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
128
|
+
eg
|
129
|
+
def foo(x: int, y=1)
|
130
|
+
end
|
131
|
+
should work
|
132
|
+
- allow defining equals using def ==(other)
|
112
133
|
- attr_reader/et al as varargs instead of just Hash. It would mean that the type info would have to come from somewhere else
|
113
134
|
- goto: headius wants it
|
114
135
|
- synchronize intrinsic ala java's
|
115
136
|
- file scoped macros / extensions
|
116
137
|
- extension syntax
|
117
|
-
- move macro / mirahc anno to separate class dir to improve javac interop
|
118
138
|
- public / private / protected / package scope helpers
|
139
|
+
|
140
|
+
|
141
|
+
# test cases
|
142
|
+
# - method w/ no modifier, modifier statement, method
|
143
|
+
# - modifier statement, method
|
144
|
+
# - modifier statement, method, same modifier statement, method
|
145
|
+
# - modifier statement, method, different modifier statement, method
|
146
|
+
# - modifier statement, method containing closure w/ mdefs
|
147
|
+
# - modifier fn w/ undefined method
|
148
|
+
# - mdef, modifier fn mname
|
149
|
+
# - modifier statement, modifiered method
|
150
|
+
# - modifier statement, differently modifiered method
|
151
|
+
# - modifier statement, modifiered method, unmodifiered method
|
152
|
+
# - modifier statement, differently modifiered method, unmodifiered method
|
153
|
+
|
154
|
+
# pub
|
155
|
+
# def a
|
156
|
+
# macro def self.public(mdef: MethodDefinition)
|
157
|
+
# set annotation on it directly
|
158
|
+
|
159
|
+
# macro def self.public(method_names: NodeList<Symbol> or something)
|
160
|
+
# find methods w/ those names, set anno on them directly
|
161
|
+
# if they don't exist, blow up
|
162
|
+
#macro def self.public()
|
163
|
+
# options
|
164
|
+
# 1) grab typer & set current scope's default access *** best most likely
|
165
|
+
# 2) don't expand here, instead throw into a queue, expand all at end
|
166
|
+
# 3) try to infer defs needed to do it
|
167
|
+
#end
|
168
|
+
|
119
169
|
- subclass access to super protected fields w/ @syntax
|
120
170
|
- (0) add a gets function like Ruby
|
121
171
|
- (2) a more "batteries included" set of imports
|
@@ -136,10 +186,16 @@ should work
|
|
136
186
|
- understand Java 8 default methods
|
137
187
|
- default args on non-last position params. eg when a method takes a block(read: functional interface), it should be allowed to have default args before the block arg.
|
138
188
|
- do jruby style method lookup
|
189
|
+
- add env var hash constant ala Ruby's ENV.
|
190
|
+
- Thread extensions:
|
191
|
+
Thread.start {}, which does t=Thread.new{};t.start;t
|
192
|
+
- macro for typecheck & cast. replace the x.kind_of? Y; Y(Object(x))
|
139
193
|
|
140
194
|
Bugs
|
141
195
|
==========
|
142
|
-
|
196
|
+
- a[-1] should work
|
197
|
+
- array ext size
|
198
|
+
- make sure that macro lookup looks at super classes
|
143
199
|
- "foo: #{x || y} acts weird", my guess is that interpolation doesn't generate the right code sometimes
|
144
200
|
- lambda's can't exist in methods! !! by which I mean that they can't close over things in methods. You can have them there, they just don't close. >:[]
|
145
201
|
- parser can't deal w/ unquotes in hash literals when key is unquote
|
@@ -169,6 +225,11 @@ class C
|
|
169
225
|
^^^^^^^^^
|
170
226
|
|
171
227
|
|
228
|
+
- constants are not referrable outside the defining scope :/ because they are private
|
229
|
+
- referring to classes as constants causes crashes
|
230
|
+
java -jar dist/mirahc.jar -cp test/fixtures/ -e 'puts org::foo::A' blows up w/ a asm error
|
231
|
+
java -jar dist/mirahc.jar -cp test/fixtures/ -e 'puts org::foo::A.class' doesn't
|
232
|
+
|
172
233
|
Libraries
|
173
234
|
===============
|
174
235
|
- delegation macro library
|
@@ -341,4 +402,4 @@ end
|
|
341
402
|
|
342
403
|
|
343
404
|
compile rake task doesn't fail, if it doesn't work for some things, it goes on anyway
|
344
|
-
in generics. hmm
|
405
|
+
in generics. hmm
|
data/bin/mirah
CHANGED
data/bin/mirahc
CHANGED
data/dist/mirahc.jar
CHANGED
Binary file
|
data/examples/bintrees.mirah
CHANGED
@@ -14,7 +14,7 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
16
|
class BinaryTrees
|
17
|
-
def self.main(args:String[])
|
17
|
+
def self.main(args:String[]):void
|
18
18
|
n = 0
|
19
19
|
n = Integer.parseInt(args[0]) if args.length > 0
|
20
20
|
|
@@ -72,7 +72,7 @@ class TreeNode
|
|
72
72
|
|
73
73
|
def itemCheck
|
74
74
|
# if necessary deallocate here
|
75
|
-
if @left
|
75
|
+
if @left.nil?
|
76
76
|
@item
|
77
77
|
else
|
78
78
|
@item + @left.itemCheck - @right.itemCheck
|
data/examples/construction.mirah
CHANGED
@@ -13,8 +13,8 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
import
|
17
|
-
import
|
16
|
+
import java.lang.StringBuffer
|
17
|
+
import java.util.ArrayList
|
18
18
|
|
19
19
|
list = ArrayList.new
|
20
20
|
sb = StringBuffer.new("Hello")
|
data/examples/fields.mirah
CHANGED
data/examples/fractal.mirah
CHANGED
data/examples/fractal.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
|
2
|
+
# All contributing project authors may be found in the NOTICE file.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
def run
|
17
|
+
puts "Rendering"
|
18
|
+
y = -39.0
|
19
|
+
while y <= 39.0
|
20
|
+
puts
|
21
|
+
x = -39.0
|
22
|
+
while x <= 39.0
|
23
|
+
i = iterate(x/40.0,y/40.0)
|
24
|
+
if (i == 0)
|
25
|
+
print "*"
|
26
|
+
else
|
27
|
+
print " "
|
28
|
+
end
|
29
|
+
x += 1
|
30
|
+
end
|
31
|
+
y += 1
|
32
|
+
end
|
33
|
+
puts
|
34
|
+
end
|
35
|
+
|
36
|
+
def iterate(x:double,y:double)
|
37
|
+
cr = y-0.5
|
38
|
+
ci = x
|
39
|
+
zi = 0.0
|
40
|
+
zr = 0.0
|
41
|
+
i = 0
|
42
|
+
|
43
|
+
result = 0
|
44
|
+
while true
|
45
|
+
i += 1
|
46
|
+
temp = zr * zi
|
47
|
+
zr2 = zr * zr
|
48
|
+
zi2 = zi * zi
|
49
|
+
zr = zr2 - zi2 + cr
|
50
|
+
zi = temp + temp + ci
|
51
|
+
if (zi2 + zr2 > 16)
|
52
|
+
result = i
|
53
|
+
break
|
54
|
+
end
|
55
|
+
if (i > 1000)
|
56
|
+
result = 0
|
57
|
+
break
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
result
|
62
|
+
end
|
63
|
+
|
64
|
+
i = 0
|
65
|
+
while i < 10
|
66
|
+
start = System.currentTimeMillis
|
67
|
+
run()
|
68
|
+
puts "Time: #{(System.currentTimeMillis - start) / 1000.0}"
|
69
|
+
i += 1
|
70
|
+
end
|
data/examples/interfaces.mirah
CHANGED
data/examples/java_thing.mirah
CHANGED
@@ -15,14 +15,14 @@
|
|
15
15
|
|
16
16
|
|
17
17
|
macro def eachChar(value, block:Block)
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
quote do
|
19
|
+
`value`.toCharArray.each do |`block.arguments`|
|
20
|
+
`block.body`
|
21
|
+
end
|
22
|
+
end
|
23
23
|
end
|
24
24
|
|
25
25
|
eachChar('laat de leeeuw niet in zijn hempie staan') do | my_char |
|
26
|
-
|
26
|
+
puts my_char
|
27
27
|
end
|
28
28
|
|
@@ -18,7 +18,7 @@ import java.util.regex.Pattern
|
|
18
18
|
import java.util.regex.Matcher
|
19
19
|
|
20
20
|
#The "remove and count the difference" method
|
21
|
-
def count_substring(pattern:
|
21
|
+
def count_substring(pattern:String, source:String)
|
22
22
|
(source.length() - source.replace(pattern, "").length()) / pattern.length()
|
23
23
|
end
|
24
24
|
|
@@ -28,7 +28,7 @@ puts count_substring("a*b", "abaabba*bbaba*bbab") # ==> 2
|
|
28
28
|
|
29
29
|
|
30
30
|
# The "split and count" method
|
31
|
-
def count_substring2(pattern:
|
31
|
+
def count_substring2(pattern:String, source:String)
|
32
32
|
# the result of split() will contain one more element than the delimiter
|
33
33
|
# the "-1" second argument makes it not discard trailing empty strings
|
34
34
|
source.split(Pattern.quote(pattern), -1).length - 1
|
@@ -40,7 +40,7 @@ puts count_substring2("a*b", "abaabba*bbaba*bbab") # ==> 2
|
|
40
40
|
|
41
41
|
|
42
42
|
# This method does a match and counts how many times it matches
|
43
|
-
def count_substring3(pattern:
|
43
|
+
def count_substring3(pattern:String, source:String)
|
44
44
|
result = 0
|
45
45
|
Matcher m = Pattern.compile(Pattern.quote(pattern)).matcher(source);
|
46
46
|
while (m.find())
|
@@ -19,6 +19,6 @@ empty_string2 = String.new
|
|
19
19
|
|
20
20
|
puts "empty string is empty" if empty_string1.isEmpty()
|
21
21
|
puts "empty string has no length" if empty_string2.length() == 0
|
22
|
-
puts "empty string is not nil" unless empty_string1
|
22
|
+
puts "empty string is not nil" unless empty_string1.nil?
|
23
23
|
|
24
24
|
|
@@ -15,10 +15,10 @@
|
|
15
15
|
|
16
16
|
|
17
17
|
1.upto(100) do |n|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
print "Fizz" if a = ((n % 3) == 0)
|
19
|
+
print "Buzz" if b = ((n % 5) == 0)
|
20
|
+
print n unless (a || b)
|
21
|
+
print "\n"
|
22
22
|
end
|
23
23
|
|
24
24
|
# a little more straight forward
|
@@ -19,7 +19,7 @@ import java.util.Scanner
|
|
19
19
|
|
20
20
|
# this first example relies on catching an exception,
|
21
21
|
# which is bad style and poorly performing in Java
|
22
|
-
def is_numeric?(s:
|
22
|
+
def is_numeric?(s:String)
|
23
23
|
begin
|
24
24
|
Double.parseDouble(s)
|
25
25
|
return true
|
@@ -40,7 +40,7 @@ puts '1.2.3 is not numeric' unless is_numeric?('1.2.3')
|
|
40
40
|
|
41
41
|
|
42
42
|
# check every element of the string
|
43
|
-
def is_numeric2?(s:
|
43
|
+
def is_numeric2?(s: String)
|
44
44
|
if (s == nil || s.isEmpty())
|
45
45
|
return false
|
46
46
|
end
|
@@ -79,7 +79,7 @@ puts '1.2.3 is not numeric' unless is_numeric2?('1.2.3')
|
|
79
79
|
|
80
80
|
|
81
81
|
# use a regular expression
|
82
|
-
def is_numeric3?(s:
|
82
|
+
def is_numeric3?(s:String)
|
83
83
|
s == nil || s.matches("[-+]?\\d+(\\.\\d+)?")
|
84
84
|
end
|
85
85
|
|
@@ -98,8 +98,8 @@ puts '1.2.3 is not numeric' unless is_numeric3?('1.2.3')
|
|
98
98
|
# (a more robust solution). If, after parsing, the parse position is at
|
99
99
|
# the end of the string, we can deduce that the entire string was a
|
100
100
|
# valid number.
|
101
|
-
def is_numeric4?(s:
|
102
|
-
return false if s
|
101
|
+
def is_numeric4?(s:String)
|
102
|
+
return false if s.nil?
|
103
103
|
formatter = NumberFormat.getInstance()
|
104
104
|
pos = ParsePosition.new(0)
|
105
105
|
formatter.parse(s, pos)
|
@@ -123,8 +123,8 @@ puts '1.2.3 is not numeric' unless is_numeric4?('1.2.3')
|
|
123
123
|
# shorts, bytes, doubles, floats, BigIntegers, and BigDecimals as well
|
124
124
|
# as methods for integral types where you may input a base/radix other than
|
125
125
|
# 10 (10 is the default, which can be changed using the useRadix method).
|
126
|
-
def is_numeric5?(s:
|
127
|
-
return false if s
|
126
|
+
def is_numeric5?(s:String)
|
127
|
+
return false if s.nil?
|
128
128
|
Scanner sc = Scanner.new(s)
|
129
129
|
sc.hasNextDouble()
|
130
130
|
end
|