Index: uspace/app/sbi/src/lex.c
===================================================================
--- uspace/app/sbi/src/lex.c	(revision 051bc69a7034999d45c93c61a56e515474aa78e3)
+++ uspace/app/sbi/src/lex.c	(revision eb522e89bed31febf22a3d81923e99a4a8ff9513)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2010 Jiri Svoboda
+ * Copyright (c) 2011 Jiri Svoboda
  * All rights reserved.
  *
@@ -45,4 +45,9 @@
 #define TAB_WIDTH 8
 
+typedef enum {
+	cs_chr,
+	cs_str
+} chr_str_t;
+
 static void lex_touch(lex_t *lex);
 static bool_t lex_read_try(lex_t *lex);
@@ -57,4 +62,5 @@
 static void lex_number(lex_t *lex);
 static void lex_string(lex_t *lex);
+static void lex_char_string_core(lex_t *lex, chr_str_t cs);
 static int digit_value(char c);
 
@@ -117,4 +123,5 @@
 	{ lc_string,	"string" },
 	{ lc_struct,	"struct" },
+	{ lc_switch,	"switch" },
 	{ lc_then,	"then" },
 	{ lc_this,	"this" },
@@ -122,4 +129,5 @@
 	{ lc_var,	"var" },
 	{ lc_with,	"with" },
+	{ lc_when,	"when" },
 	{ lc_while,	"while" },
 	{ lc_yield,	"yield" },
@@ -535,30 +543,9 @@
 static void lex_char(lex_t *lex)
 {
-	char *bp;
-	int idx;
 	size_t len;
 	int char_val;
 
-	bp = lex->ibp + 1;
-	idx = 0;
-
-	while (bp[idx] != '\'') {
-		if (idx >= SLBUF_SIZE) {
-			printf("Error: Character literal too long.\n");
-			exit(1);
-		}
-
-		if (bp[idx] == '\0') {
-			printf("Error: Unterminated character literal.\n");
-			exit(1);
-		}
-
-		strlit_buf[idx] = bp[idx];
-		++idx;
-	}
-
-	lex->ibp = bp + idx + 1;
-
-	strlit_buf[idx] = '\0';
+	lex_char_string_core(lex, cs_chr);
+
 	len = os_str_length(strlit_buf);
 	if (len != 1) {
@@ -620,31 +607,84 @@
 static void lex_string(lex_t *lex)
 {
-	char *bp;
-	int idx;
-
-	bp = lex->ibp + 1;
-	idx = 0;
-
-	while (bp[idx] != '"') {
-		if (idx >= SLBUF_SIZE) {
-			printf("Error: String literal too long.\n");
-			exit(1);
-		}
-
-		if (bp[idx] == '\0') {
-			printf("Error: Unterminated string literal.\n");
-			exit(1);
-		}
-
-		strlit_buf[idx] = bp[idx];
-		++idx;
-	}
-
-	lex->ibp = bp + idx + 1;
-
-	strlit_buf[idx] = '\0';
+	lex_char_string_core(lex, cs_str);
 
 	lex->current.lclass = lc_lit_string;
 	lex->current.u.lit_string.value = os_str_dup(strlit_buf);
+}
+
+static void lex_char_string_core(lex_t *lex, chr_str_t cs)
+{
+	char *bp;
+	int sidx, didx;
+	char term;
+	const char *descr, *cap_descr;
+	char spchar;
+
+	/* Make compiler happy */
+	term = '\0';
+	descr = NULL;
+	cap_descr = NULL;
+
+	switch (cs) {
+	case cs_chr:
+		term = '\'';
+		descr = "character";
+		cap_descr = "Character";
+		break;
+	case cs_str:
+		term = '"';
+		descr = "string";
+		cap_descr = "String";
+		break;
+	}
+
+	bp = lex->ibp + 1;
+	sidx = didx = 0;
+
+	while (bp[sidx] != term) {
+		if (didx >= SLBUF_SIZE) {
+			printf("Error: %s literal too long.\n", cap_descr);
+			exit(1);
+		}
+
+		if (bp[sidx] == '\0') {
+			printf("Error: Unterminated %s literal.\n", descr);
+			exit(1);
+		}
+
+		if (bp[sidx] == '\\') {
+			switch (bp[sidx + 1]) {
+			case '\\':
+				spchar = '\\';
+				break;
+			case '\'':
+				spchar = '\'';
+				break;
+			case '"':
+				spchar = '"';
+				break;
+			case 'n':
+				spchar = '\n';
+				break;
+			case 't':
+				spchar = '\t';
+				break;
+			default:
+				printf("Error: Unknown character escape sequence.\n");
+				exit(1);
+			}
+
+			strlit_buf[didx] = spchar;
+			++didx;
+			sidx += 2;
+		} else {
+			strlit_buf[didx] = bp[sidx];
+			++sidx; ++didx;
+		}
+	}
+
+	lex->ibp = bp + sidx + 1;
+
+	strlit_buf[didx] = '\0';
 }
 
