Index: uspace/app/sbi/Makefile
===================================================================
--- uspace/app/sbi/Makefile	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/app/sbi/Makefile	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -34,4 +34,5 @@
 
 SOURCES = \
+	src/os/helenos.c \
 	src/ancr.c \
 	src/builtin.c \
@@ -47,4 +48,5 @@
 	src/run.c \
 	src/run_expr.c \
+	src/run_texpr.c \
 	src/stree.c \
 	src/strtab.c \
Index: uspace/app/sbi/src/ancr.c
===================================================================
--- uspace/app/sbi/src/ancr.c	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/app/sbi/src/ancr.c	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -151,7 +151,11 @@
 		/* Process base CSI. */
 		ancr_csi_process(prog, base_csi);
+	} else {
+		base_csi = NULL;
 	}
 
+	/* Store base CSI and update node state. */
 	node->ancr_state = ws_visited;
+	node->base_csi = base_csi;
 }
 
Index: uspace/app/sbi/src/builtin.c
===================================================================
--- uspace/app/sbi/src/builtin.c	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/app/sbi/src/builtin.c	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -34,13 +34,21 @@
 #include "list.h"
 #include "mytypes.h"
+#include "os/os.h"
 #include "run.h"
 #include "stree.h"
 #include "strtab.h"
+#include "symbol.h"
 
 #include "builtin.h"
 
+static stree_symbol_t *builtin_declare_fun(stree_csi_t *csi, char *name);
+static void builtin_fun_add_arg(stree_symbol_t *fun_sym, char *name);
+static void builtin_fun_add_vararg(stree_symbol_t *fun_sym, char *name);
+
 static void builtin_write_line(run_t *run);
+static void builtin_exec(run_t *run);
 
 static stree_symbol_t *bi_write_line;
+static stree_symbol_t *bi_exec;
 
 /** Declare builtin symbols in the program.
@@ -53,7 +61,4 @@
 	stree_csi_t *csi;
 	stree_ident_t *ident;
-	stree_csimbr_t *csimbr;
-	stree_fun_t *fun;
-	stree_fun_arg_t *fun_arg;
 	stree_symbol_t *symbol;
 
@@ -76,30 +81,10 @@
 
 	/* Declare builtin functions. */
-	ident = stree_ident_new();
-	ident->sid = strtab_get_sid("WriteLine");
-
-	fun = stree_fun_new();
-	fun->name = ident;
-	fun->body = NULL;
-	list_init(&fun->args);
-
-	csimbr = stree_csimbr_new(csimbr_fun);
-	csimbr->u.fun = fun;
-
-	symbol = stree_symbol_new(sc_fun);
-	symbol->u.fun = fun;
-	symbol->outer_csi = csi;
-	fun->symbol = symbol;
-
-	list_append(&csi->members, csimbr);
-
-	fun_arg = stree_fun_arg_new();
-	fun_arg->name = stree_ident_new();
-	fun_arg->name->sid = strtab_get_sid("arg");
-	fun_arg->type = NULL; /* XXX */
-
-	list_append(&fun->args, fun_arg);
-
-	bi_write_line = symbol;
+
+	bi_write_line = builtin_declare_fun(csi, "WriteLine");
+	builtin_fun_add_arg(bi_write_line, "arg");
+
+	bi_exec = builtin_declare_fun(csi, "Exec");
+	builtin_fun_add_vararg(bi_exec, "args");
 }
 
@@ -111,4 +96,6 @@
 	if (fun_sym == bi_write_line) {
 		builtin_write_line(run);
+	} else if (fun_sym == bi_exec) {
+		builtin_exec(run);
 	} else {
 		assert(b_false);
@@ -116,4 +103,67 @@
 }
 
+/** Declare a builtin function in @a csi. */
+static stree_symbol_t *builtin_declare_fun(stree_csi_t *csi, char *name)
+{
+	stree_ident_t *ident;
+	stree_fun_t *fun;
+	stree_csimbr_t *csimbr;
+	stree_symbol_t *symbol;
+
+	ident = stree_ident_new();
+	ident->sid = strtab_get_sid(name);
+
+	fun = stree_fun_new();
+	fun->name = ident;
+	fun->body = NULL;
+	list_init(&fun->args);
+
+	csimbr = stree_csimbr_new(csimbr_fun);
+	csimbr->u.fun = fun;
+
+	symbol = stree_symbol_new(sc_fun);
+	symbol->u.fun = fun;
+	symbol->outer_csi = csi;
+	fun->symbol = symbol;
+
+	list_append(&csi->members, csimbr);
+
+	return symbol;
+}
+
+/** Add one formal parameter to function. */
+static void builtin_fun_add_arg(stree_symbol_t *fun_sym, char *name)
+{
+	stree_fun_arg_t *fun_arg;
+	stree_fun_t *fun;
+
+	fun = symbol_to_fun(fun_sym);
+	assert(fun != NULL);
+
+	fun_arg = stree_fun_arg_new();
+	fun_arg->name = stree_ident_new();
+	fun_arg->name->sid = strtab_get_sid(name);
+	fun_arg->type = NULL; /* XXX */
+
+	list_append(&fun->args, fun_arg);
+}
+
+/** Add variadic formal parameter to function. */
+static void builtin_fun_add_vararg(stree_symbol_t *fun_sym, char *name)
+{
+	stree_fun_arg_t *fun_arg;
+	stree_fun_t *fun;
+
+	fun = symbol_to_fun(fun_sym);
+	assert(fun != NULL);
+
+	fun_arg = stree_fun_arg_new();
+	fun_arg->name = stree_ident_new();
+	fun_arg->name->sid = strtab_get_sid(name);
+	fun_arg->type = NULL; /* XXX */
+
+	fun->varg = fun_arg;
+}
+
 static void builtin_write_line(run_t *run)
 {
@@ -121,5 +171,5 @@
 
 #ifdef DEBUG_RUN_TRACE
-	printf("Called Builtin.writeLine()\n");
+	printf("Called Builtin.WriteLine()\n");
 #endif
 	var = run_local_vars_lookup(run, strtab_get_sid("arg"));
@@ -138,2 +188,57 @@
 	}
 }
+
+/** Start an executable and wait for it to finish. */
+static void builtin_exec(run_t *run)
+{
+	rdata_var_t *args;
+	rdata_var_t *var;
+	rdata_array_t *array;
+	rdata_var_t *arg;
+	int idx, dim;
+	char **cmd;
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Called Builtin.Exec()\n");
+#endif
+	args = run_local_vars_lookup(run, strtab_get_sid("args"));
+
+	assert(args);
+	assert(args->vc == vc_ref);
+
+	var = args->u.ref_v->vref;
+	assert(var->vc == vc_array);
+
+	array = var->u.array_v;
+	assert(array->rank == 1);
+	dim = array->extent[0];
+
+	if (dim == 0) {
+		printf("Error: Builtin.Exec() expects at least one argument.\n");
+		exit(1);
+	}
+
+	cmd = calloc(dim + 1, sizeof(char *));
+	if (cmd == NULL) {
+		printf("Memory allocation failed.\n");
+		exit(1);
+	}
+
+	for (idx = 0; idx < dim; ++idx) {
+		arg = array->element[idx];
+		if (arg->vc != vc_string) {
+			printf("Error: Argument to Builtin.Exec() must be "
+			    "string (found %d).\n", arg->vc);
+			exit(1);
+		}
+
+		cmd[idx] = arg->u.string_v->value;
+	}
+
+	cmd[dim] = '\0';
+
+	if (os_exec(cmd) != EOK) {
+		printf("Error: Exec failed.\n");
+		exit(1);
+	}
+}
Index: uspace/app/sbi/src/compat.h
===================================================================
--- uspace/app/sbi/src/compat.h	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/app/sbi/src/compat.h	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -45,10 +45,4 @@
 #define list_remove sbi_list_remove
 
-/*
- * These functions can be simply mapped to HelenOS string API.
- */
-#define strcmp str_cmp
-#define strdup str_dup
-
 #endif
 
Index: uspace/app/sbi/src/lex.c
===================================================================
--- uspace/app/sbi/src/lex.c	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/app/sbi/src/lex.c	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -35,7 +35,7 @@
 #include <stdlib.h>
 #include <string.h>
-#include "compat.h"
 #include "mytypes.h"
 #include "input.h"
+#include "os/os.h"
 #include "strtab.h"
 
@@ -44,4 +44,7 @@
 #define TAB_WIDTH 8
 
+static bool_t lex_next_try(lex_t *lex);
+
+static void lex_skip_comment(lex_t *lex);
 static void lex_skip_ws(lex_t *lex);
 static bool_t is_wstart(char c);
@@ -87,4 +90,5 @@
 	{ lc_nil,	"nil" },
 	{ lc_override,	"override" },
+	{ lc_packed,	"packed" },
 	{ lc_private,	"private" },
 	{ lc_prop,	"prop" },
@@ -222,4 +226,17 @@
 void lex_next(lex_t *lex)
 {
+	bool_t got_lem;
+
+	do {
+		got_lem = lex_next_try(lex);
+	} while (got_lem == b_false);
+}
+
+/** Try reading next lexical element.
+ *
+ * @return @c b_true on success or @c b_false if it needs restarting.
+ */
+static bool_t lex_next_try(lex_t *lex)
+{
 	char *bp;
 
@@ -240,20 +257,25 @@
 		/* End of input */
 		lex->current.lclass = lc_eof;
-		return;
+		return b_true;
 	}
 
 	if (is_wstart(bp[0])) {
 		lex_word(lex);
-		return;
+		return b_true;
 	}
 
 	if (is_digit(bp[0])) {
 		lex_number(lex);
-		return;
+		return b_true;
 	}
 
 	if (bp[0] == '"') {
 		lex_string(lex);
-		return;
+		return b_true;
+	}
+
+	if (bp[0] == '-' && bp[1] == '-') {
+		lex_skip_comment(lex);
+		return b_false;
 	}
 
@@ -305,5 +327,5 @@
 
 	lex->ibp = bp;
-	return;
+	return b_true;
 
 invalid:
@@ -311,4 +333,6 @@
 	++bp;
 	lex->ibp = bp;
+
+	return b_true;
 }
 
@@ -340,5 +364,5 @@
 	dp = keywords;
 	while (dp->name != NULL) {
-		if (strcmp(ident_buf, dp->name) == 0) {
+		if (os_str_cmp(ident_buf, dp->name) == 0) {
 			/* Match */
 			lex->current.lclass = dp->lclass;
@@ -402,7 +426,20 @@
 
 	lex->current.lclass = lc_lit_string;
-	lex->current.u.lit_string.value = strdup(strlit_buf);
-}
-
+	lex->current.u.lit_string.value = os_str_dup(strlit_buf);
+}
+
+/** Lex a single-line comment. */
+static void lex_skip_comment(lex_t *lex)
+{
+	char *bp;
+
+	bp = lex->ibp + 2;
+
+	while (*bp != '\n' && *bp != '\0') {
+		++bp;
+	}
+
+	lex->ibp = bp;
+}
 
 /** Skip whitespace characters. */
Index: uspace/app/sbi/src/lex_t.h
===================================================================
--- uspace/app/sbi/src/lex_t.h	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/app/sbi/src/lex_t.h	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -58,4 +58,5 @@
 	lc_nil,
 	lc_override,
+	lc_packed,
 	lc_private,
 	lc_prop,
Index: uspace/app/sbi/src/os/helenos.c
===================================================================
--- uspace/app/sbi/src/os/helenos.c	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
+++ uspace/app/sbi/src/os/helenos.c	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2010 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file HelenOS-specific code. */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <task.h>
+
+#include "os.h"
+
+/*
+ * Using HelenOS-specific string API.
+ */
+
+/** Concatenate two strings. */
+char *os_str_acat(const char *a, const char *b)
+{
+	int a_size, b_size;
+	char *str;
+
+	a_size = str_size(a);
+	b_size = str_size(b);
+
+	str = malloc(a_size + b_size + 1);
+	if (str == NULL) {
+		printf("Memory allocation error.\n");
+		exit(1);
+	}
+
+	memcpy(str, a, a_size);
+	memcpy(str + a_size, b, b_size);
+	str[a_size + b_size] = '\0';
+
+	return str;
+}
+
+/** Compare two strings. */
+int os_str_cmp(const char *a, const char *b)
+{
+	return str_cmp(a, b);
+}
+
+/** Duplicate string. */
+char *os_str_dup(const char *str)
+{
+	return str_dup(str);
+}
+
+/** Simple command execution. */
+int os_exec(char *const cmd[])
+{
+	task_id_t tid;
+	task_exit_t texit;
+	int retval;
+
+	tid = task_spawn(cmd[0], cmd);
+	if (tid == 0) {
+		printf("Error: Failed spawning '%s'.\n", cmd[0]);
+		exit(1);
+	}
+
+	/* XXX Handle exit status and return value. */
+	task_wait(tid, &texit, &retval);
+
+	return EOK;
+}
Index: uspace/app/sbi/src/os/os.h
===================================================================
--- uspace/app/sbi/src/os/os.h	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
+++ uspace/app/sbi/src/os/os.h	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2010 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef OS_H_
+#define OS_H_
+
+char *os_str_acat(const char *a, const char *b);
+int os_str_cmp(const char *a, const char *b);
+char *os_str_dup(const char *str);
+int os_exec(char *const cmd[]);
+
+
+#endif
Index: uspace/app/sbi/src/os/posix.c
===================================================================
--- uspace/app/sbi/src/os/posix.c	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
+++ uspace/app/sbi/src/os/posix.c	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2010 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file POSIX-specific code. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+#include "../mytypes.h"
+
+#include "os.h"
+
+/*
+ * The string functions are in fact standard C, but would not work under
+ * HelenOS.
+ */
+
+/** Concatenate two strings. */
+char *os_str_acat(const char *a, const char *b)
+{
+	int a_len, b_len;
+	char *str;
+
+	a_len = strlen(a);
+	b_len = strlen(b);
+
+	str = malloc(a_len + b_len + 1);
+	if (str == NULL) {
+		printf("Memory allocation error.\n");
+		exit(1);
+	}
+
+	memcpy(str, a, a_len);
+	memcpy(str + a_len, b, b_len);
+	str[a_len + b_len] = '\0';
+
+	return str;
+}
+
+/** Compare two strings. */
+int os_str_cmp(const char *a, const char *b)
+{
+	return strcmp(a, b);
+}
+
+/** Duplicate string. */
+char *os_str_dup(const char *str)
+{
+	return strdup(str);
+}
+
+/** Simple command execution. */
+int os_exec(char *const cmd[])
+{
+	pid_t pid;
+	int status;
+
+	pid = vfork();
+
+	if (pid == 0) {
+		execvp(cmd[0], cmd);
+		/* If we get here, exec failed. */
+		exit(1);
+	} else if (pid == -1) {
+		/* fork() failed */
+		return EBUSY;
+	}
+
+	if (waitpid(pid, &status, 0) == -1) {
+		/* waitpid() failed */
+		printf("Error: Waitpid failed.\n");
+		exit(1);
+	}
+
+	if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
+		printf("Error: Exec failed or child returned non-zero "
+		    "exit status.\n");
+	}
+
+	return EOK;
+}
Index: uspace/app/sbi/src/p_expr.c
===================================================================
--- uspace/app/sbi/src/p_expr.c	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/app/sbi/src/p_expr.c	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -48,4 +48,5 @@
 static stree_expr_t *parse_pf_access(parse_t *parse, stree_expr_t *a);
 static stree_expr_t *parse_pf_call(parse_t *parse, stree_expr_t *a);
+static stree_expr_t *parse_pf_index(parse_t *parse, stree_expr_t *a);
 static stree_expr_t *parse_primitive(parse_t *parse);
 static stree_expr_t *parse_nameref(parse_t *parse);
@@ -181,6 +182,10 @@
 	lmatch(parse, lc_new);
 	texpr = parse_texpr(parse);
-	lmatch(parse, lc_lparen);
-	lmatch(parse, lc_rparen);
+
+	/* Parenthesis should be present except for arrays. */
+	if (texpr->tc != tc_tindex) {
+		lmatch(parse, lc_lparen);
+		lmatch(parse, lc_rparen);
+	}
 
 	new_op = stree_new_new();
@@ -200,5 +205,6 @@
 	a = parse_primitive(parse);
 
-	while (lcur_lc(parse) == lc_period || lcur_lc(parse) == lc_lparen) {
+	while (lcur_lc(parse) == lc_period || lcur_lc(parse) == lc_lparen ||
+	    lcur_lc(parse) == lc_lsbr) {
 
 		switch (lcur_lc(parse)) {
@@ -209,4 +215,7 @@
 			tmp = parse_pf_call(parse, a);
 			break;
+		case lc_lsbr:
+			tmp = parse_pf_index(parse, a);
+			break;
 		default:
 			assert(b_false);
@@ -273,4 +282,38 @@
 }
 
+/** Parse index expression. */
+static stree_expr_t *parse_pf_index(parse_t *parse, stree_expr_t *a)
+{
+	stree_expr_t *expr;
+	stree_index_t *index;
+	stree_expr_t *arg;
+
+	lmatch(parse, lc_lsbr);
+
+	index = stree_index_new();
+	index->base = a;
+	list_init(&index->args);
+
+	/* Parse indices */
+
+	if (lcur_lc(parse) != lc_rsbr) {
+		while (b_true) {
+			arg = parse_expr(parse);
+			list_append(&index->args, arg);
+
+			if (lcur_lc(parse) == lc_rsbr)
+				break;
+			lmatch(parse, lc_comma);
+		}
+	}
+
+	lmatch(parse, lc_rsbr);
+
+	expr = stree_expr_new(ec_index);
+	expr->u.index = index;
+
+	return expr;
+}
+
 /** Parse primitive expression. */
 static stree_expr_t *parse_primitive(parse_t *parse)
Index: uspace/app/sbi/src/p_type.c
===================================================================
--- uspace/app/sbi/src/p_type.c	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/app/sbi/src/p_type.c	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -1,3 +1,3 @@
-/*
+/*                              YI
  * Copyright (c) 2010 Jiri Svoboda
  * All rights reserved.
@@ -35,4 +35,5 @@
 #include "mytypes.h"
 #include "parse.h"
+#include "p_expr.h"
 #include "stree.h"
 
@@ -41,4 +42,6 @@
 static stree_texpr_t *parse_tapply(parse_t *parse);
 static stree_texpr_t *parse_tpostfix(parse_t *parse);
+static stree_texpr_t *parse_pf_taccess(parse_t *parse, stree_texpr_t *a);
+static stree_texpr_t *parse_pf_tindex(parse_t *parse, stree_texpr_t *a);
 static stree_texpr_t *parse_tprimitive(parse_t *parse);
 static stree_tliteral_t *parse_tliteral(parse_t *parse);
@@ -78,24 +81,88 @@
 {
 	stree_texpr_t *a;
+	stree_texpr_t *tmp;
+
+	a = parse_tprimitive(parse);
+
+	while (lcur_lc(parse) == lc_period || lcur_lc(parse) == lc_lsbr) {
+
+		switch (lcur_lc(parse)) {
+		case lc_period:
+			tmp = parse_pf_taccess(parse, a);
+			break;
+		case lc_lsbr:
+			tmp = parse_pf_tindex(parse, a);
+			break;
+		default:
+			lunexpected_error(parse);
+			exit(1);
+		}
+
+		a = tmp;
+	}
+
+	return a;
+}
+
+/** Parse access type expression. */
+static stree_texpr_t *parse_pf_taccess(parse_t *parse, stree_texpr_t *a)
+{
+	stree_texpr_t *texpr;
 	stree_ident_t *ident;
-	stree_texpr_t *tmp;
 	stree_taccess_t *taccess;
 
-	a = parse_tprimitive(parse);
-
-	while (lcur_lc(parse) == lc_period) {
-		lskip(parse);
-		ident = parse_ident(parse);
-
-		taccess = stree_taccess_new();
-		taccess->arg = a;
-		taccess->member_name = ident;
-
-		tmp = stree_texpr_new(tc_taccess);
-		tmp->u.taccess = taccess;
-		a = tmp;
-	}
-
-	return a;
+	lmatch(parse, lc_period);
+	ident = parse_ident(parse);
+
+	taccess = stree_taccess_new();
+	taccess->arg = a;
+	taccess->member_name = ident;
+
+	texpr = stree_texpr_new(tc_taccess);
+	texpr->u.taccess = taccess;
+
+	return texpr;
+}
+
+/** Parse index type expression. */
+static stree_texpr_t *parse_pf_tindex(parse_t *parse, stree_texpr_t *a)
+{
+	stree_texpr_t *texpr;
+	stree_tindex_t *tindex;
+	stree_expr_t *expr;
+
+	tindex = stree_tindex_new();
+	tindex->base_type = a;
+
+	tindex->n_args = 0;
+	list_init(&tindex->args);
+
+	lmatch(parse, lc_lsbr);
+
+	if (lcur_lc(parse) != lc_rsbr && lcur_lc(parse) != lc_comma) {
+		while (b_true) {
+			expr = parse_expr(parse);
+			tindex->n_args += 1;
+			list_append(&tindex->args, expr);
+
+			if (lcur_lc(parse) == lc_rsbr)
+				break;
+
+			lmatch(parse, lc_comma);
+		}
+	} else {
+		tindex->n_args = 1;
+		while (lcur_lc(parse) == lc_comma) {
+			lskip(parse);
+			tindex->n_args += 1;
+		}
+	}
+
+	lmatch(parse, lc_rsbr);
+
+	texpr = stree_texpr_new(tc_tindex);
+	texpr->u.tindex = tindex;
+
+	return texpr;
 }
 
Index: uspace/app/sbi/src/parse.c
===================================================================
--- uspace/app/sbi/src/parse.c	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/app/sbi/src/parse.c	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -56,4 +56,5 @@
 
 static stree_fun_arg_t *parse_fun_arg(parse_t *parse);
+static stree_arg_attr_t *parse_arg_attr(parse_t *parse);
 
 /*
@@ -72,4 +73,6 @@
 static stree_exps_t *parse_exps(parse_t *parse);
 
+static stree_except_t *parse_except(parse_t *parse);
+
 void parse_init(parse_t *parse, stree_program_t *prog, struct lex *lex)
 {
@@ -87,10 +90,4 @@
 	stree_symbol_t *symbol;
 
-/*	do {
-		lex_next(parse->lex);
-		printf("Read token: "); lem_print(&parse->lex->current);
-		putchar('\n');
-	} while (parse->lex->current.lclass != lc_eof);
-*/
 	while (lcur_lc(parse) != lc_eof) {
 		switch (lcur_lc(parse)) {
@@ -245,5 +242,10 @@
 		while (b_true) {
 			arg = parse_fun_arg(parse);
-			list_append(&fun->args, arg);
+			if (stree_arg_has_attr(arg, aac_packed)) {
+				fun->varg = arg;
+				break;
+			} else {
+				list_append(&fun->args, arg);
+			}
 
 			if (lcur_lc(parse) == lc_rparen)
@@ -307,4 +309,5 @@
 {
 	stree_fun_arg_t *arg;
+	stree_arg_attr_t *attr;
 
 	arg = stree_fun_arg_new();
@@ -313,5 +316,32 @@
 	arg->type = parse_texpr(parse);
 
+	list_init(&arg->attr);
+
+	/* Parse attributes. */
+	while (lcur_lc(parse) == lc_comma) {
+		lskip(parse);
+		attr = parse_arg_attr(parse);
+		list_append(&arg->attr, attr);
+	}
+
 	return arg;
+}
+
+/** Parse argument attribute. */
+static stree_arg_attr_t *parse_arg_attr(parse_t *parse)
+{
+	stree_arg_attr_t *attr;
+
+	if (lcur_lc(parse) != lc_packed) {
+		printf("Error: Unexpected attribute '");
+		lem_print(lcur(parse));
+		printf("'.\n");
+		exit(1);
+	}
+
+	lskip(parse);
+
+	attr = stree_arg_attr_new(aac_packed);
+	return attr;
 }
 
@@ -378,4 +408,5 @@
 		stat->u.return_s = return_s;
 		break;
+	case lc_do:
 	case lc_with:
 		wef_s = parse_wef(parse);
@@ -485,9 +516,12 @@
 static stree_raise_t *parse_raise(parse_t *parse)
 {
+	stree_raise_t *raise_s;
+
+	raise_s = stree_raise_new();
 	lmatch(parse, lc_raise);
-	(void) parse_expr(parse);
+	raise_s->expr = parse_expr(parse);
 	lmatch(parse, lc_scolon);
 
-	return stree_raise_new();
+	return raise_s;
 }
 
@@ -510,32 +544,34 @@
 {
 	stree_wef_t *wef_s;
-	stree_block_t *block;
+	stree_except_t *except_c;
 
 	wef_s = stree_wef_new();
-	list_init(&wef_s->except_blocks);
-
-	lmatch(parse, lc_with);
-	lmatch(parse, lc_ident);
-	lmatch(parse, lc_colon);
-	(void) parse_texpr(parse);
-	lmatch(parse, lc_assign);
-	(void) parse_expr(parse);
-	lmatch(parse, lc_do);
-	wef_s->with_block = parse_block(parse);
-
-	while (lcur_lc(parse) == lc_except) {
-		lmatch(parse, lc_except);
+	list_init(&wef_s->except_clauses);
+
+	if (lcur_lc(parse) == lc_with) {
+		lmatch(parse, lc_with);
 		lmatch(parse, lc_ident);
 		lmatch(parse, lc_colon);
 		(void) parse_texpr(parse);
+		lmatch(parse, lc_assign);
+		(void) parse_expr(parse);
+	}
+
+	lmatch(parse, lc_do);
+	wef_s->with_block = parse_block(parse);
+
+	while (lcur_lc(parse) == lc_except) {
+		except_c = parse_except(parse);
+		list_append(&wef_s->except_clauses, except_c);
+	}
+
+	if (lcur_lc(parse) == lc_finally) {
+		lmatch(parse, lc_finally);
 		lmatch(parse, lc_do);
-
-		block = parse_block(parse);
-		list_append(&wef_s->except_blocks, block);
-	}
-
-	lmatch(parse, lc_finally);
-	lmatch(parse, lc_do);
-	wef_s->finally_block = parse_block(parse);
+		wef_s->finally_block = parse_block(parse);
+	} else {
+		wef_s->finally_block = NULL;
+	}
+
 	lmatch(parse, lc_end);
 
@@ -556,4 +592,22 @@
 
 	return exps;
+}
+
+/* Parse @c except clause. */
+static stree_except_t *parse_except(parse_t *parse)
+{
+	stree_except_t *except_c;
+
+	except_c = stree_except_new();
+
+	lmatch(parse, lc_except);
+	except_c->evar = parse_ident(parse);
+	lmatch(parse, lc_colon);
+	except_c->etype = parse_texpr(parse);
+	lmatch(parse, lc_do);
+
+	except_c->block = parse_block(parse);
+
+	return except_c;
 }
 
Index: uspace/app/sbi/src/rdata.c
===================================================================
--- uspace/app/sbi/src/rdata.c	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/app/sbi/src/rdata.c	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -32,4 +32,5 @@
 #include <assert.h>
 #include "mytypes.h"
+#include "stree.h"
 
 #include "rdata.h"
@@ -39,5 +40,8 @@
 static void rdata_ref_copy(rdata_ref_t *src, rdata_ref_t **dest);
 static void rdata_deleg_copy(rdata_deleg_t *src, rdata_deleg_t **dest);
+static void rdata_array_copy(rdata_array_t *src, rdata_array_t **dest);
 static void rdata_object_copy(rdata_object_t *src, rdata_object_t **dest);
+
+static int rdata_array_get_dim(rdata_array_t *array);
 
 static void rdata_address_print(rdata_address_t *address);
@@ -126,4 +130,24 @@
 }
 
+rdata_array_t *rdata_array_new(int rank)
+{
+	rdata_array_t *array;
+
+	array = calloc(1, sizeof(rdata_array_t));
+	if (array == NULL) {
+		printf("Memory allocation failed.\n");
+		exit(1);
+	}
+
+	array->rank = rank;
+	array->extent = calloc(rank, sizeof(int));
+	if (array == NULL) {
+		printf("Memory allocation failed.\n");
+		exit(1);
+	}
+
+	return array;
+}
+
 rdata_object_t *rdata_object_new(void)
 {
@@ -163,4 +187,94 @@
 
 	return string_v;
+}
+
+rdata_titem_t *rdata_titem_new(titem_class_t tic)
+{
+	rdata_titem_t *titem;
+
+	titem = calloc(1, sizeof(rdata_titem_t));
+	if (titem == NULL) {
+		printf("Memory allocation failed.\n");
+		exit(1);
+	}
+
+	titem->tic = tic;
+	return titem;
+}
+
+rdata_tarray_t *rdata_tarray_new(void)
+{
+	rdata_tarray_t *tarray;
+
+	tarray = calloc(1, sizeof(rdata_tarray_t));
+	if (tarray == NULL) {
+		printf("Memory allocation failed.\n");
+		exit(1);
+	}
+
+	return tarray;
+}
+
+rdata_tcsi_t *rdata_tcsi_new(void)
+{
+	rdata_tcsi_t *tcsi;
+
+	tcsi = calloc(1, sizeof(rdata_tcsi_t));
+	if (tcsi == NULL) {
+		printf("Memory allocation failed.\n");
+		exit(1);
+	}
+
+	return tcsi;
+}
+
+rdata_tprimitive_t *rdata_tprimitive_new(void)
+{
+	rdata_tprimitive_t *tprimitive;
+
+	tprimitive = calloc(1, sizeof(rdata_tprimitive_t));
+	if (tprimitive == NULL) {
+		printf("Memory allocation failed.\n");
+		exit(1);
+	}
+
+	return tprimitive;
+}
+
+void rdata_array_alloc_element(rdata_array_t *array)
+{
+	int dim, idx;
+
+	dim = rdata_array_get_dim(array);
+
+	array->element = calloc(dim, sizeof(rdata_var_t *));
+	if (array->element == NULL) {
+		printf("Memory allocation failed.\n");
+		exit(1);
+	}
+
+	for (idx = 0; idx < dim; ++idx) {
+		array->element[idx] = calloc(1, sizeof(rdata_var_t));
+		if (array->element[idx] == NULL) {
+			printf("Memory allocation failed.\n");
+			exit(1);
+		}
+	}
+}
+
+/** Get array dimension.
+ *
+ * Dimension is the total number of elements in an array, in other words,
+ * the product of all extents.
+ */
+static int rdata_array_get_dim(rdata_array_t *array)
+{
+	int didx, dim;
+
+	dim = 1;
+	for (didx = 0; didx < array->rank; ++didx)
+		dim = dim * array->extent[didx];
+
+	return dim;
 }
 
@@ -185,4 +299,7 @@
 		rdata_deleg_copy(src->u.deleg_v, &nvar->u.deleg_v);
 		break;
+	case vc_array:
+		rdata_array_copy(src->u.array_v, &nvar->u.array_v);
+		break;
 	case vc_object:
 		rdata_object_copy(src->u.object_v, &nvar->u.object_v);
@@ -215,4 +332,11 @@
 	(void) src; (void) dest;
 	printf("Unimplemented: Copy delegate.\n");
+	exit(1);
+}
+
+static void rdata_array_copy(rdata_array_t *src, rdata_array_t **dest)
+{
+	(void) src; (void) dest;
+	printf("Unimplemented: Copy array.\n");
 	exit(1);
 }
@@ -339,23 +463,48 @@
 void rdata_address_write(rdata_address_t *address, rdata_value_t *value)
 {
+	rdata_var_write(address->vref, value);
+}
+
+/** Write data to a variable.
+ *
+ * Store @a value to variable @a var.
+ */
+void rdata_var_write(rdata_var_t *var, rdata_value_t *value)
+{
 	rdata_var_t *nvar;
-	rdata_var_t *orig_var;
 
 	/* Perform a shallow copy of @c value->var. */
 	rdata_var_copy(value->var, &nvar);
-	orig_var = address->vref;
 
 	/* XXX do this in a prettier way. */
 
-	orig_var->vc = nvar->vc;
+	var->vc = nvar->vc;
 	switch (nvar->vc) {
-	case vc_int: orig_var->u.int_v = nvar->u.int_v; break;
-	case vc_ref: orig_var->u.ref_v = nvar->u.ref_v; break;
-	case vc_deleg: orig_var->u.deleg_v = nvar->u.deleg_v; break;
-	case vc_object: orig_var->u.object_v = nvar->u.object_v; break;
-	default: assert(b_false);
+	case vc_int: var->u.int_v = nvar->u.int_v; break;
+	case vc_string: var->u.string_v = nvar->u.string_v; break;
+	case vc_ref: var->u.ref_v = nvar->u.ref_v; break;
+	case vc_deleg: var->u.deleg_v = nvar->u.deleg_v; break;
+	case vc_array: var->u.array_v = nvar->u.array_v; break;
+	case vc_object: var->u.object_v = nvar->u.object_v; break;
 	}
 
 	/* XXX We should free some stuff around here. */
+}
+
+/** Determine if CSI @a a is derived from CSI described by type item @a tb. */
+bool_t rdata_is_csi_derived_from_ti(stree_csi_t *a, rdata_titem_t *tb)
+{
+	bool_t res;
+
+	switch (tb->tic) {
+	case tic_tcsi:
+		res = stree_is_csi_derived_from_csi(a, tb->u.tcsi->csi);
+		break;
+	default:
+		printf("Error: Base type is not a CSI.\n");
+		exit(1);
+	}
+
+	return res;
 }
 
Index: uspace/app/sbi/src/rdata.h
===================================================================
--- uspace/app/sbi/src/rdata.h	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/app/sbi/src/rdata.h	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -38,8 +38,15 @@
 rdata_ref_t *rdata_ref_new(void);
 rdata_deleg_t *rdata_deleg_new(void);
+rdata_array_t *rdata_array_new(int rank);
 rdata_object_t *rdata_object_new(void);
 rdata_int_t *rdata_int_new(void);
 rdata_string_t *rdata_string_new(void);
 
+rdata_titem_t *rdata_titem_new(titem_class_t tic);
+rdata_tarray_t *rdata_tarray_new(void);
+rdata_tcsi_t *rdata_tcsi_new(void);
+rdata_tprimitive_t *rdata_tprimitive_new(void);
+
+void rdata_array_alloc_element(rdata_array_t *array);
 void rdata_var_copy(rdata_var_t *src, rdata_var_t **dest);
 
@@ -49,4 +56,7 @@
 void rdata_address_read(rdata_address_t *address, rdata_item_t **ritem);
 void rdata_address_write(rdata_address_t *address, rdata_value_t *value);
+void rdata_var_write(rdata_var_t *var, rdata_value_t *value);
+
+bool_t rdata_is_csi_derived_from_ti(stree_csi_t *a, rdata_titem_t *tb);
 
 void rdata_item_print(rdata_item_t *item);
Index: uspace/app/sbi/src/rdata_t.h
===================================================================
--- uspace/app/sbi/src/rdata_t.h	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/app/sbi/src/rdata_t.h	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -68,4 +68,19 @@
 } rdata_deleg_t;
 
+/** Array variable */
+typedef struct {
+	/** Rank */
+	int rank;
+
+	/** Extents (@c rank entries) */
+	int *extent;
+
+	/**
+	 * Elements (extent[0] * extent[1] * ... extent[rank - 1] entries)
+	 * stored in lexicographical order. Each element is (rdata_var_t *).
+	 */
+	struct rdata_var **element;
+} rdata_array_t;
+
 /** Object variable */
 typedef struct {
@@ -89,4 +104,7 @@
 	/** Delegate */
 	vc_deleg,
+
+	/** Array */
+	vc_array,
 
 	/** Object */
@@ -108,4 +126,5 @@
 		rdata_ref_t *ref_v;
 		rdata_deleg_t *deleg_v;
+		rdata_array_t *array_v;
 		rdata_object_t *object_v;
 	} u;
@@ -113,5 +132,5 @@
 
 /** Address item. */
-typedef struct {
+typedef struct rdata_address {
 	/** Targeted variable */
 	rdata_var_t *vref;
@@ -119,5 +138,5 @@
 
 /** Value item. */
-typedef struct {
+typedef struct rdata_value {
 	/**
 	 * Read-only Variable holding a copy of the data. The same @c var
@@ -150,3 +169,47 @@
 } rdata_item_t;
 
+/** Primitive type. */
+typedef struct {
+} rdata_tprimitive_t;
+
+/** Class, struct or interface type. */
+typedef struct {
+	struct stree_csi *csi;
+} rdata_tcsi_t;
+
+/** Array type. */
+typedef struct {
+	/** Base type item */
+	struct rdata_titem *base_ti;
+
+	/** Rank */
+	int rank;
+
+	/** Extents */
+	list_t extents; /* of stree_expr_t */
+} rdata_tarray_t;
+
+/** Generic type. */
+typedef struct {
+} rdata_tgeneric_t;
+
+typedef enum {
+	tic_tprimitive,
+	tic_tcsi,
+	tic_tarray,
+	tic_tgeneric
+} titem_class_t;
+
+/** Type item, the result of evaluating a type expression. */
+typedef struct rdata_titem {
+	titem_class_t tic;
+
+	union {
+		rdata_tprimitive_t *tprimitive;
+		rdata_tcsi_t *tcsi;
+		rdata_tarray_t *tarray;
+		rdata_tgeneric_t *tgeneric;
+	} u;
+} rdata_titem_t;
+
 #endif
Index: uspace/app/sbi/src/run.c
===================================================================
--- uspace/app/sbi/src/run.c	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/app/sbi/src/run.c	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -39,4 +39,5 @@
 #include "rdata.h"
 #include "run_expr.h"
+#include "run_texpr.h"
 #include "stree.h"
 #include "strtab.h"
@@ -51,5 +52,9 @@
 static void run_if(run_t *run, stree_if_t *if_s);
 static void run_while(run_t *run, stree_while_t *while_s);
+static void run_raise(run_t *run, stree_raise_t *raise_s);
 static void run_return(run_t *run, stree_return_t *return_s);
+static void run_wef(run_t *run, stree_wef_t *wef_s);
+
+static bool_t run_exc_match(run_t *run, stree_except_t *except_c);
 
 /** Initialize runner instance. */
@@ -101,4 +106,11 @@
 	run_fun_ar_set_args(run, fun_ar, &main_args);
 	run_fun(run, fun_ar, &res);
+
+	/* Check for unhandled exceptions. */
+	if (run->thread_ar->bo_mode != bm_none) {
+		assert(run->thread_ar->bo_mode == bm_exc);
+		printf("Error: Unhandled exception.\n");
+		exit(1);
+	}
 }
 
@@ -217,10 +229,14 @@
 		run_while(run, stat->u.while_s);
 		break;
+	case st_raise:
+		run_raise(run, stat->u.raise_s);
+		break;
 	case st_return:
 		run_return(run, stat->u.return_s);
 		break;
+	case st_wef:
+		run_wef(run, stat->u.wef_s);
+		break;
 	case st_for:
-	case st_raise:
-	case st_wef:
 		printf("Ignoring unimplemented statement type %d.\n", stat->sc);
 		break;
@@ -331,4 +347,23 @@
 }
 
+/** Run @c raise statement. */
+static void run_raise(run_t *run, stree_raise_t *raise_s)
+{
+	rdata_item_t *rexpr;
+	rdata_item_t *rexpr_vi;
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Executing raise statement.\n");
+#endif
+	run_expr(run, raise_s->expr, &rexpr);
+	rdata_cvt_value_item(rexpr, &rexpr_vi);
+
+	/* Store expression result in thread AR. */
+	run->thread_ar->exc_payload = rexpr_vi->u.value;
+
+	/* Start exception bailout. */
+	run->thread_ar->bo_mode = bm_exc;
+}
+
 /** Run @c return statement. */
 static void run_return(run_t *run, stree_return_t *return_s)
@@ -349,4 +384,116 @@
 	if (run->thread_ar->bo_mode == bm_none)
 		run->thread_ar->bo_mode = bm_fun;
+}
+
+/** Run @c with-except-finally statement. */
+static void run_wef(run_t *run, stree_wef_t *wef_s)
+{
+	list_node_t *except_n;
+	stree_except_t *except_c;
+	rdata_value_t *exc_payload;
+	run_bailout_mode_t bo_mode;
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Executing with-except-finally statement.\n");
+#endif
+	run_block(run, wef_s->with_block);
+
+	if (run->thread_ar->bo_mode == bm_exc) {
+#ifdef DEBUG_RUN_TRACE
+		printf("With statement detected exception.\n");
+#endif
+		/* Reset to normal execution. */
+		run->thread_ar->bo_mode = bm_none;
+
+		/* Look for an except block. */
+		except_n = list_first(&wef_s->except_clauses);
+		while (except_n != NULL) {
+			except_c = list_node_data(except_n, stree_except_t *);
+			if (run_exc_match(run, except_c))
+				break;
+
+			except_n = list_next(&wef_s->except_clauses, except_n);
+		}
+
+		/* If one was found, execute it. */
+		if (except_n != NULL)
+			run_block(run, except_c->block);
+
+		/* Execute finally block */
+		if (wef_s->finally_block != NULL) {
+			/* Put exception on the side temporarily. */
+			bo_mode = run->thread_ar->bo_mode;
+			exc_payload = run->thread_ar->exc_payload;
+
+			run->thread_ar->bo_mode = bm_none;
+			run->thread_ar->exc_payload = NULL;
+
+			run_block(run, wef_s->finally_block);
+
+			if (bo_mode == bm_exc) {
+				/*
+				 * Restore the original exception. If another
+				 * exception occured in the finally block (i.e.
+				 * double fault), it is forgotten.
+				 */
+				run->thread_ar->bo_mode = bm_exc;
+				run->thread_ar->exc_payload = exc_payload;
+			}
+		}
+	}
+
+#ifdef DEBUG_RUN_TRACE
+	printf("With-except-finally statement terminated.\n");
+#endif
+}
+
+/** Determine whether currently active exception matches @c except clause.
+ *
+ * Checks if the currently active exception in the runner object @c run
+ * matches except clause @c except_c. Generates an error if the exception
+ * payload has invalid type (i.e. not an object).
+ *
+ * @param run		Runner object.
+ * @param except_c	@c except clause.
+ * @return		@c b_true if there is a match, @c b_false otherwise.
+ */
+static bool_t run_exc_match(run_t *run, stree_except_t *except_c)
+{
+	rdata_value_t *payload;
+	rdata_var_t *payload_v;
+	rdata_object_t *payload_o;
+	rdata_titem_t *etype;
+
+	payload = run->thread_ar->exc_payload;
+	assert(payload != NULL);
+
+	if (payload->var->vc != vc_ref) {
+		printf("Error: Exception payload must be an object "
+		    "(found type %d).\n", payload->var->vc);
+		exit(1);
+	}
+
+	payload_v = payload->var->u.ref_v->vref;
+	if (payload_v->vc != vc_object) {
+		printf("Error: Exception payload must be an object "
+		    "(found type %d).\n", payload_v->vc);
+		exit(1);
+	}
+
+	payload_o = payload_v->u.object_v;
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Active exception: '");
+	symbol_print_fqn(run->program, payload_o->class_sym);
+	printf("'.\n");
+#endif
+	assert(payload_o->class_sym != NULL);
+	assert(payload_o->class_sym->sc == sc_csi);
+
+	/* Evaluate type expression in except clause. */
+	run_texpr(run, except_c->etype, &etype);
+
+	return rdata_is_csi_derived_from_ti(payload_o->class_sym->u.csi,
+	    etype);
 }
 
@@ -395,4 +542,13 @@
 	node = list_last(&fun_ar->block_ar);
 	return list_node_data(node, run_block_ar_t *);
+}
+
+/** Get current CSI. */
+stree_csi_t *run_get_current_csi(run_t *run)
+{
+	run_fun_ar_t *fun_ar;
+
+	fun_ar = run_get_current_fun_ar(run);
+	return fun_ar->fun_sym->outer_csi;
 }
 
@@ -468,7 +624,12 @@
 	run_block_ar_t *block_ar;
 	list_node_t *rarg_n, *farg_n;
+	list_node_t *cn;
 	rdata_item_t *rarg;
 	stree_fun_arg_t *farg;
 	rdata_var_t *var;
+	rdata_var_t *ref_var;
+	rdata_ref_t *ref;
+	rdata_array_t *array;
+	int n_vargs, idx;
 
 	/* AR should have been created with run_fun_ar_create(). */
@@ -511,4 +672,45 @@
 	}
 
+	if (fun->varg != NULL) {
+		/* Function is variadic. Count number of variadic arguments. */
+		cn = rarg_n;
+		n_vargs = 0;
+		while (cn != NULL) {
+			n_vargs += 1;
+			cn = list_next(args, cn);
+		}
+
+		/* Prepare array to store variadic arguments. */
+		array = rdata_array_new(1);
+		array->extent[0] = n_vargs;
+		rdata_array_alloc_element(array);
+
+		/* Read variadic arguments. */
+
+		idx = 0;
+		while (rarg_n != NULL) {
+			rarg = list_node_data(rarg_n, rdata_item_t *);
+			assert(rarg->ic == ic_value);
+
+			rdata_var_write(array->element[idx], rarg->u.value);
+
+			rarg_n = list_next(args, rarg_n);
+			idx += 1;
+		}
+
+		var = rdata_var_new(vc_array);
+		var->u.array_v = array;
+
+		/* Create reference to the new array. */
+		ref_var = rdata_var_new(vc_ref);
+		ref = rdata_ref_new();
+		ref_var->u.ref_v = ref;
+		ref->vref = var;
+
+		/* Declare variable using name of formal argument. */
+		intmap_set(&block_ar->vars, fun->varg->name->sid,
+		    ref_var);
+	}
+
 	/* Check for excess real parameters. */
 	if (rarg_n != NULL) {
Index: uspace/app/sbi/src/run.h
===================================================================
--- uspace/app/sbi/src/run.h	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/app/sbi/src/run.h	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -41,4 +41,5 @@
 run_fun_ar_t *run_get_current_fun_ar(run_t *run);
 run_block_ar_t *run_get_current_block_ar(run_t *run);
+stree_csi_t *run_get_current_csi(run_t *run);
 
 void run_value_item_to_var(rdata_item_t *item, rdata_var_t **var);
Index: uspace/app/sbi/src/run_expr.c
===================================================================
--- uspace/app/sbi/src/run_expr.c	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/app/sbi/src/run_expr.c	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -36,6 +36,8 @@
 #include "list.h"
 #include "mytypes.h"
+#include "os/os.h"
 #include "rdata.h"
 #include "run.h"
+#include "run_texpr.h"
 #include "symbol.h"
 #include "strtab.h"
@@ -61,4 +63,6 @@
 static void run_binop_int(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
     rdata_value_t *v2, rdata_item_t **res);
+static void run_binop_string(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
+    rdata_value_t *v2, rdata_item_t **res);
 static void run_binop_ref(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
     rdata_value_t *v2, rdata_item_t **res);
@@ -66,4 +70,8 @@
 static void run_unop(run_t *run, stree_unop_t *unop, rdata_item_t **res);
 static void run_new(run_t *run, stree_new_t *new_op, rdata_item_t **res);
+static void run_new_array(run_t *run, stree_new_t *new_op,
+    rdata_titem_t *titem, rdata_item_t **res);
+static void run_new_object(run_t *run, stree_new_t *new_op,
+    rdata_titem_t *titem, rdata_item_t **res);
 
 static void run_access(run_t *run, stree_access_t *access, rdata_item_t **res);
@@ -78,4 +86,5 @@
 
 static void run_call(run_t *run, stree_call_t *call, rdata_item_t **res);
+static void run_index(run_t *run, stree_index_t *index, rdata_item_t **res);
 static void run_assign(run_t *run, stree_assign_t *assign, rdata_item_t **res);
 
@@ -111,4 +120,7 @@
 	case ec_call:
 		run_call(run, expr->u.call, res);
+		break;
+	case ec_index:
+		run_index(run, expr->u.index, res);
 		break;
 	case ec_assign:
@@ -442,4 +454,7 @@
 		run_binop_int(run, binop, v1, v2, res);
 		break;
+	case vc_string:
+		run_binop_string(run, binop, v1, v2, res);
+		break;
 	case vc_ref:
 		run_binop_ref(run, binop, v1, v2, res);
@@ -508,4 +523,43 @@
 }
 
+/** Evaluate binary operation on string arguments. */
+static void run_binop_string(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
+    rdata_value_t *v2, rdata_item_t **res)
+{
+	rdata_item_t *item;
+	rdata_value_t *value;
+	rdata_var_t *var;
+	rdata_string_t *string_v;
+
+	char *s1, *s2;
+
+	(void) run;
+
+	item = rdata_item_new(ic_value);
+	value = rdata_value_new();
+	var = rdata_var_new(vc_string);
+	string_v = rdata_string_new();
+
+	item->u.value = value;
+	value->var = var;
+	var->u.string_v = string_v;
+
+	s1 = v1->var->u.string_v->value;
+	s2 = v2->var->u.string_v->value;
+
+	switch (binop->bc) {
+	case bo_plus:
+		/* Concatenate strings. */
+		string_v->value = os_str_acat(s1, s2);
+		break;
+	default:
+		printf("Error: Invalid binary operation on string "
+		    "arguments (%d).\n", binop->bc);
+		assert(b_false);
+	}
+
+	*res = item;
+}
+
 /** Evaluate binary operation on ref arguments. */
 static void run_binop_ref(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
@@ -566,4 +620,118 @@
 static void run_new(run_t *run, stree_new_t *new_op, rdata_item_t **res)
 {
+	rdata_titem_t *titem;
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Run 'new' operation.\n");
+#endif
+	/* Evaluate type expression */
+	run_texpr(run, new_op->texpr, &titem);
+
+	switch (titem->tic) {
+	case tic_tarray:
+		run_new_array(run, new_op, titem, res);
+		break;
+	case tic_tcsi:
+		run_new_object(run, new_op, titem, res);
+		break;
+	default:
+		printf("Error: Invalid argument to operator 'new', "
+		    "expected object.\n");
+		exit(1);
+	}
+}
+
+/** Create new array. */
+static void run_new_array(run_t *run, stree_new_t *new_op,
+    rdata_titem_t *titem, rdata_item_t **res)
+{
+	rdata_tarray_t *tarray;
+	rdata_array_t *array;
+	rdata_var_t *array_var;
+	rdata_var_t *elem_var;
+
+	rdata_item_t *rexpr, *rexpr_vi;
+	rdata_var_t *rexpr_var;
+
+	stree_expr_t *expr;
+
+	list_node_t *node;
+	int length;
+	int i;
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Create new array.\n");
+#endif
+	(void) run;
+	(void) new_op;
+
+	assert(titem->tic == tic_tarray);
+	tarray = titem->u.tarray;
+
+	/* Create the array. */
+	assert(titem->u.tarray->rank > 0);
+	array = rdata_array_new(titem->u.tarray->rank);
+
+	/* Compute extents. */
+	node = list_first(&tarray->extents);
+	if (node == NULL) {
+		printf("Error: Extents must be specified when constructing "
+		    "an array with 'new'.\n");
+		exit(1);
+	}
+
+	i = 0; length = 1;
+	while (node != NULL) {
+		expr = list_node_data(node, stree_expr_t *);
+
+		/* Evaluate extent argument. */
+		run_expr(run, expr, &rexpr);
+		rdata_cvt_value_item(rexpr, &rexpr_vi);
+		assert(rexpr_vi->ic == ic_value);
+		rexpr_var = rexpr_vi->u.value->var;
+
+		if (rexpr_var->vc != vc_int) {
+			printf("Error: Array extent must be an integer.\n");
+			exit(1);
+		}
+
+#ifdef DEBUG_RUN_TRACE
+		printf("Array extent: %d.\n", rexpr_var->u.int_v->value);
+#endif
+		array->extent[i] = rexpr_var->u.int_v->value;
+		length = length * array->extent[i];
+
+		node = list_next(&tarray->extents, node);
+		i += 1;
+	}
+
+	array->element = calloc(length, sizeof(rdata_var_t *));
+	if (array->element == NULL) {
+		printf("Memory allocation failed.\n");
+		exit(1);
+	}
+
+	/* Create member variables */
+	for (i = 0; i < length; ++i) {
+		/* XXX Depends on member variable type. */
+		elem_var = rdata_var_new(vc_int);
+		elem_var->u.int_v = rdata_int_new();
+		elem_var->u.int_v->value = 0;
+
+		array->element[i] = elem_var;
+	}
+
+	/* Create array variable. */
+	array_var = rdata_var_new(vc_array);
+	array_var->u.array_v = array;
+
+	/* Create reference to the new array. */
+	rdata_reference(array_var, res);
+}
+
+/** Create new object. */
+static void run_new_object(run_t *run, stree_new_t *new_op,
+    rdata_titem_t *titem, rdata_item_t **res)
+{
 	rdata_object_t *obj;
 	rdata_var_t *obj_var;
@@ -578,16 +746,13 @@
 
 #ifdef DEBUG_RUN_TRACE
-	printf("Run 'new' operation.\n");
-#endif
+	printf("Create new object.\n");
+#endif
+	(void) run;
+	(void) new_op;
+
 	/* Lookup object CSI. */
-	/* XXX Should start in the current CSI. */
-	csi_sym = symbol_xlookup_in_csi(run->program, NULL, new_op->texpr);
-	csi = symbol_to_csi(csi_sym);
-	if (csi == NULL) {
-		printf("Error: Symbol '");
-		symbol_print_fqn(run->program, csi_sym);
-		printf("' is not a CSI. CSI required for 'new' operator.\n");
-		exit(1);
-	}
+	assert(titem->tic == tic_tcsi);
+	csi = titem->u.tcsi->csi;
+	csi_sym = csi_to_symbol(csi);
 
 	/* Create the object. */
@@ -875,4 +1040,111 @@
 }
 
+/** Run index operation. */
+static void run_index(run_t *run, stree_index_t *index, rdata_item_t **res)
+{
+	rdata_item_t *rbase;
+	rdata_item_t *base_i;
+	list_node_t *node;
+	stree_expr_t *arg;
+	rdata_item_t *rarg_i, *rarg_vi;
+	rdata_array_t *array;
+	var_class_t vc;
+
+	int i;
+	int elem_index;
+	int arg_val;
+
+	rdata_item_t *ritem;
+	rdata_address_t *address;
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Run index operation.\n");
+#endif
+	run_expr(run, index->base, &rbase);
+
+	switch (rbase->ic) {
+	case ic_value:
+		vc = rbase->u.value->var->vc;
+		break;
+	case ic_address:
+		vc = rbase->u.address->vref->vc;
+		break;
+	default:
+		/* Silence warning. */
+		abort();
+	}
+
+	if (vc != vc_ref) {
+		printf("Error: Base of index operation is not a reference.\n");
+		exit(1);
+	}
+
+	rdata_dereference(rbase, &base_i);
+	assert(base_i->ic == ic_address);
+
+	if (base_i->u.value->var->vc != vc_array) {
+		printf("Error: Indexing something which is not an array.\n");
+		exit(1);
+	}
+
+	array = base_i->u.value->var->u.array_v;
+
+	/* Evaluate arguments (indices). */
+	node = list_first(&index->args);
+
+	/*
+	 * Linear index of the desired element. Elements are stored in
+	 * lexicographic order with the last index changing the fastest.
+	 */
+	elem_index = 0;
+
+	i = 0;
+	while (node != NULL) {
+		if (i >= array->rank) {
+			printf("Error: Too many indices for array of rank %d",
+			    array->rank);
+			exit(1);
+		}
+
+		arg = list_node_data(node, stree_expr_t *);
+		run_expr(run, arg, &rarg_i);
+		rdata_cvt_value_item(rarg_i, &rarg_vi);
+		assert(rarg_vi->ic == ic_value);
+
+		if (rarg_vi->u.value->var->vc != vc_int) {
+			printf("Error: Array index is not an integer.\n");
+			exit(1);
+		}
+
+		arg_val = rarg_vi->u.value->var->u.int_v->value;
+
+		if (arg_val < 0 || arg_val >= array->extent[i]) {
+			printf("Error: Array index (value: %d) is out of range.\n",
+			    arg_val);
+			exit(1);
+		}
+
+		elem_index = elem_index * array->extent[i] + arg_val;
+
+		node = list_next(&index->args, node);
+		i += 1;
+	}
+
+	if (i < array->rank) {
+		printf("Error: Too few indices for array of rank %d",
+		    array->rank);
+		exit(1);
+	}
+
+	/* Construct variable address item. */
+	ritem = rdata_item_new(ic_address);
+	address = rdata_address_new();
+	ritem->u.address = address;
+
+	address->vref = array->element[elem_index];
+
+	*res = ritem;
+}
+
 /** Execute assignment. */
 static void run_assign(run_t *run, stree_assign_t *assign, rdata_item_t **res)
Index: uspace/app/sbi/src/run_t.h
===================================================================
--- uspace/app/sbi/src/run_t.h	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/app/sbi/src/run_t.h	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -74,6 +74,9 @@
 
 	/** Return from function */
-	bm_fun
-} run_bailout_mode;
+	bm_fun,
+
+	/** Exception */
+	bm_exc
+} run_bailout_mode_t;
 
 /** Thread activation record
@@ -86,5 +89,8 @@
 
 	/** Bailout mode */
-	run_bailout_mode bo_mode;
+	run_bailout_mode_t bo_mode;
+
+	/** Exception payload */
+	struct rdata_value *exc_payload;
 } run_thread_ar_t;
 
Index: uspace/app/sbi/src/run_texpr.c
===================================================================
--- uspace/app/sbi/src/run_texpr.c	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
+++ uspace/app/sbi/src/run_texpr.c	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2010 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file Evaluates type expressions. */
+
+#include <stdlib.h>
+#include "list.h"
+#include "mytypes.h"
+#include "rdata.h"
+#include "run.h"
+#include "symbol.h"
+
+#include "run_texpr.h"
+
+static void run_taccess(run_t *run, stree_taccess_t *taccess,
+    rdata_titem_t **res);
+static void run_tindex(run_t *run, stree_tindex_t *tindex,
+    rdata_titem_t **res);
+static void run_tliteral(run_t *run, stree_tliteral_t *tliteral,
+    rdata_titem_t **res);
+static void run_tnameref(run_t *run, stree_tnameref_t *tnameref,
+    rdata_titem_t **res);
+
+void run_texpr(run_t *run, stree_texpr_t *texpr, rdata_titem_t **res)
+{
+	switch (texpr->tc) {
+	case tc_taccess:
+		run_taccess(run, texpr->u.taccess, res);
+		break;
+	case tc_tindex:
+		run_tindex(run, texpr->u.tindex, res);
+		break;
+	case tc_tliteral:
+		run_tliteral(run, texpr->u.tliteral, res);
+		break;
+	case tc_tnameref:
+		run_tnameref(run, texpr->u.tnameref, res);
+		break;
+	case tc_tapply:
+		printf("Unimplemented: Evaluate type expression type %d.\n",
+		    texpr->tc);
+		exit(1);
+	}
+}
+
+static void run_taccess(run_t *run, stree_taccess_t *taccess,
+    rdata_titem_t **res)
+{
+	stree_symbol_t *sym;
+	rdata_titem_t *targ_i;
+	rdata_titem_t *titem;
+	rdata_tcsi_t *tcsi;
+	stree_csi_t *base_csi;
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Evaluating type access operation.\n");
+#endif
+	/* Evaluate base type. */
+	run_texpr(run, taccess->arg, &targ_i);
+
+	if (targ_i->tic != tic_tcsi) {
+		printf("Error: Using '.' with type which is not CSI.\n");
+		exit(1);
+	}
+
+	/* Get base CSI. */
+	base_csi = targ_i->u.tcsi->csi;
+
+	sym = symbol_lookup_in_csi(run->program, base_csi,
+	    taccess->member_name);
+	if (sym->sc != sc_csi) {
+		printf("Error: Symbol '");
+		symbol_print_fqn(run->program, sym);
+		printf("' is not a CSI.\n");
+		exit(1);
+	}
+
+	/* Construct type item. */
+	titem = rdata_titem_new(tic_tcsi);
+	tcsi = rdata_tcsi_new();
+	titem->u.tcsi = tcsi;
+
+	tcsi->csi = sym->u.csi;
+
+	*res = titem;
+}
+
+static void run_tindex(run_t *run, stree_tindex_t *tindex, rdata_titem_t **res)
+{
+	rdata_titem_t *base_ti;
+	rdata_titem_t *titem;
+	rdata_tarray_t *tarray;
+	stree_expr_t *arg_expr;
+	list_node_t *arg_node;
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Evaluating type index operation.\n");
+#endif
+	/* Evaluate base type. */
+	run_texpr(run, tindex->base_type, &base_ti);
+
+	/* Construct type item. */
+	titem = rdata_titem_new(tic_tarray);
+	tarray = rdata_tarray_new();
+	titem->u.tarray = tarray;
+
+	tarray->base_ti = base_ti;
+	tarray->rank = tindex->n_args;
+
+	/* Copy extents. */
+	list_init(&tarray->extents);
+	arg_node = list_first(&tindex->args);
+
+	while (arg_node != NULL) {
+		arg_expr = list_node_data(arg_node, stree_expr_t *);
+		list_append(&tarray->extents, arg_expr);
+		arg_node = list_next(&tindex->args, arg_node);
+	}
+
+	*res = titem;
+}
+
+static void run_tliteral(run_t *run, stree_tliteral_t *tliteral,
+    rdata_titem_t **res)
+{
+	rdata_titem_t *titem;
+	rdata_tprimitive_t *tprimitive;
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Evaluating type literal.\n");
+#endif
+
+	(void) run;
+	(void) tliteral;
+
+	/* Construct type item. */
+	titem = rdata_titem_new(tic_tprimitive);
+	tprimitive = rdata_tprimitive_new();
+	titem->u.tprimitive = tprimitive;
+
+	*res = titem;
+}
+
+static void run_tnameref(run_t *run, stree_tnameref_t *tnameref,
+    rdata_titem_t **res)
+{
+	stree_csi_t *current_csi;
+	stree_symbol_t *sym;
+	rdata_titem_t *titem;
+	rdata_tcsi_t *tcsi;
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Evaluating type name reference.\n");
+#endif
+	current_csi = run_get_current_csi(run);
+	sym = symbol_lookup_in_csi(run->program, current_csi, tnameref->name);
+
+	if (sym->sc != sc_csi) {
+		printf("Error: Symbol '");
+		symbol_print_fqn(run->program, sym);
+		printf("' is not a CSI.\n");
+		exit(1);
+	}
+
+	/* Construct type item. */
+	titem = rdata_titem_new(tic_tcsi);
+	tcsi = rdata_tcsi_new();
+	titem->u.tcsi = tcsi;
+
+	tcsi->csi = sym->u.csi;
+
+	*res = titem;
+}
Index: uspace/app/sbi/src/run_texpr.h
===================================================================
--- uspace/app/sbi/src/run_texpr.h	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
+++ uspace/app/sbi/src/run_texpr.h	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2010 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RUN_TEXPR_H_
+#define RUN_TEXPR_H_
+
+#include "mytypes.h"
+
+void run_texpr(run_t *run, stree_texpr_t *texpr, rdata_titem_t **res);
+
+#endif
Index: uspace/app/sbi/src/stree.c
===================================================================
--- uspace/app/sbi/src/stree.c	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/app/sbi/src/stree.c	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -149,4 +149,18 @@
 }
 
+stree_arg_attr_t *stree_arg_attr_new(arg_attr_class_t aac)
+{
+	stree_arg_attr_t *arg_attr;
+
+	arg_attr = calloc(1, sizeof(stree_arg_attr_t));
+	if (arg_attr == NULL) {
+		printf("Memory allocation failed.\n");
+		exit(1);
+	}
+
+	arg_attr->aac = aac;
+	return arg_attr;
+}
+
 stree_stat_t *stree_stat_new(stat_class_t sc)
 {
@@ -267,4 +281,17 @@
 }
 
+stree_except_t *stree_except_new(void)
+{
+	stree_except_t *except_c;
+
+	except_c = calloc(1, sizeof(stree_except_t));
+	if (except_c == NULL) {
+		printf("Memory allocation failed.\n");
+		exit(1);
+	}
+
+	return except_c;
+}
+
 stree_block_t *stree_block_new(void)
 {
@@ -361,4 +388,17 @@
 }
 
+stree_index_t *stree_index_new(void)
+{
+	stree_index_t *index;
+
+	index = calloc(1, sizeof(stree_index_t));
+	if (index == NULL) {
+		printf("Memory allocation failed.\n");
+		exit(1);
+	}
+
+	return index;
+}
+
 stree_nameref_t *stree_nameref_new(void)
 {
@@ -428,4 +468,17 @@
 }
 
+stree_taccess_t *stree_taccess_new(void)
+{
+	stree_taccess_t *taccess;
+
+	taccess = calloc(1, sizeof(stree_taccess_t));
+	if (taccess == NULL) {
+		printf("Memory allocation failed.\n");
+		exit(1);
+	}
+
+	return taccess;
+}
+
 stree_tapply_t *stree_tapply_new(void)
 {
@@ -441,15 +494,15 @@
 }
 
-stree_taccess_t *stree_taccess_new(void)
-{
-	stree_taccess_t *taccess;
-
-	taccess = calloc(1, sizeof(stree_taccess_t));
-	if (taccess == NULL) {
-		printf("Memory allocation failed.\n");
-		exit(1);
-	}
-
-	return taccess;
+stree_tindex_t *stree_tindex_new(void)
+{
+	stree_tindex_t *tindex;
+
+	tindex = calloc(1, sizeof(stree_tindex_t));
+	if (tindex == NULL) {
+		printf("Memory allocation failed.\n");
+		exit(1);
+	}
+
+	return tindex;
 }
 
@@ -506,2 +559,43 @@
 	return program;
 }
+
+/** Determine if argument @a arg has attribute of class @a aac. */
+bool_t stree_arg_has_attr(stree_fun_arg_t *arg, arg_attr_class_t aac)
+{
+	list_node_t *node;
+	stree_arg_attr_t *attr;
+
+	node = list_first(&arg->attr);
+	while (node != NULL) {
+		attr = list_node_data(node, stree_arg_attr_t *);
+		if (attr->aac == aac)
+			return b_true;
+
+		node = list_next(&arg->attr, node);
+	}
+
+	return b_false;
+}
+
+/** Determine wheter @a a is derived (transitively) from @a b.
+ *
+ * @param a	Derived CSI.
+ * @param b	Base CSI.
+ * @return	@c b_true if @a a is equal to or directly or indirectly
+ *		derived from @a b.
+ */
+bool_t stree_is_csi_derived_from_csi(stree_csi_t *a, stree_csi_t *b)
+{
+	stree_csi_t *csi;
+
+	csi = a;
+	while (csi != NULL) {
+		if (csi == b)
+			return b_true;
+
+		csi = csi->base_csi;
+	}
+
+	/* We went all the way to the root and did not find b. */
+	return b_false;
+}
Index: uspace/app/sbi/src/stree.h
===================================================================
--- uspace/app/sbi/src/stree.h	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/app/sbi/src/stree.h	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -41,4 +41,5 @@
 
 stree_fun_arg_t *stree_fun_arg_new(void);
+stree_arg_attr_t *stree_arg_attr_new(arg_attr_class_t aac);
 
 stree_stat_t *stree_stat_new(stat_class_t sc);
@@ -51,4 +52,6 @@
 stree_wef_t *stree_wef_new(void);
 stree_exps_t *stree_exps_new(void);
+
+stree_except_t *stree_except_new(void);
 stree_block_t *stree_block_new(void);
 
@@ -59,4 +62,5 @@
 stree_access_t *stree_access_new(void);
 stree_call_t *stree_call_new(void);
+stree_index_t *stree_index_new(void);
 stree_nameref_t *stree_nameref_new(void);
 
@@ -66,6 +70,7 @@
 
 stree_texpr_t *stree_texpr_new(texpr_class_t tc);
+stree_taccess_t *stree_taccess_new(void);
 stree_tapply_t *stree_tapply_new(void);
-stree_taccess_t *stree_taccess_new(void);
+stree_tindex_t *stree_tindex_new(void);
 stree_tliteral_t *stree_tliteral_new(void);
 stree_tnameref_t *stree_tnameref_new(void);
@@ -74,3 +79,6 @@
 stree_program_t *stree_program_new(void);
 
+bool_t stree_arg_has_attr(stree_fun_arg_t *arg, arg_attr_class_t aac);
+bool_t stree_is_csi_derived_from_csi(stree_csi_t *a, stree_csi_t *b);
+
 #endif
Index: uspace/app/sbi/src/stree_t.h
===================================================================
--- uspace/app/sbi/src/stree_t.h	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/app/sbi/src/stree_t.h	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -151,4 +151,13 @@
 } stree_assign_t;
 
+/** Indexing operation */
+typedef struct {
+	/** Base */
+	struct stree_expr *base;
+
+	/** Arguments (indices) */
+	list_t args; /* of stree_expr_t */
+} stree_index_t;
+
 /** Arithmetic expression class */
 typedef enum {
@@ -161,5 +170,6 @@
 	ec_access,
 	ec_call,
-	ec_assign
+	ec_assign,
+	ec_index
 } expr_class_t;
 
@@ -177,4 +187,5 @@
 		stree_access_t *access;
 		stree_call_t *call;
+		stree_index_t *index;
 		stree_assign_t *assign;
 	} u;
@@ -217,4 +228,19 @@
 } stree_tapply_t;
 
+/** Type index operation */
+typedef struct {
+	/** Base type */
+	struct stree_texpr *base_type;
+
+	/**
+	 * Number of arguments (rank). Needed when only rank is specified
+	 * and @c args are not used.
+	 */
+	int n_args;
+
+	/** Arguments (extents) */
+	list_t args; /* of stree_expr_t */
+} stree_tindex_t;
+
 /** Type expression class */
 typedef enum {
@@ -222,5 +248,6 @@
 	tc_tnameref,
 	tc_taccess,
-	tc_tapply
+	tc_tapply,
+	tc_tindex
 } texpr_class_t;
 
@@ -234,4 +261,5 @@
 		stree_taccess_t *taccess;
 		stree_tapply_t *tapply;
+		stree_tindex_t *tindex;
 	} u;
 } stree_texpr_t;
@@ -252,4 +280,11 @@
 	stree_texpr_t *type;
 } stree_vdecl_t;
+
+/** @c except clause */
+typedef struct {
+	stree_ident_t *evar;
+	stree_texpr_t *etype;
+	stree_block_t *block;
+} stree_except_t;
 
 /** If statement */
@@ -273,4 +308,5 @@
 /** Raise statement */
 typedef struct {
+	stree_expr_t *expr;
 } stree_raise_t;
 
@@ -288,7 +324,8 @@
 typedef struct {
 	stree_block_t *with_block;
-	list_t except_blocks; /* of stree_block_t */
+	list_t except_clauses; /* of stree_except_t */
 	stree_block_t *finally_block;
 } stree_wef_t;
+
 
 /** Statement class */
@@ -320,4 +357,15 @@
 } stree_stat_t;
 
+/** Argument attribute class */
+typedef enum {
+	/** Packed argument (for variadic functions) */
+	aac_packed
+} arg_attr_class_t;
+
+/** Argument atribute */
+typedef struct {
+	arg_attr_class_t aac;
+} stree_arg_attr_t;
+
 /** Formal function parameter */
 typedef struct {
@@ -327,4 +375,7 @@
 	/* Argument type */
 	stree_texpr_t *type;
+
+	/* Attributes */
+	list_t attr; /* of stree_arg_attr_t */
 } stree_fun_arg_t;
 
@@ -339,4 +390,7 @@
 	/** Formal parameters */
 	list_t args; /* of stree_fun_arg_t */
+
+	/** Variadic argument or @c NULL if none. */
+	stree_fun_arg_t *varg;
 
 	/** Return type */
@@ -400,4 +454,7 @@
 	stree_texpr_t *base_csi_ref;
 
+	/** Base CSI. Only available when ancr_state == ws_visited. */
+	struct stree_csi *base_csi;
+
 	/** Node state for ancr walks. */
 	walk_state_t ancr_state;
Index: uspace/app/sbi/src/strtab.c
===================================================================
--- uspace/app/sbi/src/strtab.c	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/app/sbi/src/strtab.c	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -37,5 +37,5 @@
 #include <string.h>
 #include "mytypes.h"
-#include "compat.h"
+#include "os/os.h"
 #include "list.h"
 
@@ -59,5 +59,5 @@
 	while (node != NULL) {
 		++sid;
-		if (strcmp(str, list_node_data(node, char *)) == 0)
+		if (os_str_cmp(str, list_node_data(node, char *)) == 0)
 			return sid;
 
@@ -66,5 +66,5 @@
 
 	++sid;
-	list_append(&str_list, strdup(str));
+	list_append(&str_list, os_str_dup(str));
 
 	return sid;
@@ -85,5 +85,5 @@
 	if (node == NULL) {
 		printf("Internal error: Invalid SID %d", sid);
-		exit(1);
+		abort();
 	}
 
Index: uspace/dist/sysel/array.sy
===================================================================
--- uspace/dist/sysel/array.sy	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
+++ uspace/dist/sysel/array.sy	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -0,0 +1,46 @@
+--
+-- Copyright (c) 2010 Jiri Svoboda
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+--
+-- o Redistributions of source code must retain the above copyright
+--   notice, this list of conditions and the following disclaimer.
+-- o Redistributions in binary form must reproduce the above copyright
+--   notice, this list of conditions and the following disclaimer in the
+--   documentation and/or other materials provided with the distribution.
+-- o The name of the author may not be used to endorse or promote products
+--   derived from this software without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+-- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+-- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+
+class ArrayDemo is
+	fun Main() is
+		var a : int[,];
+		var i : int;
+
+		a = new int[3, 2];
+
+		a[0, 0] = 1;
+		a[1, 0] = 2;
+		a[2, 0] = 3;
+
+		i = 0;
+		while i < 3 do
+			Builtin.WriteLine(a[i, 0]);
+			i = i + 1;
+		end
+	end
+end
Index: uspace/dist/sysel/count.sy
===================================================================
--- uspace/dist/sysel/count.sy	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/dist/sysel/count.sy	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -1,2 +1,30 @@
+--
+-- Copyright (c) 2010 Jiri Svoboda
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+--
+-- o Redistributions of source code must retain the above copyright
+--   notice, this list of conditions and the following disclaimer.
+-- o Redistributions in binary form must reproduce the above copyright
+--   notice, this list of conditions and the following disclaimer in the
+--   documentation and/or other materials provided with the distribution.
+-- o The name of the author may not be used to endorse or promote products
+--   derived from this software without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+-- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+-- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+
 class CountDemo is
 	fun Count(a : int; b : int) is
Index: uspace/dist/sysel/except.sy
===================================================================
--- uspace/dist/sysel/except.sy	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
+++ uspace/dist/sysel/except.sy	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -0,0 +1,53 @@
+--
+-- Copyright (c) 2010 Jiri Svoboda
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+--
+-- o Redistributions of source code must retain the above copyright
+--   notice, this list of conditions and the following disclaimer.
+-- o Redistributions in binary form must reproduce the above copyright
+--   notice, this list of conditions and the following disclaimer in the
+--   documentation and/or other materials provided with the distribution.
+-- o The name of the author may not be used to endorse or promote products
+--   derived from this software without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+-- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+-- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+
+class ExceptionDemo is
+	fun foo() : int is
+	        Builtin.WriteLine("Entered foo().");
+		raise new BaseException();
+	end
+
+	fun Main() is
+		do
+			foo();
+			foo();
+		except e : DerivedException do
+			Builtin.WriteLine("Caught derived exception.");
+		except e : BaseException do
+			Builtin.WriteLine("Caught base exception.");
+		finally do
+			Builtin.WriteLine("Finally.");
+		end
+	end
+end
+
+class BaseException is
+end
+
+class DerivedException : BaseException is
+end
Index: uspace/dist/sysel/hello.sy
===================================================================
--- uspace/dist/sysel/hello.sy	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/dist/sysel/hello.sy	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -1,2 +1,30 @@
+--
+-- Copyright (c) 2010 Jiri Svoboda
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+--
+-- o Redistributions of source code must retain the above copyright
+--   notice, this list of conditions and the following disclaimer.
+-- o Redistributions in binary form must reproduce the above copyright
+--   notice, this list of conditions and the following disclaimer in the
+--   documentation and/or other materials provided with the distribution.
+-- o The name of the author may not be used to endorse or promote products
+--   derived from this software without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+-- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+-- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+
 class HelloWorld is
 	fun Main() is
Index: uspace/dist/sysel/hexec.sy
===================================================================
--- uspace/dist/sysel/hexec.sy	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
+++ uspace/dist/sysel/hexec.sy	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -0,0 +1,34 @@
+--
+-- Copyright (c) 2010 Jiri Svoboda
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+--
+-- o Redistributions of source code must retain the above copyright
+--   notice, this list of conditions and the following disclaimer.
+-- o Redistributions in binary form must reproduce the above copyright
+--   notice, this list of conditions and the following disclaimer in the
+--   documentation and/or other materials provided with the distribution.
+-- o The name of the author may not be used to endorse or promote products
+--   derived from this software without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+-- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+-- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+
+class HelenOSExecDemo is
+	fun Main() is
+		Builtin.Exec("/app/tester");
+		Builtin.Exec("/app/tester", "print1");
+	end
+end
Index: uspace/dist/sysel/inherit.sy
===================================================================
--- uspace/dist/sysel/inherit.sy	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/dist/sysel/inherit.sy	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -1,2 +1,30 @@
+--
+-- Copyright (c) 2010 Jiri Svoboda
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+--
+-- o Redistributions of source code must retain the above copyright
+--   notice, this list of conditions and the following disclaimer.
+-- o Redistributions in binary form must reproduce the above copyright
+--   notice, this list of conditions and the following disclaimer in the
+--   documentation and/or other materials provided with the distribution.
+-- o The name of the author may not be used to endorse or promote products
+--   derived from this software without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+-- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+-- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+
 class A is
 	fun Foo() is
Index: uspace/dist/sysel/list.sy
===================================================================
--- uspace/dist/sysel/list.sy	(revision fa36f294e6a3f5cc4a846e9b33621971e0cc3d07)
+++ uspace/dist/sysel/list.sy	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -1,30 +1,29 @@
-
-class ListNode is
-	var value : int;
-
-	var prev : ListNode;
-	var next : ListNode;
-	var head : ListNode;
-
-	fun GetNext() : ListNode is
-		if next != head then
-			return next;
-		else
-			return nil;
-		end
-	end
-
-	fun GetPrev() : ListNode is
-		if prev != head then
-			return next;
-		else
-			return nil;
-		end
-	end
-
-	fun GetValue() : int is
-		return value;
-	end
-end
+--
+-- Copyright (c) 2010 Jiri Svoboda
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+--
+-- o Redistributions of source code must retain the above copyright
+--   notice, this list of conditions and the following disclaimer.
+-- o Redistributions in binary form must reproduce the above copyright
+--   notice, this list of conditions and the following disclaimer in the
+--   documentation and/or other materials provided with the distribution.
+-- o The name of the author may not be used to endorse or promote products
+--   derived from this software without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+-- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+-- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
 
 class List is
@@ -59,4 +58,32 @@
 end
 
+class ListNode is
+	var value : int;
+
+	var prev : ListNode;
+	var next : ListNode;
+	var head : ListNode;
+
+	fun GetNext() : ListNode is
+		if next != head then
+			return next;
+		else
+			return nil;
+		end
+	end
+
+	fun GetPrev() : ListNode is
+		if prev != head then
+			return next;
+		else
+			return nil;
+		end
+	end
+
+	fun GetValue() : int is
+		return value;
+	end
+end
+
 class ListDemo is
 	fun Main() is
Index: uspace/dist/sysel/string.sy
===================================================================
--- uspace/dist/sysel/string.sy	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
+++ uspace/dist/sysel/string.sy	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -0,0 +1,34 @@
+--
+-- Copyright (c) 2010 Jiri Svoboda
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+--
+-- o Redistributions of source code must retain the above copyright
+--   notice, this list of conditions and the following disclaimer.
+-- o Redistributions in binary form must reproduce the above copyright
+--   notice, this list of conditions and the following disclaimer in the
+--   documentation and/or other materials provided with the distribution.
+-- o The name of the author may not be used to endorse or promote products
+--   derived from this software without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+-- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+-- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+
+class StringDemo is
+	fun Main() is
+		-- Concatenate some strings.
+		Builtin.WriteLine("One-" + "two-" + "three!");
+	end
+end
Index: uspace/dist/sysel/varargs.sy
===================================================================
--- uspace/dist/sysel/varargs.sy	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
+++ uspace/dist/sysel/varargs.sy	(revision 94d484ac742127ae8d87a7e0bb630fafe11f65be)
@@ -0,0 +1,51 @@
+--
+-- Copyright (c) 2010 Jiri Svoboda
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+--
+-- o Redistributions of source code must retain the above copyright
+--   notice, this list of conditions and the following disclaimer.
+-- o Redistributions in binary form must reproduce the above copyright
+--   notice, this list of conditions and the following disclaimer in the
+--   documentation and/or other materials provided with the distribution.
+-- o The name of the author may not be used to endorse or promote products
+--   derived from this software without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+-- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+-- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+
+class VariadicArgumentsDemo is
+	--- Variadic function example.
+	--
+	-- A variadic function is declared by marking its last argument
+	-- with the attribute 'packed'.
+	--
+	-- Note that we need to pass 'n' just because the array type
+	-- does not implement the Length property yet.
+	--
+	fun Print(n : int; args : string[], packed) is
+		var i : int;
+
+		i = 0;
+		while i < n do
+			Builtin.WriteLine(args[i]);
+			i = i + 1;
+		end
+	end
+
+	fun Main() is
+		Print(5, "One", "Two", "Three", "Four", "Five");
+	end
+end
