diff --git a/Slang/slang.html b/Slang/slang.html
new file mode 100755
index 0000000..e69dd24
--- /dev/null
+++ b/Slang/slang.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/Slang/slang.js b/Slang/slang.js
new file mode 100755
index 0000000..4ad3f76
--- /dev/null
+++ b/Slang/slang.js
@@ -0,0 +1,504 @@
+/**********************************************************************
+* 
+*
+*
+**********************************************************************/
+
+
+/*********************************************************************/
+
+function run(context){
+
+	var stack = context.stack
+	stack = stack == null ? [] : stack
+	context.stack = stack
+
+	var ns = context.ns
+
+	while(context.code.length > 0){
+
+		var cur = context.code.splice(0, 1)[0]
+
+		// exit...
+		if(typeof(cur) == typeof('abc') && cur == '_exit'){
+			return context
+
+		// word
+		} else if(typeof(cur) == typeof('abc') && cur in ns){
+			var word = ns[cur]
+			// low-level word...
+			if(typeof(word) == typeof(function(){})){
+				var res = ns[cur](context)
+
+			// hi-level word...
+			} else if(typeof(word) == typeof([]) && word.constructor.name == 'Array'){
+				// XXX add isolation with a continuation...
+				context.code.splice.apply(context.code, [0, 0].concat(word))
+				var res = null
+
+			// variable...
+			} else {
+				res = word
+			}
+
+			if(res != null){
+				context.stack.push(res)
+			}
+
+		// everything else...
+		} else {
+			context.stack.push(cur)
+		}
+	}
+
+	return context
+}
+
+var SPLITTER = /\s*\([^\)]*\)\s*|\s*--.*[\n$]|\s*(".*")\s*|\s*('.*')\s*|\s+/m
+
+
+// pre-processor namespace...
+var PRE_NAMESPACE = {
+	// XXX use the real reader...
+	// block...
+	// syntax: [ ... ]
+	'[': function(context){
+		var block = []
+		var code = context.code
+		var cur = code.splice(0, 1)[0]
+		while(cur != ']' && code.length > 0){
+			if(cur == '['){
+				cur = this['['](context)
+			}
+			block.push(cur)
+			cur = code.splice(0, 1)[0]
+		}
+		if(code.length == 0 && cur != ']'){
+			console.error('Did not find expected "]".')
+		} 
+		return block
+	},
+	'macro:': function(context){
+		var ident = context.code.splice(0, 1)
+		var cur = context.code.splice(0, 1)
+
+		// as we do not have blocks yet we need to manually collect one ;)
+		if(cur[0] == '['){
+			cur = [ this['['](context) ]
+		}
+
+		this[ident] = cur[0]
+	},
+}
+
+
+// main namespace...
+var NAMESPACE = {
+	// constants...
+	'true': true,
+	'false': false,
+	// this is mutable, so we'll need to create a new instance each time
+	'[]': function(){ return [] }, 
+
+	'nop': function(){}, 
+
+	// XXX experimental...
+	// flip the code and stack...
+	// ... -- ...
+	'_flip': function(context){
+		var stack = context.stack
+		context.stack = context.code.reverse()
+		context.code = stack.reverse()
+	},
+
+	// swap heads of stack and code
+	// ... ns nc -- ...
+	'_swapN': function(context){ 
+		var c = context.stack.pop()
+		var s = context.stack.pop()
+		var l = context.stack.length
+
+		// get the stack/code sections to swap...
+		var s_c = context.stack.splice(l-s, l)
+		var c_c = context.code.splice(0, c)
+		var l = context.stack.length
+
+		// we need to pad e_c and c_c to requested length...
+		s_c = s_c.length < s ? s_c.concat(Array( s - s_c.length )) : s_c
+		c_c = c_c.length < c ? c_c.concat(Array( c - c_c.length )) : c_c
+
+		// XXX we also need to shove something more sensible in the 
+		// 		padding that undefined...
+
+		context.code.splice.apply(context.code, [0, 0].concat(s_c))
+		context.stack.splice.apply(context.stack, [l, 0].concat(c_c))
+	},
+
+	// encapsulate stack to a block...
+	// ... -- [ ... ]
+	's2b': function(context){
+		context.stack = [ context.stack ]
+	},
+	// expand block to stack... 
+	// NOTE: this will append the block contents to stack, w.o. replacing 
+	// 		stack contents. this is different to _s2b
+	// ... [ ... ] -- ... ...
+	'b2s': function(context){
+		var c = context.stack.pop()
+		context.stack.splice.apply(context.stack, [context.stack.length, 0].concat(c))
+	},
+	'print': function(context){
+		console.log('>>>', context.stack[context.stack.length-1])
+	},
+
+	// turn a sting into a lexical list...
+	// c -- b
+	// XXX BUG see code...
+	'lex': function(context){
+		code = context.stack.pop()
+		if(typeof(code) == typeof('abc')){
+			// XXX BUG: '"aaa" "bbb"' translates to ['"aaa"', '" "', '"bbb"'] 
+			// 		i.e. quotes w/o whitespace are eaten...
+			if(/^(['"]).*\1$/m.test(code)){
+				code = code.split(/^(['"])(.*)\1$/m)[2]
+			}
+			var res = []
+			code = code
+				// split by strings whitespace and block comments...
+				.split(SPLITTER)
+				// parse numbers...
+				.map(function(e){ 
+					// numbers...
+					if(/^[-+]?[0-9]+\.[0-9]+$/.test(e)){
+						e = parseFloat(e)
+					} else if(/^[-+]?[0-9]+$/.test(e)){
+						e = parseInt(e)
+					}
+					return e
+				})
+				// remove undefined groups...
+				.filter(function(e){ 
+					// NOTE: in JS 0 == '' is true ;)
+					return e !== undefined && e !== ''
+				})
+		}
+		return code
+	},
+	// pre-process a lexical list...
+	// a -- b
+	'prep': function(context){
+		var code = context.stack.pop()
+
+		return run({
+			stack: [],
+			code: code,
+			ns: context.pre_ns,
+			pre_ns: {},
+		}).stack
+	},
+
+	// word definition...
+	// syntax: ::  
+	// --
+	'::': function(context){
+		var ident = context.code.splice(0, 1)
+		var cur = context.code.splice(0, 1)
+
+		this[ident] = cur[0]
+	},
+
+	// s c -- s
+	'_exec': function(context){
+		// block...
+		var b = context.stack.pop()
+		if(typeof(b) == typeof([]) && b.constructor.name == 'Array'){
+			b = b.slice()
+		} else {
+			b = [ b ]
+		}
+		// stack...
+		var s = context.stack.pop()
+		var res = run({
+			stack: s,
+			code: b,
+			// NOTE: this can have side-effects on the context...
+			ns: context.ns,
+			pre_ns: context.pre_ns
+		}).stack
+		return res
+	},
+	// quote - push the next elem as-is to stack...
+	// -- x
+	'\\': function(context){
+		var code = context.code
+		return code.splice(0, 1)[0] 
+	},
+
+	// comparisons and logic...
+	// a b -- c
+	'and': function(context){
+		var b = context.stack.pop()
+		var a = context.stack.pop()
+		if(a){
+			return b
+		} else {
+			return a
+		}
+	},
+	// a b -- c
+	'or': function(context){
+		var b = context.stack.pop()
+		var a = context.stack.pop()
+		if(a){
+			return a
+		} else {
+			return b
+		}
+	},
+	// x -- b
+	'not': function(context){
+		return !context.stack.pop()
+	},
+	// a b -- c
+	'gt': function(context){
+		return context.stack.pop() < context.stack.pop()
+	},
+	// a b -- c
+	'eq': function(context){
+		return context.stack.pop() == context.stack.pop()
+	},
+
+	// stack operations...
+	// ... x -- x ...
+	'rot': function(context){
+		context.stack.splice(0, 0, context.stack.pop())
+	},
+	// x ... -- ... x
+	'tor': function(context){
+		context.stack.push(context.stack.shift())
+	},
+	// a b -- b a
+	'swap': function(context){
+		return context.stack.splice(context.stack.length-2, 1)[0]
+	},
+	// x -- x x
+	'dup': function(context){
+		return context.stack[context.stack.length-1]
+	},
+	// x --
+	'drop': function(context){
+		context.stack.pop()
+	},
+
+	// basic number operations...
+	// a -- b
+	'isNumber': function(context){
+		return typeof(context.stack.pop()) == typeof(123)
+	},
+	// a b -- c
+	'add': function(context){
+		return context.stack.pop() + context.stack.pop()
+	},
+	'sub': function(context){
+		return - context.stack.pop() + context.stack.pop()
+	},
+	'mul': function(context){
+		return context.stack.pop() * context.stack.pop()
+	},
+	'div': function(context){
+		return context.stack.pop() / context.stack.pop()
+	},
+
+	// block/list operations...
+	'isBlock': function(context){
+		var e = context.stack.pop()
+		return typeof(e) == typeof([]) && e.constructor.name == 'Array'
+	},
+	// b n -- b e
+	'at': function(context){
+		var i = context.stack.pop()
+		if(i < 0){
+			var l = context.stack[context.stack.length-1]
+			return l[l.length + i]
+		}
+		return context.stack[context.stack.length-1][i]
+	},
+	// b e n -- b
+	'to': function(context){
+		var i = context.stack.pop()
+		var e = context.stack.pop()
+		if(i < 0){
+			var l = context.stack[context.stack.length-1]
+			l[l.length + i] = e
+		} else {
+			context.stack[context.stack.length-1][i] = e
+		}
+	},
+	// b e n -- b
+	'before': function(context){
+		var i = context.stack.pop()
+		var e = context.stack.pop()
+		if(i < 0){
+			var l = context.stack[context.stack.length-1]
+			l.splice(l.length + i + 1, 0, e)
+		} else {
+			context.stack[context.stack.length-1].splice(i, 0, e)
+		}
+	},
+	// b -- b e
+	'pop': function(context){
+		return context.stack[context.stack.length-1].pop()
+	},
+	// b -- b l
+	'len': function(context){
+		return context.stack[context.stack.length-1].length
+	},
+	// b c -- b
+	'each': function(context){
+		var c = context.stack.pop()
+		var b = context.stack[context.stack.length-1]
+		for(var i=0; i < b.length; i++){
+			// exec block in a separate context...
+			var res = run({
+				stack: [b[i], c],
+				code: ['exec'],
+				// NOTE: this can have side-effects on the context...
+				ns: context.ns
+			}).stack
+			var l = res.length
+			if(l == 0){
+				b.splice(i, 1)
+				i--
+			} else {
+				b.splice.apply(b, [i, 1].concat(res))
+				i += l - 1
+			}
+		}
+	},
+}
+
+
+var BOOTSTRAP = '\n'+
+':: _swap ( x -- y ) [ 1 1 _swapN ]\n'+
+':: _push ( x -- y ) [ 0 _swapN ]\n'+
+':: _pull ( x -- y ) [ 0 swap _swapN ]\n'+
+'\n'+
+':: exec ( b -- ... ) [ s2b pop _exec b2s ]\n'+
+':: eval ( c -- ... ) [ lex prep exec ]\n'+
+'-- like exec but will run a block in current context...\n'+
+':: b2c [ len rot b2s tor 0 _swapN ]\n'+
+'\n'+
+':: . ( x -- ) [ print drop ]\n'+
+'\n'+
+':: swap2 ( a _ b -- b _ a ) [ swap rot swap tor swap ]\n'+
+'\n'+
+':: isT ( a -- b ) [ not not true eq ]\n'+
+':: isF ( a -- b ) [ not isT ]\n'+
+//'\n'+
+//':: if ( cond a b -- ... ) [ rot rot exec isT tor and tor or exec ]\n'+
+'\n'+
+'-- [  ] ? [  ] \n'+
+'-- [  ] ? [  ] else [  ] \n'+
+':: _run_else [ drop dup \\ else eq [ drop \\ exec _swap 4 ] and\n'+
+'				[ 1 _push 2 ] or\n'+
+'				b2s 0 _swapN ]\n'+
+':: _run_then [ \\ exec swap dup \\ else eq [ (drop else) drop \\ drop _swap 6 ] and\n'+
+'				[ (run as-is) 1 _push 4 ] or\n'+
+'				b2s 0 _swapN ]\n'+
+// XXX BUG: if no code after this will break...
+// 		Ex:
+// 			-- this will not exec [ B ]...
+// 			[ A ] ? [ B ]
+// 			-- while this will...
+// 			[ A ] ? [ B ] nop
+':: ? [ exec [ _run_then 1 ] and [ swap _run_else 2 ] or b2s 2 _swapN ]\n'+
+'\n'+
+'\n'+
+'-- list/block 2\'nd gen stuff...\n'+
+':: push ( b e i -- b ) [ -1 before ]\n'+
+'\n'+
+'\n'+
+'-- experimental...\n'+
+'-- NOTE: these are at this point stupid and do not support priorities or grouping...\n'+
+'-- NOTE: these have both stack and code effect, in genera the operations are of \n'+
+'--		the form: A op B\n'+
+':: + [ \\ add _swap ]\n'+
+':: - [ \\ sub _swap ]\n'+
+':: * [ \\ mul _swap ]\n'+
+':: / [ \\ div _swap ]\n'+
+'\n'+
+':: == [ \\ eq _swap ]\n'+
+':: > [ \\ gt _swap ]\n'+
+'\n'+
+'\n'+
+'-- this is here for devel use only\n'+
+':: _clear ( * -- ) [ s2b drop ] \n'+
+':: _stack_size ( -- l ) [ s2b len swap b2s tor ] \n'+
+'\n'+
+'\n'+
+'-- tests and examples...\n'+
+':: hi ( -- ) [ "Hello World!" print drop ]\n'+
+//'-- NOTE: nop at the end is a stub to fix a bug in ? else ...\n'+
+//':: ! ( a -- b ) [ [ dup 1 eq not ] ? [ dup 1 sub ! mul ] nop ]\n'+
+':: ! ( a -- b ) [ [ dup 1 eq not ] ? [ dup 1 sub ! mul ] ]\n'+
+':: range ( n -- b ) [\n'+
+'		-- initial state...\n'+
+'		[ dup isNumber ] ? \n'+
+'			[ [] swap ]\n'+
+'		-- get first elem...\n'+
+'		else\n'+
+'			[ 0 at ]\n'+
+'		-- we got to the end...\n'+
+'		[ dup 0 eq ] ? \n'+
+'			[ drop ]\n'+
+'		-- dec push new and continue...\n'+
+'		else\n'+
+'			[ 1 sub 0 before range ] ]\n'+
+':: range2 ( n s -- b )\n'+
+'		[ swap range swap [] swap push \\ * 0 before each ]\n'+
+'\n'+
+''
+
+
+var STARTUP = [[], BOOTSTRAP, 'lex', 'prep', '_exec', 'drop']
+
+
+// build bootstrap...
+var CONTEXT = {
+	stack: [],
+	code: STARTUP.slice(),
+	ns: NAMESPACE,
+	pre_ns: PRE_NAMESPACE,
+}
+
+
+// run bootstrap...
+run(CONTEXT)
+
+
+// convenience...
+function _slang(code, context){
+	context = context == null ? CONTEXT : context
+
+	context.code = code
+	return run(context).stack
+}
+
+
+function slang(code, context){
+	context = context == null ? CONTEXT : context
+
+	if(typeof(code) == typeof('abc')){
+		code = [ '"'+code+'"', 'lex', 'prep', 'exec' ]
+	} else {
+		code = [ [code], 'b2s', 'prep', 'exec' ]
+	}
+
+	context.code = code
+	return run(context).stack
+}
+
+
+
+/**********************************************************************
+* vim:set ts=4 sw=4 :                                                */