Hello, Dart World!
Posted on 12月 13th, 2011 by cx20
Dart
Dart は Google によって開発された Web 向けのプログラミング言語である。JavaScript の代替を目的に作られており Dart の仮想マシンを Chrome に統合することが計画されている。
プログラムは Dart のオフィシャルサイト(http://www.dartlang.org/)にて試すことができる。
ソースコード(Dart)
main() { print( 'Hello, Dart World!' ); } |
上記コードを、JavaScript コンパイラ「Frog」でコンパイルすることで、以下のコードを生成する。
ソースコード(JavaScript)
// ********** Library dart:core ************** // ********** Natives dart:core ************** function $defProp(obj, prop, value) { Object.defineProperty(obj, prop, {value: value, enumerable: false, writable: true, configurable: true}); } function $throw(e) { // If e is not a value, we can use V8's captureStackTrace utility method. // TODO(jmesserly): capture the stack trace on other JS engines. if (e && (typeof e == 'object') && Error.captureStackTrace) { // TODO(jmesserly): this will clobber the e.stack property Error.captureStackTrace(e, $throw); } throw e; } $defProp(Object.prototype, '$index', function(i) { $throw(new NoSuchMethodException(this, "operator []", [i])); }); $defProp(Array.prototype, '$index', function(index) { var i = index | 0; if (i !== index) { throw new IllegalArgumentException('index is not int'); } else if (i < 0 || i >= this.length) { throw new IndexOutOfRangeException(index); } return this[i]; }); $defProp(String.prototype, '$index', function(i) { return this[i]; }); function $$add$complex(x, y) { if (typeof(x) == 'number') { $throw(new IllegalArgumentException(y)); } else if (typeof(x) == 'string') { var str = (y == null) ? 'null' : y.toString(); if (typeof(str) != 'string') { throw new Error("calling toString() on right hand operand of operator " + "+ did not return a String"); } return x + str; } else if (typeof(x) == 'object') { return x.$add(y); } else { $throw(new NoSuchMethodException(x, "operator +", [y])); } } function $$add(x, y) { if (typeof(x) == 'number' && typeof(y) == 'number') return x + y; return $$add$complex(x, y); } function $$eq(x, y) { if (x == null) return y == null; return (typeof(x) != 'object') ? x === y : x.$eq(y); } // TODO(jimhug): Should this or should it not match equals? $defProp(Object.prototype, '$eq', function(other) { return this === other; }); // ********** Code for Object ************** $defProp(Object.prototype, "is$Collection", function() { return false; }); $defProp(Object.prototype, "is$List", function() { return false; }); $defProp(Object.prototype, "is$Map", function() { return false; }); // ********** Code for IndexOutOfRangeException ************** function IndexOutOfRangeException(_index) { this._index = _index; } IndexOutOfRangeException.prototype.is$IndexOutOfRangeException = function(){return true}; IndexOutOfRangeException.prototype.toString = function() { return ("IndexOutOfRangeException: " + this._index); } // ********** Code for NoSuchMethodException ************** function NoSuchMethodException(_receiver, _functionName, _arguments, _existingArgumentNames) { this._receiver = _receiver; this._functionName = _functionName; this._arguments = _arguments; this._existingArgumentNames = _existingArgumentNames; } NoSuchMethodException.prototype.is$NoSuchMethodException = function(){return true}; NoSuchMethodException.prototype.toString = function() { var sb = new StringBufferImpl(""); for (var i = (0); i < this._arguments.get$length(); i++) { if (i > (0)) { sb.add(", "); } sb.add(this._arguments.$index(i)); } if (null == this._existingArgumentNames) { return $$add($$add(("NoSuchMethodException : method not found: '" + this._functionName + "'n"), ("Receiver: " + this._receiver + "n")), ("Arguments: [" + sb + "]")); } else { var actualParameters = sb.toString(); sb = new StringBufferImpl(""); for (var i = (0); i < this._existingArgumentNames.get$length(); i++) { if (i > (0)) { sb.add(", "); } sb.add(this._existingArgumentNames.$index(i)); } var formalParameters = sb.toString(); return $$add($$add($$add("NoSuchMethodException: incorrect number of arguments passed to ", ("method named '" + this._functionName + "'nReceiver: " + this._receiver + "n")), ("Tried calling: " + this._functionName + "(" + actualParameters + ")n")), ("Found: " + this._functionName + "(" + formalParameters + ")")); } } // ********** Code for ClosureArgumentMismatchException ************** function ClosureArgumentMismatchException() { } ClosureArgumentMismatchException.prototype.toString = function() { return "Closure argument mismatch"; } // ********** Code for IllegalArgumentException ************** function IllegalArgumentException(arg) { this._arg = arg; } IllegalArgumentException.prototype.is$IllegalArgumentException = function(){return true}; IllegalArgumentException.prototype.toString = function() { return ("Illegal argument(s): " + this._arg); } // ********** Code for NoMoreElementsException ************** function NoMoreElementsException() { } NoMoreElementsException.prototype.toString = function() { return "NoMoreElementsException"; } // ********** Code for dart_core_Function ************** Function.prototype.to$call$0 = function() { this.call$0 = this._genStub(0); this.to$call$0 = function() { return this.call$0; }; return this.call$0; }; Function.prototype.call$0 = function() { return this.to$call$0()(); }; function to$call$0(f) { return f && f.to$call$0(); } Function.prototype.to$call$1 = function() { this.call$1 = this._genStub(1); this.to$call$1 = function() { return this.call$1; }; return this.call$1; }; Function.prototype.call$1 = function($0) { return this.to$call$1()($0); }; function to$call$1(f) { return f && f.to$call$1(); } Function.prototype.to$call$2 = function() { this.call$2 = this._genStub(2); this.to$call$2 = function() { return this.call$2; }; return this.call$2; }; Function.prototype.call$2 = function($0, $1) { return this.to$call$2()($0, $1); }; function to$call$2(f) { return f && f.to$call$2(); } // ********** Code for top level ************** function print(obj) { return _print(obj); } function _print(obj) { if (typeof console == 'object') { if (obj) obj = obj.toString(); console.log(obj); } else if (typeof write === 'function') { write(obj); write('n'); } } // ********** Library dart:coreimpl ************** // ********** Code for ListFactory ************** ListFactory = Array; $defProp(ListFactory.prototype, "is$List", function(){return true}); $defProp(ListFactory.prototype, "is$Collection", function(){return true}); $defProp(ListFactory.prototype, "get$length", function() { return this.length; }); $defProp(ListFactory.prototype, "set$length", function(value) { return this.length = value; }); $defProp(ListFactory.prototype, "add", function(value) { this.push(value); }); $defProp(ListFactory.prototype, "clear", function() { this.set$length((0)); }); $defProp(ListFactory.prototype, "removeLast", function() { return this.pop(); }); $defProp(ListFactory.prototype, "iterator", function() { return new ListIterator(this); }); $defProp(ListFactory.prototype, "toString", function() { return Collections.collectionToString(this); }); // ********** Code for ListIterator ************** function ListIterator(array) { this._array = array; this._pos = (0); } ListIterator.prototype.hasNext = function() { return this._array.get$length() > this._pos; } ListIterator.prototype.next = function() { if (!this.hasNext()) { $throw(const$0000); } return this._array.$index(this._pos++); } // ********** Code for NumImplementation ************** NumImplementation = Number; // ********** Code for Collections ************** function Collections() {} Collections.collectionToString = function(c) { var result = new StringBufferImpl(""); Collections._emitCollection(c, result, new Array()); return result.toString(); } Collections._emitCollection = function(c, result, visiting) { visiting.add(c); var isList = !!(c && c.is$List()); result.add(isList ? "[" : "{"); var first = true; for (var $$i = c.iterator(); $$i.hasNext(); ) { var e = $$i.next(); if (!first) { result.add(", "); } first = false; Collections._emitObject(e, result, visiting); } result.add(isList ? "]" : "}"); visiting.removeLast(); } Collections._emitObject = function(o, result, visiting) { if (!!(o && o.is$Collection())) { if (Collections._containsRef(visiting, o)) { result.add(!!(o && o.is$List()) ? "[...]" : "{...}"); } else { Collections._emitCollection(o, result, visiting); } } else if (!!(o && o.is$Map())) { if (Collections._containsRef(visiting, o)) { result.add("{...}"); } else { Maps._emitMap(o, result, visiting); } } else { result.add($$eq(o) ? "null" : o); } } Collections._containsRef = function(c, ref) { for (var $$i = c.iterator(); $$i.hasNext(); ) { var e = $$i.next(); if ((null == e ? null == (ref) : e === ref)) return true; } return false; } // ********** Code for HashMapImplementation ************** function HashMapImplementation() {} HashMapImplementation.prototype.is$Map = function(){return true}; HashMapImplementation.prototype.forEach = function(f) { var length = this._keys.get$length(); for (var i = (0); i < length; i++) { var key = this._keys.$index(i); if ((null != key) && ((null == key ? null != (const$0001) : key !== const$0001))) { f(key, this._values.$index(i)); } } } HashMapImplementation.prototype.toString = function() { return Maps.mapToString(this); } // ********** Code for _DeletedKeySentinel ************** function _DeletedKeySentinel() { } // ********** Code for Maps ************** function Maps() {} Maps.mapToString = function(m) { var result = new StringBufferImpl(""); Maps._emitMap(m, result, new Array()); return result.toString(); } Maps._emitMap = function(m, result, visiting) { visiting.add(m); result.add("{"); var first = true; m.forEach((function (k, v) { if (!first) { result.add(", "); } first = false; Collections._emitObject(k, result, visiting); result.add(": "); Collections._emitObject(v, result, visiting); }) ); result.add("}"); visiting.removeLast(); } // ********** Code for DoubleLinkedQueue ************** function DoubleLinkedQueue() {} DoubleLinkedQueue.prototype.is$Collection = function(){return true}; DoubleLinkedQueue.prototype.iterator = function() { return new _DoubleLinkedQueueIterator(this._sentinel); } DoubleLinkedQueue.prototype.toString = function() { return Collections.collectionToString(this); } // ********** Code for _DoubleLinkedQueueIterator ************** function _DoubleLinkedQueueIterator(_sentinel) { this._sentinel = _sentinel; this._currentEntry = this._sentinel; } _DoubleLinkedQueueIterator.prototype.hasNext = function() { var $0; return (($0 = this._currentEntry._next) == null ? null != (this._sentinel) : $0 !== this._sentinel); } _DoubleLinkedQueueIterator.prototype.next = function() { if (!this.hasNext()) { $throw(const$0000); } this._currentEntry = this._currentEntry._next; return this._currentEntry.get$element(); } // ********** Code for StringBufferImpl ************** function StringBufferImpl(content) { this.clear(); this.add(content); } StringBufferImpl.prototype.add = function(obj) { var str = obj.toString(); if (null == str || str.isEmpty()) return this; this._buffer.add(str); this._length = this._length + str.length; return this; } StringBufferImpl.prototype.clear = function() { this._buffer = new Array(); this._length = (0); return this; } StringBufferImpl.prototype.toString = function() { if (this._buffer.get$length() == (0)) return ""; if (this._buffer.get$length() == (1)) return this._buffer.$index((0)); var result = StringBase.concatAll(this._buffer); this._buffer.clear(); this._buffer.add(result); return result; } // ********** Code for StringBase ************** function StringBase() {} StringBase.join = function(strings, separator) { if (strings.get$length() == (0)) return ""; var s = strings.$index((0)); for (var i = (1); i < strings.get$length(); i++) { s = $$add($$add(s, separator), strings.$index(i)); } return s; } StringBase.concatAll = function(strings) { return StringBase.join(strings, ""); } // ********** Code for StringImplementation ************** StringImplementation = String; StringImplementation.prototype.isEmpty = function() { return this.length == (0); } // ********** Code for _Worker ************** // ********** Code for _ArgumentMismatchException ************** /** Implements extends for Dart classes on JavaScript prototypes. */ function $inherits(child, parent) { if (child.prototype.__proto__) { child.prototype.__proto__ = parent.prototype; } else { function tmp() {}; tmp.prototype = parent.prototype; child.prototype = new tmp(); child.prototype.constructor = child; } } $inherits(_ArgumentMismatchException, ClosureArgumentMismatchException); function _ArgumentMismatchException(_message) { this._dart_coreimpl_message = _message; ClosureArgumentMismatchException.call(this); } _ArgumentMismatchException.prototype.toString = function() { return ("Closure argument mismatch: " + this._dart_coreimpl_message); } // ********** Code for _FunctionImplementation ************** _FunctionImplementation = Function; _FunctionImplementation.prototype._genStub = function(argsLength, names) { // Fast path #1: if no named arguments and arg count matches if (this.length == argsLength && !names) { return this; } var paramsNamed = this.$optional ? (this.$optional.length / 2) : 0; var paramsBare = this.length - paramsNamed; var argsNamed = names ? names.length : 0; var argsBare = argsLength - argsNamed; // Check we got the right number of arguments if (argsBare < paramsBare || argsLength > this.length || argsNamed > paramsNamed) { return function() { $throw(new _ArgumentMismatchException( 'Wrong number of arguments to function. Expected ' + paramsBare + ' positional arguments and at most ' + paramsNamed + ' named arguments, but got ' + argsBare + ' positional arguments and ' + argsNamed + ' named arguments.')); }; } // First, fill in all of the default values var p = new Array(paramsBare); if (paramsNamed) { p = p.concat(this.$optional.slice(paramsNamed)); } // Fill in positional args var a = new Array(argsLength); for (var i = 0; i < argsBare; i++) { p[i] = a[i] = '$' + i; } // Then overwrite with supplied values for optional args var lastParameterIndex; var namesInOrder = true; for (var i = 0; i < argsNamed; i++) { var name = names[i]; a[i + argsBare] = name; var j = this.$optional.indexOf(name); if (j < 0 || j >= paramsNamed) { return function() { $throw(new _ArgumentMismatchException( 'Named argument "' + name + '" was not expected by function.' + ' Did you forget to mark the function parameter [optional]?')); }; } else if (lastParameterIndex && lastParameterIndex > j) { namesInOrder = false; } p[j + paramsBare] = name; lastParameterIndex = j; } if (this.length == argsLength && namesInOrder) { // Fast path #2: named arguments, but they're in order and all supplied. return this; } // Note: using Function instead of 'eval' to get a clean scope. // TODO(jmesserly): evaluate the performance of these stubs. var f = 'function(' + a.join(',') + '){return $f(' + p.join(',') + ');}'; return new Function('$f', 'return ' + f + '').call(null, this); } // ********** Code for top level ************** // ********** Library hello ************** // ********** Code for top level ************** function main() { print("Hello, Dart World!"); } // ********** Globals ************** function $static_init(){ } var const$0000 = Object.create(NoMoreElementsException.prototype, {}); var const$0001 = Object.create(_DeletedKeySentinel.prototype, {}); $static_init(); main(); |
実行方法(JavaScript にコンパイルして実行)
$ frogc hello.dart $ node hello.dart.js
実行方法(Dart VM にて実行)
$ dart hello.dart |
実行結果
Hello, Dart World! |
Tags: Dart
Categories: Dart, JavaScript