Skip to content

Instantly share code, notes, and snippets.

@evanw
Last active November 25, 2015 17:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save evanw/7df825297d952e0f3090 to your computer and use it in GitHub Desktop.
Save evanw/7df825297d952e0f3090 to your computer and use it in GitHub Desktop.

This is a comparison of Skew (http://skew-lang.org) to Haxe (http://haxe.org). Skew is a programming language I've been working on. Haxe is a great language and ecosystem but the JavaScript code that the Haxe compiler generates isn't as good as it could be and the language itself could be better. Here's a quick list of some things that Skew is better at:

Things the Skew compiler has that Haxe doesn't:

  • Actual integers (Haxe uses doubles)
  • Automatic inlining (Haxe needs "inline" everywhere)
  • Dead code elimination (the Haxe compiler emits unused inlined getters)
  • Property minification (must manually specify minified names with @:native in Haxe)
  • Comment preservation (the Haxe compiler strips all comments from the debugging output)
  • Local constant folding (can't specify a local variable as "inline" in Haxe)
  • Smaller output (7x in this case, 2.8x with minification using uglify)

Things the Skew language has that Haxe doesn't:

  • Function overloading
  • Top-level functions
  • Much lighter syntax

Obviously Skew has a long way to go, but it's just getting started and it already generates much better JavaScript than Haxe!

# This demonstrates using type wrapping to make an efficient color API. Colors
# are stored directly as 32-bit integers and don't cause any allocations.
type Color : int {
def r int {
return (self as int) >> 16 & 255
}
def g int {
return (self as int) >> 8 & 255
}
def b int {
return (self as int) & 255
}
def a int {
return (self as int) >>> 24
}
def withAlpha(a int) Color {
return new(r, g, b, a)
}
def toString string {
return "Color(\(r), \(g), \(b), \(a))"
}
}
namespace Color {
const TRANSPARENT = new(0, 0, 0, 0)
const BLACK = new(0, 0, 0)
const WHITE = new(255, 255, 255)
const RED = hex(0xFF0000)
const GREEN = hex(0x00FF00)
const BLUE = hex(0x0000FF)
def new(r int, g int, b int) Color {
return new(r, g, b, 255)
}
def new(r int, g int, b int, a int) Color {
assert(r >= 0 && r <= 0xFF)
assert(g >= 0 && g <= 0xFF)
assert(b >= 0 && b <= 0xFF)
assert(a >= 0 && a <= 0xFF)
return (r << 16 | g << 8 | b | a << 24) as Color
}
def hex(rgb int) Color {
return hex(rgb, 255)
}
def hex(rgb int, a int) Color {
assert(rgb >= 0 && rgb <= 0xFFFFFF)
assert(a >= 0 && a <= 0xFF)
return (rgb | a << 24) as Color
}
}
# This API works well with inlining and constant folding in release mode
@entry
def test {
var red Color = .RED
var green Color = .GREEN
var yellow = Color.new(red.r, green.g, 0).withAlpha(127)
dynamic.console.log("yellow: \(yellow)")
var test = 1
for i in 0..64 {
test = test * 1103515245 + 12345
dynamic.console.log(test)
assert(test == (test | 0))
}
}
(function() {
var __imul = Math.imul ? Math.imul : function(a, b) {
var ah = a >> 16 & 65535;
var bh = b >> 16 & 65535;
var al = a & 65535;
var bl = b & 65535;
return al * bl + (ah * bl + al * bh << 16) | 0;
};
function assert(truth) {
if (!truth) {
throw Error('Assertion failed');
}
}
// This API works well with inlining and constant folding in release mode
function test() {
var red = Color.RED;
var green = Color.GREEN;
var yellow = Color.withAlpha(Color.new1(Color.r(red), Color.g(green), 0), 127);
console.log('yellow: ' + Color.toString(yellow));
var test = 1;
for (var i = 0; i < 64; i = i + 1 | 0) {
test = __imul(test, 1103515245) + 12345 | 0;
console.log(test);
assert(test == (test | 0));
}
}
// This demonstrates using type wrapping to make an efficient color API. Colors
// are stored directly as 32-bit integers and don't cause any allocations.
var Color = {};
Color.r = function(self) {
return self >> 16 & 255;
};
Color.g = function(self) {
return self >> 8 & 255;
};
Color.b = function(self) {
return self & 255;
};
Color.a = function(self) {
return self >>> 24;
};
Color.withAlpha = function(self, a) {
return Color.new2(Color.r(self), Color.g(self), Color.b(self), a);
};
Color.toString = function(self) {
return 'Color(' + Color.r(self).toString() + ', ' + Color.g(self).toString() + ', ' + Color.b(self).toString() + ', ' + Color.a(self).toString() + ')';
};
Color.new1 = function(r, g, b) {
return Color.new2(r, g, b, 255);
};
Color.new2 = function(r, g, b, a) {
assert(r >= 0 && r <= 255);
assert(g >= 0 && g <= 255);
assert(b >= 0 && b <= 255);
assert(a >= 0 && a <= 255);
return r << 16 | g << 8 | b | a << 24;
};
Color.hex1 = function(rgb) {
return Color.hex2(rgb, 255);
};
Color.hex2 = function(rgb, a) {
assert(rgb >= 0 && rgb <= 16777215);
assert(a >= 0 && a <= 255);
return rgb | a << 24;
};
Color.RED = Color.hex1(16711680);
Color.GREEN = Color.hex1(65280);
test();
})();
//# sourceMappingURL=color.sk.debug.js.map
{"version":3,"sources":["<native-js>","color.sk"],"sourcesContent":["\nconst __extends = (derived dynamic, base dynamic) => {\n derived.prototype = dynamic.Object.create(base.prototype)\n derived.prototype.constructor = derived\n}\n\nconst __imul fn(int, int) int = dynamic.Math.imul ? dynamic.Math.imul : (a, b) => {\n const ah dynamic = (a >> 16) & 65535\n const bh dynamic = (b >> 16) & 65535\n const al dynamic = a & 65535\n const bl dynamic = b & 65535\n return al * bl + ((ah * bl + al * bh) << 16) | 0\n}\n\nconst __isInt = (value dynamic) => value == (value | 0)\nconst __isBool = (value dynamic) => value == !!value\nconst __isDouble = (value dynamic) => value == +value || dynamic.isNaN(value)\nconst __isString = (value dynamic) => dynamic.typeof(value) == \"string\"\n\ndef assert(truth bool) {\n if !truth {\n throw dynamic.Error(\"Assertion failed\")\n }\n}\n\n@import\nnamespace Math {}\n\nclass double {\n def isFinite bool {\n return dynamic.isFinite(self)\n }\n\n def isNaN bool {\n return dynamic.isNaN(self)\n }\n}\n\nclass string {\n def <=>(x string) int {\n return ((x as dynamic < self) as int) - ((x as dynamic > self) as int)\n }\n\n def startsWith(text string) bool {\n return count >= text.count && slice(0, text.count) == text\n }\n\n def endsWith(text string) bool {\n return count >= text.count && slice(count - text.count) == text\n }\n\n def replaceAll(before string, after string) string {\n return after.join(self.split(before))\n }\n\n def in(value string) bool {\n return indexOf(value) != -1\n }\n\n def count int {\n return (self as dynamic).length\n }\n\n def [](index int) int {\n return (self as dynamic).charCodeAt(index)\n }\n\n def get(index int) string {\n return (self as dynamic)[index]\n }\n\n def repeat(times int) string {\n var result = \"\"\n for i in 0..times {\n result += self\n }\n return result\n }\n\n def join(parts List<string>) string {\n return (parts as dynamic).join(self)\n }\n\n def codeUnits List<int> {\n var result List<int> = []\n for i in 0..count {\n result.append(self[i])\n }\n return result\n }\n}\n\nnamespace string {\n def fromCodeUnit(codeUnit int) string {\n return dynamic.String.fromCharCode(codeUnit)\n }\n\n def fromCodeUnits(codeUnits List<int>) string {\n var result = \"\"\n for codeUnit in codeUnits {\n result += string.fromCodeUnit(codeUnit)\n }\n return result\n }\n}\n\nclass StringBuilder {\n var buffer = \"\"\n\n def new {\n }\n\n def append(x string) {\n buffer += x\n }\n\n def toString string {\n return buffer\n }\n}\n\n@rename(\"Array\")\nclass List {\n @rename(\"shift\") {\n def removeFirst\n def takeFirst T\n }\n\n @rename(\"pop\") {\n def removeLast\n def takeLast T\n }\n\n @rename(\"unshift\")\n def prepend(x T)\n\n @rename(\"push\")\n def append(x T)\n\n @rename(\"every\") if TARGET == .JAVASCRIPT\n def all(x fn(T) bool) bool\n\n @rename(\"some\") if TARGET == .JAVASCRIPT\n def any(x fn(T) bool) bool\n\n @rename(\"slice\") if TARGET == .JAVASCRIPT\n def clone List<T>\n\n @rename(\"forEach\") if TARGET == .JAVASCRIPT\n def each(x fn(T))\n\n def in(value T) bool {\n return indexOf(value) != -1\n }\n\n def isEmpty bool {\n return count == 0\n }\n\n def count int {\n return (self as dynamic).length\n }\n\n def first T {\n return self[0]\n }\n\n def last T {\n return self[count - 1]\n }\n\n def prepend(values List<T>) {\n var count = values.count\n for i in 0..count {\n prepend(values[count - i - 1])\n }\n }\n\n def append(values List<T>) {\n for value in values {\n append(value)\n }\n }\n\n def insert(index int, values List<T>) {\n for value in values {\n insert(index, value)\n index++\n }\n }\n\n def insert(index int, value T) {\n (self as dynamic).splice(index, 0, value)\n }\n\n def removeAt(x int) {\n (self as dynamic).splice(x, 1)\n }\n\n def takeAt(x int) T {\n return (self as dynamic).splice(x, 1)[0]\n }\n\n def takeRange(start int, end int) List<T> {\n return (self as dynamic).splice(start, end - start)\n }\n\n def appendOne(value T) {\n if !(value in self) {\n append(value)\n }\n }\n\n def removeOne(value T) {\n var index = indexOf(value)\n if index >= 0 {\n removeAt(index)\n }\n }\n\n def removeRange(start int, end int) {\n (self as dynamic).splice(start, end - start)\n }\n\n def removeIf(callback fn(T) bool) {\n var index = 0\n\n # Remove elements in place\n for i in 0..count {\n if !callback(self[i]) {\n if index < i {\n self[index] = self[i]\n }\n index++\n }\n }\n\n # Shrink the array to the correct size\n while index < count {\n removeLast\n }\n }\n\n def equals(other List<T>) bool {\n if count != other.count {\n return false\n }\n for i in 0..count {\n if self[i] != other[i] {\n return false\n }\n }\n return true\n }\n}\n\nnamespace List {\n def new List<T> {\n return [] as dynamic\n }\n}\n\nnamespace StringMap {\n def new StringMap<T> {\n return dynamic.Object.create(null)\n }\n}\n\nclass StringMap {\n def {...}(key string, value T) StringMap<T> {\n self[key] = value\n return self\n }\n\n def count int {\n return keys.count\n }\n\n def isEmpty bool {\n for key in self as dynamic {\n return false\n }\n return true\n }\n\n def get(key string, defaultValue T) T {\n var value = self[key]\n return value != dynamic.void(0) ? value : defaultValue # Compare against undefined so the key is only hashed once for speed\n }\n\n def keys List<string> {\n return dynamic.Object.keys(self)\n }\n\n def values List<T> {\n var values List<T> = []\n for key in self as dynamic {\n values.append(self[key])\n }\n return values\n }\n\n def clone StringMap<T> {\n var clone = new\n for key in keys {\n clone[key] = self[key]\n }\n return clone\n }\n\n def remove(key string) {\n dynamic.delete(self[key])\n }\n\n def each(x fn(string, T)) {\n for key in self as dynamic {\n x(key, self[key])\n }\n }\n}\n\nnamespace IntMap {\n def new IntMap<T> {\n return {} as dynamic\n }\n}\n\nclass IntMap {\n def {...}(key int, value T) IntMap<T> {\n self[key] = value\n return self\n }\n\n def count int {\n return values.count\n }\n\n def isEmpty bool {\n for key in self as dynamic {\n return false\n }\n return true\n }\n\n def get(key int, defaultValue T) T {\n var value = self[key]\n return value != dynamic.void(0) ? value : defaultValue # Compare against undefined so the key is only hashed once for speed\n }\n\n def keys List<int> {\n var keys List<int> = []\n for key in self as dynamic {\n keys.append(key as int)\n }\n return keys\n }\n\n def values List<T> {\n var values List<T> = []\n for key in self as dynamic {\n values.append(self[key])\n }\n return values\n }\n\n def clone IntMap<T> {\n var clone = new\n for key in keys {\n clone[key] = self[key]\n }\n return clone\n }\n\n def remove(key int) {\n dynamic.delete(self[key])\n }\n\n def each(x fn(int, T)) {\n for key in self as dynamic {\n x(key as int, self[key])\n }\n }\n}\n","# This demonstrates using type wrapping to make an efficient color API. Colors\n# are stored directly as 32-bit integers and don't cause any allocations.\ntype Color : int {\n def r int {\n return (self as int) >> 16 & 255\n }\n\n def g int {\n return (self as int) >> 8 & 255\n }\n\n def b int {\n return (self as int) & 255\n }\n\n def a int {\n return (self as int) >>> 24\n }\n\n def withAlpha(a int) Color {\n return new(r, g, b, a)\n }\n\n def toString string {\n return \"Color(\\(r), \\(g), \\(b), \\(a))\"\n }\n}\n\nnamespace Color {\n const TRANSPARENT = new(0, 0, 0, 0)\n\n const BLACK = new(0, 0, 0)\n const WHITE = new(255, 255, 255)\n\n const RED = hex(0xFF0000)\n const GREEN = hex(0x00FF00)\n const BLUE = hex(0x0000FF)\n\n def new(r int, g int, b int) Color {\n return new(r, g, b, 255)\n }\n\n def new(r int, g int, b int, a int) Color {\n assert(r >= 0 && r <= 0xFF)\n assert(g >= 0 && g <= 0xFF)\n assert(b >= 0 && b <= 0xFF)\n assert(a >= 0 && a <= 0xFF)\n return (r << 16 | g << 8 | b | a << 24) as Color\n }\n\n def hex(rgb int) Color {\n return hex(rgb, 255)\n }\n\n def hex(rgb int, a int) Color {\n assert(rgb >= 0 && rgb <= 0xFFFFFF)\n assert(a >= 0 && a <= 0xFF)\n return (rgb | a << 24) as Color\n }\n}\n\n# This API works well with inlining and constant folding in release mode\n@entry\ndef test {\n var red Color = .RED\n var green Color = .GREEN\n var yellow = Color.new(red.r, green.g, 0).withAlpha(127)\n dynamic.console.log(\"yellow: \\(yellow)\")\n\n var test = 1\n for i in 0..64 {\n test = test * 1103515245 + 12345\n dynamic.console.log(test)\n assert(test == (test | 0))\n }\n}\n"],"names":[],"mappings":";AAMM,eAA0B,YAAoB,YAAoB,SAAC,GAAG,EAAM;AAChF,aAAmB,KAAM,KAAM;AAC/B,aAAmB,KAAM,KAAM;AAC/B,aAAmB,IAAI;AACvB,aAAmB,IAAI;AACvB,WAAO,KAAK,KAAK,CAAC,KAAM,KAAK,KAAK,MAAO,MAAM;;;AAQ7C,kBAAO;AACT,QAAG,CAAC,MAAM;AACR,YAAM,MAAc;;;;AC0CpB;;AACF,cAAgB;AAChB,gBAAkB;AAClB,iBAAa,2BAAU,cAAO,gBAAS,IAAa;AACpD,gBAAoB,aAAW;AAE/B,eAAW;;AACX,iBAAS,OAAG,kBAAG;AACb,aAAO,aAAO,cAAa;AAC3B,kBAAoB;AACpB,aAAO,QAAQ,CAAC,OAAO;;;;AAvEtB;;;;AACC;AACF,WAAQ,QAAgB,KAAK;;;AAG3B;AACF,WAAQ,QAAgB,IAAI;;;AAG1B;AACF,WAAO,OAAgB;;;AAGrB;AACF,WAAO,SAAkB;;;AAGvB,mCAAU;AACZ,WAAO,WAAI,eAAG,eAAG,eAAG;;;AAGlB;AACF,WAAO,WAAS,2BAAC,OAAK,2BAAC,OAAK,2BAAC,OAAK,2BAAC;;;AAcjC,wBAAI,GAAO,GAAO;AACpB,WAAO,WAAI,GAAG,GAAG,GAAG;;;AAGlB,wBAAI,GAAO,GAAO,GAAO;AAC3B,WAAO,KAAK,KAAK,KAAK;AACtB,WAAO,KAAK,KAAK,KAAK;AACtB,WAAO,KAAK,KAAK,KAAK;AACtB,WAAO,KAAK,KAAK,KAAK;AACtB,WAAO,KAAM,KAAK,KAAK,IAAI,IAAI,KAAK;;;AAGlC,wBAAI;AACN,WAAO,WAAI,KAAK;;;AAGd,wBAAI,KAAS;AACf,WAAO,OAAO,KAAK,OAAO;AAC1B,WAAO,KAAK,KAAK,KAAK;AACtB,WAAO,MAAO,KAAK;;;AAvBf,cAAM,WAAI;AACV,gBAAQ,WAAI"}
(function(){var i=Math.imul||function(a,b){var c=a>>16&65535,f=b>>16&65535,d=a&65535,e=b&65535;return d*e+(c*e+d*f<<16)|0};function j(){var a=g(-256,127);console.log('yellow: '+h(a));for(var b=1,c=0;c<64;c=c+1|0)b=i(b,1103515245)+12345|0,console.log(b)}function g(b,a){return b&16777215|a<<24}function h(a){return 'Color('+(a>>16&255)+', '+(a>>8&255)+', '+(a&255)+', '+(a>>>24)+')'}j()})();
class Assert {
public static inline function assert(truth: Bool) {
if (!truth) {
trace('assert failed');
}
}
}
// This demonstrates using type wrapping to make an efficient color API. Colors
// are stored directly as 32-bit integers and don't cause any allocations.
abstract Color(Int) {
public var r(get, never): Int;
public var g(get, never): Int;
public var b(get, never): Int;
public var a(get, never): Int;
public inline function get_r(): Int {
return cast(this >> 16 & 255);
}
public inline function get_g(): Int {
return cast(this >> 8 & 255);
}
public inline function get_b(): Int {
return cast(this & 255);
}
public inline function get_a(): Int {
return cast(this >>> 24);
}
public inline function withAlpha(a: Int): Color {
return createRGBA(r, g, b, a);
}
public inline function toString(): String {
return 'Color($r, $g, $b, $a)';
}
public static inline function createRGB(r: Int, g: Int, b: Int): Color {
return createRGBA(r, g, b, 255);
}
public static inline function createRGBA(r: Int, g: Int, b: Int, a: Int): Color {
Assert.assert(r >= 0 && r <= 0xFF);
Assert.assert(g >= 0 && g <= 0xFF);
Assert.assert(b >= 0 && b <= 0xFF);
Assert.assert(a >= 0 && a <= 0xFF);
return cast(r << 16 | g << 8 | b | a << 24);
}
public static inline function hexRGB(rgb: Int): Color {
return hexRGBA(rgb, 255);
}
public static inline function hexRGBA(rgb: Int, a: Int): Color {
Assert.assert(rgb >= 0 && rgb <= 0xFFFFFF);
Assert.assert(a >= 0 && a <= 0xFF);
return cast(rgb | a << 24);
}
public static inline var TRANSPARENT = createRGBA(0, 0, 0, 0);
public static inline var BLACK = createRGB(0, 0, 0);
public static inline var WHITE = createRGB(255, 255, 255);
public static inline var RED = hexRGB(0xFF0000);
public static inline var GREEN = hexRGB(0x00FF00);
public static inline var BLUE = hexRGB(0x0000FF);
}
// This API works well with inlining and constant folding in release mode
class Main {
public static function main(): Void {
var red = Color.RED;
var green = Color.GREEN;
var yellow = Color.createRGB(red.r, green.g, 0).withAlpha(127);
untyped console.log('yellow: $yellow');
var test: Int = 1;
for (i in 0...64) {
test = test * 1103515245 + 12345;
untyped console.log(test);
Assert.assert(test == (test | 0));
}
}
}
(function (console) { "use strict";
var Assert = function() { };
Assert.assert = function(truth) {
if(!truth) console.log("assert failed");
};
var _$Main_Color_$Impl_$ = {};
_$Main_Color_$Impl_$.get_r = function(this1) {
return this1 >> 16 & 255;
};
_$Main_Color_$Impl_$.get_g = function(this1) {
return this1 >> 8 & 255;
};
_$Main_Color_$Impl_$.get_b = function(this1) {
return this1 & 255;
};
_$Main_Color_$Impl_$.get_a = function(this1) {
return this1 >>> 24;
};
_$Main_Color_$Impl_$.withAlpha = function(this1,a) {
var r = this1 >> 16 & 255;
var g = this1 >> 8 & 255;
var b = this1 & 255;
if(!(r >= 0 && r <= 255)) console.log("assert failed");
if(!(g >= 0 && g <= 255)) console.log("assert failed");
if(!(b >= 0 && b <= 255)) console.log("assert failed");
if(!(a >= 0 && a <= 255)) console.log("assert failed");
return r << 16 | g << 8 | b | a << 24;
};
_$Main_Color_$Impl_$.toString = function(this1) {
return "Color(" + (this1 >> 16 & 255) + ", " + (this1 >> 8 & 255) + ", " + (this1 & 255) + ", " + (this1 >>> 24) + ")";
};
_$Main_Color_$Impl_$.createRGB = function(r,g,b) {
if(!(r >= 0 && r <= 255)) console.log("assert failed");
if(!(g >= 0 && g <= 255)) console.log("assert failed");
if(!(b >= 0 && b <= 255)) console.log("assert failed");
return r << 16 | g << 8 | b | -16777216;
};
_$Main_Color_$Impl_$.createRGBA = function(r,g,b,a) {
if(!(r >= 0 && r <= 255)) console.log("assert failed");
if(!(g >= 0 && g <= 255)) console.log("assert failed");
if(!(b >= 0 && b <= 255)) console.log("assert failed");
if(!(a >= 0 && a <= 255)) console.log("assert failed");
return r << 16 | g << 8 | b | a << 24;
};
_$Main_Color_$Impl_$.hexRGB = function(rgb) {
if(!(rgb >= 0 && rgb <= 16777215)) console.log("assert failed");
return rgb | -16777216;
};
_$Main_Color_$Impl_$.hexRGBA = function(rgb,a) {
if(!(rgb >= 0 && rgb <= 16777215)) console.log("assert failed");
if(!(a >= 0 && a <= 255)) console.log("assert failed");
return rgb | a << 24;
};
var Main = function() { };
Main.main = function() {
var red = -65536;
var green = -16711936;
var yellow;
var this1;
var r = red >> 16 & 255;
var g = green >> 8 & 255;
if(!(r >= 0 && r <= 255)) console.log("assert failed");
if(!(g >= 0 && g <= 255)) console.log("assert failed");
this1 = r << 16 | g << 8 | 0 | -16777216;
var r1 = this1 >> 16 & 255;
var g1 = this1 >> 8 & 255;
var b = this1 & 255;
if(!(r1 >= 0 && r1 <= 255)) console.log("assert failed");
if(!(g1 >= 0 && g1 <= 255)) console.log("assert failed");
if(!(b >= 0 && b <= 255)) console.log("assert failed");
yellow = r1 << 16 | g1 << 8 | b | 2130706432;
console.log("yellow: " + ("Color(" + (yellow >> 16 & 255) + ", " + (yellow >> 8 & 255) + ", " + (yellow & 255) + ", " + (yellow >>> 24) + ")"));
var test = 1;
var _g = 0;
while(_g < 64) {
var i = _g++;
test = test * 1103515245 + 12345;
console.log(test);
if(!(test == (test | 0))) console.log("assert failed");
}
};
_$Main_Color_$Impl_$.TRANSPARENT = 0;
_$Main_Color_$Impl_$.BLACK = -16777216;
_$Main_Color_$Impl_$.WHITE = -1;
_$Main_Color_$Impl_$.RED = -65536;
_$Main_Color_$Impl_$.GREEN = -16711936;
_$Main_Color_$Impl_$.BLUE = -16776961;
Main.main();
})(typeof console != "undefined" ? console : {log:function(){}});
//# sourceMappingURL=Main.hx.debug.js.map
{
"version":3,
"file":"Main.hx.debug.js",
"sourceRoot":"file:///",
"sources":["/Users/evan/7df825297d952e0f3090/Main.hx"],
"names":[],
"mappings":";;gBACsB,AACnB;EAAI,DAAC,AACH,WAAO;;;6BAaG,bACZ;OAAO,AAAI,AAAC,HAAQ,DAAK;;6BAGb,bACZ;OAAO,AAAI,AAAC,HAAQ,DAAI;;6BAGZ,bACZ;OAAO,AAAI,AAAC,JAAO;;6BAGP,bACZ;OAAO,AAAI,AAAC,FAAS;;iCAGT,fACZ;CAAkB;CAAG;CAAG;CAAjB;;;CAAoB,GAApB,AAAoB,AAApB;CAAP,MAAO,JAAoB,CAApB;;gCAGK,hBACZ;OAAQ,JAAO,AAAC,AAAG,AAAC,AAAG,AAAC,AAAG,AAAC;;iCAGT,jBACnB;CAAO,AAAW,GAAX,AAAW,AAAX;CAAc,GAAd,AAAc,AAAd;CAAiB,GAAjB,AAAiB,AAAjB;CAAP,MAAO,AAAW,HAAX,DAAc,CAAd,DAAiB,AAAjB;;kCAGY,hBAA2D;CAC9E,AAAc,GAAK,AAAK,AAAK,HAA7B;CACA,AAAc,GAAK,AAAK,AAAK,HAA7B;CACA,AAAc,GAAK,AAAK,AAAK,HAA7B;CACA,AAAc,GAAK,AAAK,AAAK,HAA7B;CACA,MAAO,AAAI,AAAC,HAAK,DAAK,CAAK,DAAI,AAAI,CAAK;;8BAGrB,hBACnB;CAAO,AAAQ,GAAR,AAAQ,AAAR;CAAP,MAAO,AAAQ,JAAR;;+BAGY,fAA0C;CAC7D,AAAc,GAAO,AAAK,AAAO,HAAjC;CACA,AAAc,GAAK,AAAK,AAAK,HAA7B;CACA,MAAO,AAAI,AAAC,JAAM,CAAK;;;YAeX,DAAsB;CACxB;CACE;CACC;;CAAgB;CAAO;CAAvB;;GAAgC,AAAhC;;;;;;;;CACL,AAAa,EAAS;CAEd;CACN;CAAV,EAAc,FAAI;EAAlB;EACE,CAAO,AAAO,AAAa;EACnB,DAAY;EACpB,DAAc,GAAQ,HAAC,EAAO,FAA9B;;;mCAtBmC;6BAEN;6BACA;2BAEF;6BACE;4BACD;;;;"
}
(function (console) { "use strict";
var Assert = function() { };
Assert.assert = function(truth) {
if(!truth) null;
};
var _$Main_Color_$Impl_$ = {};
_$Main_Color_$Impl_$.get_r = function(this1) {
return this1 >> 16 & 255;
};
_$Main_Color_$Impl_$.get_g = function(this1) {
return this1 >> 8 & 255;
};
_$Main_Color_$Impl_$.get_b = function(this1) {
return this1 & 255;
};
_$Main_Color_$Impl_$.get_a = function(this1) {
return this1 >>> 24;
};
_$Main_Color_$Impl_$.withAlpha = function(this1,a) {
var r = this1 >> 16 & 255;
var g = this1 >> 8 & 255;
var b = this1 & 255;
if(!(r >= 0 && r <= 255)) null;
if(!(g >= 0 && g <= 255)) null;
if(!(b >= 0 && b <= 255)) null;
if(!(a >= 0 && a <= 255)) null;
return r << 16 | g << 8 | b | a << 24;
};
_$Main_Color_$Impl_$.toString = function(this1) {
return "Color(" + (this1 >> 16 & 255) + ", " + (this1 >> 8 & 255) + ", " + (this1 & 255) + ", " + (this1 >>> 24) + ")";
};
_$Main_Color_$Impl_$.createRGB = function(r,g,b) {
if(!(r >= 0 && r <= 255)) null;
if(!(g >= 0 && g <= 255)) null;
if(!(b >= 0 && b <= 255)) null;
return r << 16 | g << 8 | b | -16777216;
};
_$Main_Color_$Impl_$.createRGBA = function(r,g,b,a) {
if(!(r >= 0 && r <= 255)) null;
if(!(g >= 0 && g <= 255)) null;
if(!(b >= 0 && b <= 255)) null;
if(!(a >= 0 && a <= 255)) null;
return r << 16 | g << 8 | b | a << 24;
};
_$Main_Color_$Impl_$.hexRGB = function(rgb) {
if(!(rgb >= 0 && rgb <= 16777215)) null;
return rgb | -16777216;
};
_$Main_Color_$Impl_$.hexRGBA = function(rgb,a) {
if(!(rgb >= 0 && rgb <= 16777215)) null;
if(!(a >= 0 && a <= 255)) null;
return rgb | a << 24;
};
var Main = function() { };
Main.main = function() {
var red = -65536;
var green = -16711936;
var yellow;
var this1;
var r = red >> 16 & 255;
var g = green >> 8 & 255;
if(!(r >= 0 && r <= 255)) null;
if(!(g >= 0 && g <= 255)) null;
this1 = r << 16 | g << 8 | 0 | -16777216;
var r1 = this1 >> 16 & 255;
var g1 = this1 >> 8 & 255;
var b = this1 & 255;
if(!(r1 >= 0 && r1 <= 255)) null;
if(!(g1 >= 0 && g1 <= 255)) null;
if(!(b >= 0 && b <= 255)) null;
yellow = r1 << 16 | g1 << 8 | b | 2130706432;
console.log("yellow: " + ("Color(" + (yellow >> 16 & 255) + ", " + (yellow >> 8 & 255) + ", " + (yellow & 255) + ", " + (yellow >>> 24) + ")"));
var test = 1;
var _g = 0;
while(_g < 64) {
var i = _g++;
test = test * 1103515245 + 12345;
console.log(test);
if(!(test == (test | 0))) null;
}
};
_$Main_Color_$Impl_$.TRANSPARENT = 0;
_$Main_Color_$Impl_$.BLACK = -16777216;
_$Main_Color_$Impl_$.WHITE = -1;
_$Main_Color_$Impl_$.RED = -65536;
_$Main_Color_$Impl_$.GREEN = -16711936;
_$Main_Color_$Impl_$.BLUE = -16776961;
Main.main();
})(typeof console != "undefined" ? console : {log:function(){}});
!function(n){"use strict";var t=function(){};t.assert=function(n){};var r={};r.get_r=function(n){return n>>16&255},r.get_g=function(n){return n>>8&255},r.get_b=function(n){return 255&n},r.get_a=function(n){return n>>>24},r.withAlpha=function(n,t){var r=n>>16&255,o=n>>8&255,e=255&n;return r<<16|o<<8|e|t<<24},r.toString=function(n){return"Color("+(n>>16&255)+", "+(n>>8&255)+", "+(255&n)+", "+(n>>>24)+")"},r.createRGB=function(n,t,r){return n<<16|t<<8|r|-16777216},r.createRGBA=function(n,t,r,o){return n<<16|t<<8|r|o<<24},r.hexRGB=function(n){return-16777216|n},r.hexRGBA=function(n,t){return n|t<<24};var o=function(){};o.main=function(){var t,r,o=-65536,e=-16711936,u=o>>16&255,i=e>>8&255;r=u<<16|i<<8|0|-16777216;var c=r>>16&255,f=r>>8&255,a=255&r;t=c<<16|f<<8|a|2130706432,n.log("yellow: "+("Color("+(t>>16&255)+", "+(t>>8&255)+", "+(255&t)+", "+(t>>>24)+")"));for(var l=1,g=0;64>g;){g++;l=1103515245*l+12345,n.log(l)}},r.TRANSPARENT=0,r.BLACK=-16777216,r.WHITE=-1,r.RED=-65536,r.GREEN=-16711936,r.BLUE=-16776961,o.main()}("undefined"!=typeof console?console:{log:function(){}});
build:
skewc color.sk --output-file=color.sk.debug.js --target=js --js-source-map
skewc color.sk --output-file=color.sk.release.js --target=js --release
haxe -main Main -js Main.hx.debug.js -debug
haxe -main Main -js Main.hx.release.js --no-traces
test -e node_modules || npm install
node_modules/.bin/uglifyjs Main.hx.release.js --screw-ie8 --compress --mangle > Main.hx.release.min.js
{
"dependencies": {
"uglify-js": "2.6.1"
}
}
@mems
Copy link

mems commented Nov 24, 2015

Your review need few adjustments (I only scratch the surface, I'm not an Haxe expert):
To transpile Haxe and remove dead code of inlining use -dce full
http://try.haxe.org/#8B6d9 + https://marijnhaverbeke.nl/uglifyjs now give 751 chars.
Also be careful, the output of Skew release don't have "strict mode", and asserts() are removed. That means the result is not compatible (and Haxe provide a "fallback" to console.log).

@mrcdk
Copy link

mrcdk commented Nov 25, 2015

I forked this gist and updated the Haxe files adding dce and enabling the static analyzer. And also actual integers. https://gist.github.com/mrcdk/f76bb65c5e04a9a5355c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment