 				}
 				else if (escapeIndex < bracketIndex) // handle '\'
 				{
+					// append everything before the escaped character
+					output += input.substring(searchIndex, escapeIndex);
+					
 					// look up escaped character
 					var c:String = input.charAt(escapeIndex + 1);
+					c = DECODE_LOOKUP[c] || c;
 					
-					//TODO: octal and hex escape sequences
+					if ('0123'.indexOf(c) >= 0)
+					{
+						// \000 .. \377        a byte specified in octal
+						var oct:String = input.substr(escapeIndex + 1, 3);
+						c = String.fromCharCode(parseInt(oct, 8));
+						searchIndex = escapeIndex + 4; // skip over escape sequence
+					}
+					else if (c == 'x')
+					{
+						// \x00 .. \xFF        a byte specified in hexadecimal
+						var hex:String = input.substr(escapeIndex + 2, 2);
+						c = String.fromCharCode(parseInt(hex, 16));
+						searchIndex = escapeIndex + 4; // skip over escape sequence
+					}
+					else if (c == 'u')
+					{
+						// \u0000 .. \uFFFF    a 16-bit Unicode character specified in hexadecimal
+						var unicode:String = input.substr(escapeIndex + 2, 4);
+						c = String.fromCharCode(parseInt(unicode, 16));
+						searchIndex = escapeIndex + 6; // skip over escape sequence
+					}
+					else
+					{
+						searchIndex = escapeIndex + 2; // skip over escape sequence
+					}
 					
-					c = DECODE_LOOKUP[c] || c;
-					output += input.substring(searchIndex, escapeIndex) + c;
-					// skip over escape sequence
-					searchIndex = escapeIndex + 2;
+					// append the escaped character
+					output += c;
 				}
 				else if (bracketIndex < escapeIndex) // handle '{'
 				{

			// this function avoids unnecessary function calls by keeping its own call stack rather than using recursion.
			var wrapperFunction:Function = function(...args):*
			{
				// reset local symbol table each time the function is called
				for (symbolName in localSymbolTable)
					localSymbolTable[symbolName] = undefined;
				
				builtInSymbolTable['this'] = this;
				builtInSymbolTable['arguments'] = args;
				// make function parameters available under the specified parameter names
				if (paramNames)
					for (i = 0; i < paramNames.length; i++)
						builtInSymbolTable[paramNames[i] as String] = args.length > i ? args[i] : paramDefaults[i];
				
				if (useThisScope)
					allSymbolTables[THIS_SYMBOL_TABLE_INDEX] = this;

							if (ASSIGN_OP_LOOKUP[call.evaluatedMethod] && compiledParams.length == 2) // two params means local assignment
							{
								symbolName = call.evaluatedParams[0];
								if (builtInSymbolTable.hasOwnProperty(symbolName))
									throw new Error("Cannot assign built-in variable: " + symbolName);
								
								// assignment operator expects parameters like (host, ...chain, value)
								// if there is no matching local variable and 'this' has a matching one, assign the property of 'this'
								if (useThisScope && this && this.hasOwnProperty(symbolName) && !localSymbolTable.hasOwnProperty(symbolName))
