duby 0.0.2-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/History.txt +8 -0
  2. data/README.txt +39 -0
  3. data/Rakefile +13 -0
  4. data/bin/duby +9 -0
  5. data/bin/dubyc +9 -0
  6. data/bin/dubyp +9 -0
  7. data/examples/README +16 -0
  8. data/examples/appengine/Rakefile +72 -0
  9. data/examples/appengine/Readme +27 -0
  10. data/examples/appengine/config.ru +7 -0
  11. data/examples/appengine/lib/duby/plugin/datastore.rb +171 -0
  12. data/examples/appengine/src/com/google/appengine/ext/duby/db/Model.duby +132 -0
  13. data/examples/appengine/src/com/ribrdb/DubyApp.duby +28 -0
  14. data/examples/appengine/src/com/ribrdb/list.dhtml +15 -0
  15. data/examples/construction.duby +8 -0
  16. data/examples/edb.duby +3 -0
  17. data/examples/fib.duby +24 -0
  18. data/examples/fields.duby +22 -0
  19. data/examples/fractal.duby +57 -0
  20. data/examples/java_thing.duby +13 -0
  21. data/examples/simple_class.duby +12 -0
  22. data/examples/swing.duby +20 -0
  23. data/examples/tak.duby +15 -0
  24. data/examples/test.edb +9 -0
  25. data/javalib/JRubyParser.jar +0 -0
  26. data/lib/duby.rb +168 -0
  27. data/lib/duby/ast.rb +386 -0
  28. data/lib/duby/ast/call.rb +145 -0
  29. data/lib/duby/ast/class.rb +154 -0
  30. data/lib/duby/ast/flow.rb +332 -0
  31. data/lib/duby/ast/intrinsics.rb +56 -0
  32. data/lib/duby/ast/literal.rb +97 -0
  33. data/lib/duby/ast/local.rb +92 -0
  34. data/lib/duby/ast/method.rb +244 -0
  35. data/lib/duby/ast/structure.rb +62 -0
  36. data/lib/duby/ast/type.rb +93 -0
  37. data/lib/duby/c/compiler.rb +134 -0
  38. data/lib/duby/compiler.rb +282 -0
  39. data/lib/duby/jvm/compiler.rb +766 -0
  40. data/lib/duby/jvm/method_lookup.rb +193 -0
  41. data/lib/duby/jvm/source_compiler.rb +605 -0
  42. data/lib/duby/jvm/source_generator/builder.rb +387 -0
  43. data/lib/duby/jvm/source_generator/loops.rb +110 -0
  44. data/lib/duby/jvm/source_generator/precompile.rb +170 -0
  45. data/lib/duby/jvm/source_generator/typer.rb +11 -0
  46. data/lib/duby/jvm/typer.rb +131 -0
  47. data/lib/duby/jvm/types.rb +331 -0
  48. data/lib/duby/jvm/types/basic_types.rb +19 -0
  49. data/lib/duby/jvm/types/boolean.rb +11 -0
  50. data/lib/duby/jvm/types/enumerable.rb +63 -0
  51. data/lib/duby/jvm/types/factory.rb +155 -0
  52. data/lib/duby/jvm/types/floats.rb +70 -0
  53. data/lib/duby/jvm/types/integers.rb +110 -0
  54. data/lib/duby/jvm/types/intrinsics.rb +230 -0
  55. data/lib/duby/jvm/types/literals.rb +82 -0
  56. data/lib/duby/jvm/types/methods.rb +381 -0
  57. data/lib/duby/jvm/types/number.rb +92 -0
  58. data/lib/duby/nbcompiler.rb +29 -0
  59. data/lib/duby/old/compiler_old.rb +845 -0
  60. data/lib/duby/old/declaration.rb +72 -0
  61. data/lib/duby/old/mapper.rb +72 -0
  62. data/lib/duby/old/signature.rb +52 -0
  63. data/lib/duby/old/typer_old.rb +163 -0
  64. data/lib/duby/plugin/edb.rb +25 -0
  65. data/lib/duby/plugin/java.rb +42 -0
  66. data/lib/duby/plugin/math.rb +84 -0
  67. data/lib/duby/transform.rb +1028 -0
  68. data/lib/duby/typer.rb +369 -0
  69. data/test/TestUser.class +0 -0
  70. data/test/test_ast.rb +391 -0
  71. data/test/test_compilation.rb +98 -0
  72. data/test/test_java_typer.rb +199 -0
  73. data/test/test_javac_compiler.rb +58 -0
  74. data/test/test_jvm_compiler.rb +1770 -0
  75. data/test/test_math_plugin.rb +87 -0
  76. data/test/test_typer.rb +246 -0
  77. metadata +156 -0
@@ -0,0 +1,8 @@
1
+ === 0.0.2 / 2010-02-15
2
+
3
+ * More language features added
4
+
5
+ === 0.0.1 / 2009-10-27
6
+
7
+ * First gem release
8
+ * Most things necessary for simple apps, scripts, servlets are working
@@ -0,0 +1,39 @@
1
+ = duby
2
+
3
+ * http://kenai.com/projects/duby
4
+
5
+ == DESCRIPTION:
6
+
7
+ Duby is a customizable programming language featuring static types,
8
+ local type inference and a heavily Ruby-inspired syntax. Duby
9
+ currently includes a typer/compiler backend for the JVM which can
10
+ output either JVM bytecode or Java source files.
11
+
12
+ == FEATURES/PROBLEMS:
13
+
14
+ * Ruby syntax
15
+ * Compiles to .class or .java
16
+ * Fast as Java
17
+
18
+ == SYNOPSIS:
19
+
20
+ duby <script.duby>
21
+ duby -e "inline script"
22
+ dubyc <script.duby>
23
+ dubyc -e "inline script" # produces dash_e.class
24
+ dubyc -java <script.duby>
25
+ dubyc -java -e "inline script" # produces dash_e.java
26
+
27
+ == REQUIREMENTS:
28
+
29
+ * JRuby 1.4RC2 or higher.
30
+ * BiteScript 0.0.5 or higher
31
+
32
+ == INSTALL:
33
+
34
+ * gem install duby
35
+
36
+ To build from source you should have a checkout of both jruby and
37
+ bitescript in Duby's parent directory. Run "ant jar-complete" in
38
+ jruby, then in the duby directory "ant bootstrap" followed by "ant"
39
+ should build it.
@@ -0,0 +1,13 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'java'
4
+
5
+ task :default => :test
6
+
7
+ Rake::TestTask.new :test do |t|
8
+ t.libs << "lib"
9
+ # This is hacky, I know
10
+ t.libs.concat Dir["../bitescript*/lib"]
11
+ t.test_files = FileList["test/**/*.rb"]
12
+ java.lang.System.set_property("jruby.duby.enabled", "true")
13
+ end
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env jruby
2
+ begin
3
+ require 'duby'
4
+ rescue LoadError
5
+ $: << File.dirname(File.dirname(__FILE__)) + '/lib'
6
+ require 'duby'
7
+ end
8
+
9
+ Duby.run(*ARGV)
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env jruby
2
+ begin
3
+ require 'duby'
4
+ rescue LoadError
5
+ $: << File.dirname(File.dirname(__FILE__)) + '/lib'
6
+ require 'duby'
7
+ end
8
+
9
+ Duby.compile(*ARGV)
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env jruby
2
+ begin
3
+ require 'duby'
4
+ rescue LoadError
5
+ $: << File.dirname(File.dirname(__FILE__)) + '/lib'
6
+ require 'duby'
7
+ end
8
+
9
+ puts Duby.parse(*ARGV).inspect
@@ -0,0 +1,16 @@
1
+ Duby: A Type-Inferred Ruby-Like JVM Language
2
+
3
+ Duby is an experimental project to create a JVM bytecode compiler for a
4
+ Ruby-like language that infers static types from argument declarations
5
+ and called methods. It is currently under development, but may eventually
6
+ be used to implement portions of JRuby, since Duby combines the terse,
7
+ neat syntax of Ruby with the performance of statically-typed Java
8
+ bytecode.
9
+
10
+ To compile the samples, run the following lines:
11
+
12
+ jruby lib/ruby/site_ruby/1.8/compiler/duby/compiler.rb <filename>
13
+
14
+ And to load and call them, use JRuby's Java integration:
15
+
16
+ CLASSPATH=. jruby -rjava -e "p Java::Foo.new.fib(35)"
@@ -0,0 +1,72 @@
1
+ require 'appengine-sdk'
2
+ require 'appengine-tools/web-xml'
3
+ require 'appengine-tools/xml-formatter'
4
+
5
+ SRC = File.expand_path(File.dirname(__FILE__) + '/src')
6
+ LIB = File.expand_path(File.dirname(__FILE__) + '/lib')
7
+ WAR = File.expand_path(File.dirname(__FILE__) + '/war')
8
+ CONFIG_RU = File.expand_path(File.dirname(__FILE__) + '/config.ru')
9
+ SERVLET = AppEngine::SDK::SDK_ROOT +
10
+ '/lib/shared/geronimo-servlet_2.5_spec-1.2.jar'
11
+ APIS = AppEngine::SDK::API_JAR
12
+
13
+ WEB_INF_CLASSES = WAR + '/WEB-INF/classes'
14
+ WEB_XML = WAR + '/WEB-INF/web.xml'
15
+ AEWEB_XML = WAR + '/WEB-INF/appengine-web.xml'
16
+
17
+ MODEL = 'com/google/appengine/ext/duby/db/Model'
18
+ DUBY_APP = 'com/ribrdb/DubyApp'
19
+
20
+ MODEL_DUBY = "#{SRC}/#{MODEL}.duby"
21
+ MODEL_CLASS = "#{WEB_INF_CLASSES}/#{MODEL}.class"
22
+ DUBY_APP_DUBY = "#{SRC}/#{DUBY_APP}.duby"
23
+ DUBY_APP_CLASS = "#{WEB_INF_CLASSES}/#{DUBY_APP}.class"
24
+ LIST = "#{SRC}/com/ribrdb/list.dhtml"
25
+
26
+ def dubyc(*files)
27
+ chdir(File.dirname(__FILE__) + '/src') do
28
+ files = files.join ' '
29
+ dest = '-d ../war/WEB-INF/classes'
30
+ dubyc = '../../../bin/dubyc'
31
+ options = "-I #{LIB} -p datastore"
32
+ orig_classpath = ENV['CLASSPATH']
33
+ ENV['CLASSPATH'] ||= ''
34
+ ENV['CLASSPATH'] += ":#{SERVLET}:#{APIS}:#{WEB_INF_CLASSES}"
35
+ sh %{#{dubyc} #{dest} #{options} #{files}}
36
+ ENV['CLASSPATH'] = orig_classpath
37
+ end
38
+ end
39
+
40
+ directory WEB_INF_CLASSES
41
+
42
+ file MODEL_CLASS => MODEL_DUBY do
43
+ dubyc("#{MODEL}.duby")
44
+ end
45
+
46
+ file DUBY_APP_CLASS => [DUBY_APP_DUBY, LIST, MODEL_CLASS] do
47
+ dubyc("#{DUBY_APP}.duby")
48
+ end
49
+
50
+ file WEB_XML => [WEB_INF_CLASSES, CONFIG_RU] do
51
+ builder = WebXmlBuilder.new do
52
+ eval IO.read(CONFIG_RU), nil, 'config.ru', 1
53
+ end
54
+ open(WEB_XML, 'w') do |webxml|
55
+ xml = AppEngine::Rack::XmlFormatter.format(builder.to_xml)
56
+ webxml.write(xml)
57
+ end
58
+ open(AEWEB_XML, 'w') do |aeweb|
59
+ xml = AppEngine::Rack::XmlFormatter.format(AppEngine::Rack.app.to_xml)
60
+ aeweb.write(xml)
61
+ end
62
+ end
63
+
64
+ task :server => [WEB_XML, DUBY_APP_CLASS] do
65
+ sh "dev_appserver.rb #{WAR}"
66
+ end
67
+
68
+ task :upload => [WEB_XML, DUBY_APP_CLASS] do
69
+ sh "appcfg.rb update #{WAR}"
70
+ end
71
+
72
+ task :default => :server
@@ -0,0 +1,27 @@
1
+ Run rake to compile the application and start the development server.
2
+
3
+ Requirements:
4
+ - Install the google-appengine gem (under MRI, not JRUBY)
5
+ - Have jruby on your path so dubyc can run.
6
+
7
+ Datastore API:
8
+ Model.get(key)
9
+ Model.delete(key)
10
+ Model.all -> Query
11
+ property foo, String # or any supported datastore type
12
+ # For numbers use Long or Double
13
+
14
+ instance.save
15
+ instance.key
16
+
17
+ instance.foo
18
+ instance.foo=
19
+
20
+ Query.count
21
+ Query.run -> Model[]
22
+ Query.first -> instance || nil
23
+ Query.sort(property_name)
24
+ Query.sort(property_name, true) # descending
25
+ Query.foo('foo').bar(3) # Only return instances where foo = 'foo' and bar = 3
26
+ Query.offset(10)
27
+ Query.limit(5)
@@ -0,0 +1,7 @@
1
+ require 'appengine-rack'
2
+ require 'appengine-rack/java'
3
+
4
+ # TODO: Fill in your app id
5
+ AppEngine::Rack.app.configure(:application => '', :version => '1')
6
+
7
+ run JavaServlet.new('com.ribrdb.DubyApp')
@@ -0,0 +1,171 @@
1
+ class DatastorePlugin
2
+ @models = {}
3
+
4
+ class ModelState
5
+ include Duby::AST
6
+ attr_reader :kind, :query, :read, :save, :transformer
7
+
8
+ def initialize(transformer, klass, parent, position, ast)
9
+ @transformer = transformer
10
+ @kind = klass.name.split('.')[-1]
11
+ init_query(klass.name, parent, position, ast)
12
+ init_static(parent, ast)
13
+ init_read(parent, position, ast)
14
+ init_save(parent, position, ast)
15
+ end
16
+
17
+ def init_query(classname, parent, position, ast)
18
+ name = "#{classname}$Query"
19
+ @query = ClassDefinition.new(parent, position, name) do |classdef|
20
+ queryinit = <<-EOF
21
+ def initialize; end
22
+
23
+ def kind
24
+ "#{kind}"
25
+ end
26
+
27
+ def first
28
+ it = _prepare.asIterator
29
+ if it.hasNext
30
+ e = Entity(it.next)
31
+ m = #{kind}.new
32
+ m._read_from(e)
33
+ m
34
+ else
35
+ #{kind}(nil)
36
+ end
37
+ end
38
+
39
+ def run
40
+ entities = _prepare.asList(_options)
41
+ models = #{kind}[entities.size]
42
+ it = entities.iterator
43
+ i = 0
44
+ while (it.hasNext)
45
+ e = Entity(it.next)
46
+ m = #{kind}.new
47
+ m._read_from(e)
48
+ models[i] = m
49
+ i += 1
50
+ end
51
+ models
52
+ end
53
+ EOF
54
+ [Duby::AST.type('com.google.appengine.ext.duby.db.DQuery'),
55
+ eval(classdef, queryinit)]
56
+ end
57
+ ast.children << @query
58
+ end
59
+
60
+ def init_read(parent, position, ast)
61
+ @read = eval(parent, <<-EOF)
62
+ def _read_from(e:Entity)
63
+ end
64
+ EOF
65
+ @read.body = @read.children[2] = Body.new(@read, position) {[]}
66
+ ast.children << @read
67
+ end
68
+
69
+ def init_save(parent, position, ast)
70
+ @save = eval(parent, <<-EOF)
71
+ def _save_to(e:Entity)
72
+ end
73
+ EOF
74
+ @save.body = @save.children[2] = Body.new(@save, position) {[]}
75
+ ast.children << @save
76
+ end
77
+
78
+ def init_static(parent, ast)
79
+ ast.children << eval(parent, <<-EOF)
80
+ import com.google.appengine.api.datastore.Entity
81
+ import com.google.appengine.api.datastore.Blob
82
+ import com.google.appengine.api.datastore.Category
83
+ import com.google.appengine.api.datastore.Email
84
+ import com.google.appengine.api.datastore.GeoPt
85
+ import com.google.appengine.api.datastore.IMHandle
86
+ import com.google.appengine.api.datastore.Key
87
+ import com.google.appengine.api.datastore.Link
88
+ import com.google.appengine.api.datastore.PhoneNumber
89
+ import com.google.appengine.api.datastore.PostalAddress
90
+ import com.google.appengine.api.datastore.Rating
91
+ import com.google.appengine.api.datastore.ShortBlob
92
+ import com.google.appengine.api.datastore.Text
93
+ import '#{kind}__Query__', '#{kind}$Query'
94
+
95
+ def self.get(key:Key)
96
+ m = #{kind}.new
97
+ m._read_from(Model._datastore.get(key))
98
+ m
99
+ end
100
+
101
+ def self.all
102
+ #{kind}__Query__.new
103
+ end
104
+ EOF
105
+ end
106
+
107
+ def eval(parent, src)
108
+ ast = Duby::AST.parse_ruby(src, __FILE__)
109
+ transformer.transform(ast.body_node, parent)
110
+ end
111
+
112
+ def extend_query(code)
113
+ query.body.children << eval(query.body, code)
114
+ end
115
+
116
+ def extend_read(code)
117
+ code = 'e=nil;' + code
118
+ read.body.children.concat eval(read.body, code).children[1..-1]
119
+ end
120
+
121
+ def extend_save(code)
122
+ code = 'e=nil;' + code
123
+ save.body.children.concat eval(save.body, code).children[1..-1]
124
+ end
125
+ end
126
+
127
+ def self.find_class(node)
128
+ node = node.parent until Duby::AST::ClassDefinition === node
129
+ node
130
+ end
131
+
132
+ Duby::AST.defmacro("property") do |transformer, fcall, parent|
133
+ result = Duby::AST::Body.new(parent, fcall.position) {[]}
134
+ klass = find_class(parent)
135
+ unless @models[klass]
136
+ @models[klass] = ModelState.new(
137
+ transformer, klass, parent, fcall.position, result)
138
+ end
139
+ model = @models[klass]
140
+
141
+ name = fcall.args_node.get(0).name
142
+ type = fcall.args_node.get(1).name
143
+
144
+ model.extend_query(<<-EOF)
145
+ def #{name}(value:#{type})
146
+ returns :void
147
+ _query.addFilter("#{name}", _eq_op, value)
148
+ end
149
+ EOF
150
+
151
+ model.extend_read(<<-EOF)
152
+ @#{name} = #{type}(e.getProperty("#{name}"))
153
+ EOF
154
+
155
+ model.extend_save(<<-EOF)
156
+ e.setProperty("#{name}", @#{name})
157
+ EOF
158
+
159
+ result.children << model.eval(parent, <<-EOF)
160
+ def #{name}
161
+ @#{name}
162
+ end
163
+
164
+ def #{name}=(value:#{type})
165
+ @#{name} = value
166
+ end
167
+ EOF
168
+
169
+ result
170
+ end
171
+ end
@@ -0,0 +1,132 @@
1
+ import com.google.appengine.api.datastore.DatastoreServiceFactory
2
+ import com.google.appengine.api.datastore.Entity
3
+ import com.google.appengine.api.datastore.EntityNotFoundException
4
+ import com.google.appengine.api.datastore.Key
5
+ import com.google.appengine.api.datastore.KeyFactory
6
+ import com.google.appengine.api.datastore.Query
7
+ import 'Builder', 'com.google.appengine.api.datastore.FetchOptions$Builder'
8
+ import 'FilterOperator', 'com.google.appengine.api.datastore.Query$FilterOperator'
9
+ import 'SortDirection', 'com.google.appengine.api.datastore.Query$SortDirection'
10
+
11
+ class DQuery
12
+ def initialize
13
+ @query = Query.new(kind)
14
+ end
15
+
16
+ def kind
17
+ "foo"
18
+ end
19
+
20
+ def limit(l:int)
21
+ returns :void
22
+ if @options
23
+ @options.limit(l)
24
+ else
25
+ @options = Builder.withLimit(l)
26
+ end
27
+ end
28
+
29
+ def offset(o:int)
30
+ returns :void
31
+ if @options
32
+ @options.offset(o)
33
+ else
34
+ @options = Builder.withOffset(o)
35
+ end
36
+ end
37
+
38
+ def sort(name:String)
39
+ sort(name, false)
40
+ end
41
+
42
+ def sort(name:String, descending:boolean)
43
+ returns :void
44
+ if descending
45
+ @query.addSort(name, _desc)
46
+ else
47
+ @query.addSort(name)
48
+ end
49
+ end
50
+
51
+ def count
52
+ _prepare.countEntities
53
+ end
54
+
55
+ def _query
56
+ @query
57
+ end
58
+
59
+ def _options
60
+ if @options.nil?
61
+ @options = Builder.withOffset(0)
62
+ end
63
+ @options
64
+ end
65
+
66
+ def _prepare
67
+ Model._datastore.prepare(@query)
68
+ end
69
+
70
+ def _eq_op
71
+ FilterOperator.valueOf("EQUAL")
72
+ end
73
+
74
+ def _desc
75
+ SortDirection.valueOf("DESCENDING")
76
+ end
77
+ end
78
+
79
+ class Model
80
+ def initialize
81
+ end
82
+
83
+ def self._datastore
84
+ unless @service
85
+ @service = DatastoreServiceFactory.getDatastoreService
86
+ end
87
+ @service
88
+ end
89
+
90
+ def self.delete(key:Key)
91
+ returns :void
92
+ keys = Key[1]
93
+ keys[0] = key
94
+ Model._datastore.delete(keys)
95
+ end
96
+
97
+ def kind
98
+ getClass.getSimpleName
99
+ end
100
+
101
+ def key
102
+ if @entity
103
+ @entity.getKey
104
+ else
105
+ Key(nil)
106
+ end
107
+ end
108
+
109
+ def save
110
+ Model._datastore.put(to_entity)
111
+ end
112
+
113
+ def delete
114
+ returns :void
115
+ Model.delete(key)
116
+ end
117
+
118
+ def to_entity
119
+ unless @entity
120
+ @entity = Entity.new(kind)
121
+ end
122
+ _save_to(@entity)
123
+ @entity
124
+ end
125
+
126
+ # protected
127
+ def _save_to(e:Entity)
128
+ end
129
+
130
+ def _read_from(e:Entity)
131
+ end
132
+ end