Index: uspace/app/sbi/src/run_expr.c
===================================================================
--- uspace/app/sbi/src/run_expr.c	(revision 1ebc1a62b0e759c001488fc0e221be6347082167)
+++ uspace/app/sbi/src/run_expr.c	(revision ecb6ac3260db8fa03e8e388fb729beb20587181b)
@@ -32,4 +32,5 @@
 #include <stdlib.h>
 #include <assert.h>
+#include "bigint.h"
 #include "debug.h"
 #include "intmap.h"
@@ -71,4 +72,7 @@
 
 static void run_unop(run_t *run, stree_unop_t *unop, rdata_item_t **res);
+static void run_unop_int(run_t *run, stree_unop_t *unop, rdata_value_t *val,
+    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,
@@ -349,5 +353,5 @@
 	value->var = var;
 	var->u.int_v = int_v;
-	int_v->value = lit_int->value;
+	bigint_clone(&lit_int->value, &int_v->value);
 
 	*res = item;
@@ -436,8 +440,19 @@
 #endif
 	run_expr(run, binop->arg1, &rarg1_i);
+	if (run_is_bo(run)) {
+		*res = NULL;
+		return;
+	}
+
 	run_expr(run, binop->arg2, &rarg2_i);
+	if (run_is_bo(run)) {
+		*res = NULL;
+		return;
+	}
 
 	switch (binop->bc) {
 	case bo_plus:
+	case bo_minus:
+	case bo_mult:
 	case bo_equal:
 	case bo_notequal:
@@ -496,5 +511,8 @@
 	rdata_int_t *int_v;
 
-	int i1, i2;
+	bigint_t *i1, *i2;
+	bigint_t diff;
+	bool_t done;
+	bool_t zf, nf;
 
 	(void) run;
@@ -509,30 +527,54 @@
 	var->u.int_v = int_v;
 
-	i1 = v1->var->u.int_v->value;
-	i2 = v2->var->u.int_v->value;
+	i1 = &v1->var->u.int_v->value;
+	i2 = &v2->var->u.int_v->value;
+
+	done = b_true;
 
 	switch (binop->bc) {
 	case bo_plus:
-		int_v->value = i1 + i2;
-		break;
+		bigint_add(i1, i2, &int_v->value);
+		break;
+	case bo_minus:
+		bigint_sub(i1, i2, &int_v->value);
+		break;
+	case bo_mult:
+		bigint_mul(i1, i2, &int_v->value);
+		break;
+	default:
+		done = b_false;
+		break;
+	}
+
+	if (done) {
+		*res = item;
+		return;
+	}
+
+	/* Relational operation. */
+
+	bigint_sub(i1, i2, &diff);
+	zf = bigint_is_zero(&diff);
+	nf = bigint_is_negative(&diff);
 
 	/* XXX We should have a real boolean type. */
+	switch (binop->bc) {
 	case bo_equal:
-		int_v->value = (i1 == i2) ? 1 : 0;
+		bigint_init(&int_v->value, zf ? 1 : 0);
 		break;
 	case bo_notequal:
-		int_v->value = (i1 != i2) ? 1 : 0;
+		bigint_init(&int_v->value, !zf ? 1 : 0);
 		break;
 	case bo_lt:
-		int_v->value = (i1 < i2) ? 1 : 0;
+		bigint_init(&int_v->value, (!zf && nf) ? 1 : 0);
 		break;
 	case bo_gt:
-		int_v->value = (i1 > i2) ? 1 : 0;
+		bigint_init(&int_v->value, (!zf && !nf) ? 1 : 0);
 		break;
 	case bo_lt_equal:
-		int_v->value = (i1 <= i2) ? 1 : 0;
+		bigint_init(&int_v->value, (zf || nf) ? 1 : 0);
 		break;
 	case bo_gt_equal:
-		int_v->value = (i1 >= i2) ? 1 : 0;
+		bigint_init(&int_v->value, !nf ? 1 : 0);
 		break;
 	default:
@@ -610,8 +652,8 @@
 	/* XXX We should have a real boolean type. */
 	case bo_equal:
-		int_v->value = (ref1 == ref2) ? 1 : 0;
+		bigint_init(&int_v->value, (ref1 == ref2) ? 1 : 0);
 		break;
 	case bo_notequal:
-		int_v->value = (ref1 != ref2) ? 1 : 0;
+		bigint_init(&int_v->value, (ref1 != ref2) ? 1 : 0);
 		break;
 	default:
@@ -628,12 +670,70 @@
 static void run_unop(run_t *run, stree_unop_t *unop, rdata_item_t **res)
 {
-	rdata_item_t *rarg;
+	rdata_item_t *rarg_i;
+	rdata_item_t *rarg_vi;
+	rdata_value_t *val;
 
 #ifdef DEBUG_RUN_TRACE
 	printf("Run unary operation.\n");
 #endif
-	run_expr(run, unop->arg, &rarg);
-	*res = NULL;
-}
+	run_expr(run, unop->arg, &rarg_i);
+	if (run_is_bo(run)) {
+		*res = NULL;
+		return;
+	}
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Check unop argument result.\n");
+#endif
+	run_cvt_value_item(run, rarg_i, &rarg_vi);
+
+	val = rarg_vi->u.value;
+
+	switch (val->var->vc) {
+	case vc_int:
+		run_unop_int(run, unop, val, res);
+		break;
+	default:
+		printf("Unimplemented: Unrary operation argument of "
+		    "type %d.\n", val->var->vc);
+		run_raise_error(run);
+		*res = NULL;
+		break;
+	}
+}
+
+/** Evaluate unary operation on int argument. */
+static void run_unop_int(run_t *run, stree_unop_t *unop, rdata_value_t *val,
+    rdata_item_t **res)
+{
+	rdata_item_t *item;
+	rdata_value_t *value;
+	rdata_var_t *var;
+	rdata_int_t *int_v;
+
+	(void) run;
+
+	item = rdata_item_new(ic_value);
+	value = rdata_value_new();
+	var = rdata_var_new(vc_int);
+	int_v = rdata_int_new();
+
+	item->u.value = value;
+	value->var = var;
+	var->u.int_v = int_v;
+
+	switch (unop->uc) {
+	case uo_plus:
+	        bigint_clone(&val->var->u.int_v->value, &int_v->value);
+		break;
+	case uo_minus:
+		bigint_reverse_sign(&val->var->u.int_v->value,
+		    &int_v->value);
+		break;
+	}
+
+	*res = item;
+}
+
 
 /** Evaluate @c new operation. */
@@ -680,4 +780,6 @@
 	int length;
 	int i;
+	int rc;
+	int iextent;
 
 #ifdef DEBUG_RUN_TRACE
@@ -708,4 +810,9 @@
 		/* Evaluate extent argument. */
 		run_expr(run, expr, &rexpr);
+		if (run_is_bo(run)) {
+			*res = NULL;
+			return;
+		}
+
 		run_cvt_value_item(run, rexpr, &rexpr_vi);
 		assert(rexpr_vi->ic == ic_value);
@@ -718,7 +825,16 @@
 
 #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;
+		printf("Array extent: ");
+		bigint_print(&rexpr_var->u.int_v->value);
+		printf(".\n");
+#endif
+		rc = bigint_get_value_int(&rexpr_var->u.int_v->value,
+		    &iextent);
+		if (rc != EOK) {
+			printf("Memory allocation failed (big int used).\n");
+			exit(1);
+		}
+
+		array->extent[i] = iextent;
 		length = length * array->extent[i];
 
@@ -738,5 +854,5 @@
 		elem_var = rdata_var_new(vc_int);
 		elem_var->u.int_v = rdata_int_new();
-		elem_var->u.int_v->value = 0;
+		bigint_init(&elem_var->u.int_v->value, 0);
 
 		array->element[i] = elem_var;
@@ -755,19 +871,9 @@
     tdata_item_t *titem, rdata_item_t **res)
 {
-	rdata_object_t *obj;
-	rdata_var_t *obj_var;
-
-	stree_symbol_t *csi_sym;
 	stree_csi_t *csi;
-	stree_csimbr_t *csimbr;
-
-	rdata_var_t *mbr_var;
-
-	list_node_t *node;
 
 #ifdef DEBUG_RUN_TRACE
 	printf("Create new object.\n");
 #endif
-	(void) run;
 	(void) new_op;
 
@@ -775,33 +881,7 @@
 	assert(titem->tic == tic_tobject);
 	csi = titem->u.tobject->csi;
-	csi_sym = csi_to_symbol(csi);
-
-	/* Create the object. */
-	obj = rdata_object_new();
-	obj->class_sym = csi_sym;
-	intmap_init(&obj->fields);
-
-	obj_var = rdata_var_new(vc_object);
-	obj_var->u.object_v = obj;
-
-	/* Create object fields. */
-	node = list_first(&csi->members);
-	while (node != NULL) {
-		csimbr = list_node_data(node, stree_csimbr_t *);
-		if (csimbr->cc == csimbr_var) {
-			/* XXX Depends on member variable type. */
-			mbr_var = rdata_var_new(vc_int);
-			mbr_var->u.int_v = rdata_int_new();
-			mbr_var->u.int_v->value = 0;
-
-			intmap_set(&obj->fields, csimbr->u.var->name->sid,
-			    mbr_var);
-		}
-
-		node = list_next(&csi->members, node);
-	}
-
-	/* Create reference to the new object. */
-	run_reference(run, obj_var, res);
+
+	/* Create CSI instance. */
+	run_new_csi_inst(run, csi, res);
 }
 
@@ -815,4 +895,9 @@
 #endif
 	run_expr(run, access->arg, &rarg);
+	if (run_is_bo(run)) {
+		*res = NULL;
+		return;
+    	}
+
 	if (rarg == NULL) {
 		printf("Error: Sub-expression has no value.\n");
@@ -1028,4 +1113,8 @@
 #endif
 	run_expr(run, call->fun, &rfun);
+	if (run_is_bo(run)) {
+		*res = NULL;
+		return;
+	}
 
 	if (run->thread_ar->bo_mode != bm_none) {
@@ -1058,4 +1147,9 @@
 		arg = list_node_data(node, stree_expr_t *);
 		run_expr(run, arg, &rarg_i);
+		if (run_is_bo(run)) {
+			*res = NULL;
+			return;
+		}
+
 		run_cvt_value_item(run, rarg_i, &rarg_vi);
 
@@ -1096,4 +1190,8 @@
 #endif
 	run_expr(run, index->base, &rbase);
+	if (run_is_bo(run)) {
+		*res = NULL;
+		return;
+	}
 
 	vc = run_item_get_vc(run, rbase);
@@ -1115,4 +1213,9 @@
 		arg = list_node_data(node, stree_expr_t *);
 		run_expr(run, arg, &rarg_i);
+		if (run_is_bo(run)) {
+			*res = NULL;
+			return;
+		}
+
 		run_cvt_value_item(run, rarg_i, &rarg_vi);
 
@@ -1149,4 +1252,5 @@
 	int elem_index;
 	int arg_val;
+	int rc;
 
 	rdata_item_t *ritem;
@@ -1189,10 +1293,16 @@
 		}
 
-		arg_val = arg->u.value->var->u.int_v->value;
-
-		if (arg_val < 0 || arg_val >= array->extent[i]) {
+		rc = bigint_get_value_int(
+		    &arg->u.value->var->u.int_v->value,
+		    &arg_val);
+
+		if (rc != EOK || arg_val < 0 || arg_val >= array->extent[i]) {
+#ifdef DEBUG_RUN_TRACE
 			printf("Error: Array index (value: %d) is out of range.\n",
 			    arg_val);
-			run_raise_error(run);
+#endif
+			/* Raise Error.OutOfBounds */
+			run_raise_exc(run,
+			    run->program->builtin->error_outofbounds);
 			*res = run_recovery_item(run);
 			return;
@@ -1307,5 +1417,5 @@
 	int elem_index;
 	int arg_val;
-	int rc;
+	int rc1, rc2;
 
 	rdata_value_t *value;
@@ -1322,5 +1432,5 @@
 	run_cvt_value_item(run, base, &base_vi);
 	assert(base_vi->u.value->var->vc == vc_string);
-	string = base->u.value->var->u.string_v;
+	string = base_vi->u.value->var->u.string_v;
 
 	/*
@@ -1346,5 +1456,8 @@
 		}
 
-		arg_val = arg->u.value->var->u.int_v->value;
+		rc1 = bigint_get_value_int(
+		    &arg->u.value->var->u.int_v->value,
+		    &arg_val);
+
 		elem_index = arg_val;
 
@@ -1358,6 +1471,8 @@
 	}
 
-	rc = os_str_get_char(string->value, elem_index, &cval);
-	if (rc != EOK) {
+	if (rc1 == EOK)
+		rc2 = os_str_get_char(string->value, elem_index, &cval);
+
+	if (rc1 != EOK || rc2 != EOK) {
 		printf("Error: String index (value: %d) is out of range.\n",
 		    arg_val);
@@ -1372,5 +1487,5 @@
 	cvar = rdata_var_new(vc_int);
 	cvar->u.int_v = rdata_int_new();
-	cvar->u.int_v->value = cval;
+	bigint_init(&cvar->u.int_v->value, cval);
 	value->var = cvar;
 
@@ -1389,5 +1504,14 @@
 #endif
 	run_expr(run, assign->dest, &rdest_i);
+	if (run_is_bo(run)) {
+		*res = NULL;
+		return;
+	}
+
 	run_expr(run, assign->src, &rsrc_i);
+	if (run_is_bo(run)) {
+		*res = NULL;
+		return;
+	}
 
 	run_cvt_value_item(run, rsrc_i, &rsrc_vi);
@@ -1423,4 +1547,8 @@
 #endif
 	run_expr(run, as_op->arg, &rarg_i);
+	if (run_is_bo(run)) {
+		*res = NULL;
+		return;
+	}
 
 	/*
@@ -1467,4 +1595,54 @@
 
 	*res = rarg_vi;
+}
+
+/** Create new CSI instance. */
+void run_new_csi_inst(run_t *run, stree_csi_t *csi, rdata_item_t **res)
+{
+	rdata_object_t *obj;
+	rdata_var_t *obj_var;
+
+	stree_symbol_t *csi_sym;
+	stree_csimbr_t *csimbr;
+
+	rdata_var_t *mbr_var;
+
+	list_node_t *node;
+
+	csi_sym = csi_to_symbol(csi);
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Create new instance of CSI '");
+	symbol_print_fqn(csi_sym);
+	printf("'.\n");
+#endif
+
+	/* Create the object. */
+	obj = rdata_object_new();
+	obj->class_sym = csi_sym;
+	intmap_init(&obj->fields);
+
+	obj_var = rdata_var_new(vc_object);
+	obj_var->u.object_v = obj;
+
+	/* Create object fields. */
+	node = list_first(&csi->members);
+	while (node != NULL) {
+		csimbr = list_node_data(node, stree_csimbr_t *);
+		if (csimbr->cc == csimbr_var) {
+			/* XXX Depends on member variable type. */
+			mbr_var = rdata_var_new(vc_int);
+			mbr_var->u.int_v = rdata_int_new();
+			bigint_init(&mbr_var->u.int_v->value, 0);
+
+			intmap_set(&obj->fields, csimbr->u.var->name->sid,
+			    mbr_var);
+		}
+
+		node = list_next(&csi->members, node);
+	}
+
+	/* Create reference to the new object. */
+	run_reference(run, obj_var, res);
 }
 
@@ -1492,4 +1670,4 @@
 	}
 
-	return (var->u.int_v->value != 0);
-}
+	return !bigint_is_zero(&var->u.int_v->value);
+}
