Index: uspace/app/sbi/src/p_expr.c
===================================================================
--- uspace/app/sbi/src/p_expr.c	(revision 074444f189ee9356421b26e70454fae61c81def3)
+++ uspace/app/sbi/src/p_expr.c	(revision 051bc69a7034999d45c93c61a56e515474aa78e3)
@@ -32,4 +32,5 @@
 #include <stdlib.h>
 #include "bigint.h"
+#include "cspan.h"
 #include "debug.h"
 #include "lex.h"
@@ -43,4 +44,6 @@
 
 static stree_expr_t *parse_assign(parse_t *parse);
+static stree_expr_t *parse_disjunctive(parse_t *parse);
+static stree_expr_t *parse_conjunctive(parse_t *parse);
 static stree_expr_t *parse_comparative(parse_t *parse);
 static stree_expr_t *parse_additive(parse_t *parse);
@@ -95,5 +98,5 @@
 	stree_assign_t *assign;
 
-	a = parse_comparative(parse);
+	a = parse_disjunctive(parse);
 
 	switch (lcur_lc(parse)) {
@@ -109,5 +112,5 @@
 
 	lskip(parse);
-	b = parse_comparative(parse);
+	b = parse_disjunctive(parse);
 
 	assign->dest = a;
@@ -116,5 +119,81 @@
 	tmp = stree_expr_new(ec_assign);
 	tmp->u.assign = assign;
+	tmp->cspan = cspan_merge(a->cspan, b->cspan);
+
+	assign->expr = tmp;
+
 	return tmp;
+}
+
+/** Parse disjunctive expression.
+ *
+ * @param parse		Parser object.
+ */
+static stree_expr_t *parse_disjunctive(parse_t *parse)
+{
+	stree_expr_t *a, *b, *tmp;
+	stree_binop_t *binop;
+	cspan_t *cs;
+
+	a = parse_conjunctive(parse);
+	cs = a->cspan;
+
+	while (lcur_lc(parse) == lc_or) {
+		if (parse_is_error(parse))
+			break;
+
+		lskip(parse);
+		b = parse_conjunctive(parse);
+
+		binop = stree_binop_new(bo_or);
+		binop->arg1 = a;
+		binop->arg2 = b;
+
+		tmp = stree_expr_new(ec_binop);
+		tmp->u.binop = binop;
+		tmp->cspan = cspan_merge(cs, b->cspan);
+		binop->expr = tmp;
+
+		a = tmp;
+		cs = tmp->cspan;
+	}
+
+	return a;
+}
+
+/** Parse conjunctive expression.
+ *
+ * @param parse		Parser object.
+ */
+static stree_expr_t *parse_conjunctive(parse_t *parse)
+{
+	stree_expr_t *a, *b, *tmp;
+	stree_binop_t *binop;
+	cspan_t *cs;
+
+	a = parse_comparative(parse);
+	cs = a->cspan;
+
+	while (lcur_lc(parse) == lc_and) {
+		if (parse_is_error(parse))
+			break;
+
+		lskip(parse);
+		b = parse_comparative(parse);
+
+		binop = stree_binop_new(bo_and);
+		binop->arg1 = a;
+		binop->arg2 = b;
+
+		tmp = stree_expr_new(ec_binop);
+		tmp->u.binop = binop;
+		tmp->cspan = cspan_merge(cs, b->cspan);
+		binop->expr = tmp;
+
+		a = tmp;
+		cs = tmp->cspan;
+	}
+
+	return a;
 }
 
@@ -128,6 +207,8 @@
 	stree_binop_t *binop;
 	binop_class_t bc;
+	cspan_t *cs;
 
 	a = parse_additive(parse);
+	cs = a->cspan;
 
 	while (lcur_lc(parse) == lc_equal || lcur_lc(parse) == lc_notequal ||
@@ -157,5 +238,9 @@
 		tmp = stree_expr_new(ec_binop);
 		tmp->u.binop = binop;
+		tmp->cspan = cspan_merge(cs, b->cspan);
+		binop->expr = tmp;
+
 		a = tmp;
+		cs = tmp->cspan;
 	}
 
@@ -172,6 +257,9 @@
 	stree_binop_t *binop;
 	binop_class_t bc;
+	cspan_t *cs;
 
 	a = parse_multip(parse);
+	cs = a->cspan;
+
 	while (lcur_lc(parse) == lc_plus || lcur_lc(parse) == lc_minus) {
 		if (parse_is_error(parse))
@@ -193,5 +281,9 @@
 		tmp = stree_expr_new(ec_binop);
 		tmp->u.binop = binop;
+		tmp->cspan = cspan_merge(cs, b->cspan);
+		binop->expr = tmp;
+
 		a = tmp;
+		cs = tmp->cspan;
 	}
 
@@ -208,6 +300,9 @@
 	stree_binop_t *binop;
 	binop_class_t bc;
+	cspan_t *cs;
 
 	a = parse_prefix(parse);
+	cs = a->cspan;
+
 	while (lcur_lc(parse) == lc_mult) {
 		if (parse_is_error(parse))
@@ -228,5 +323,9 @@
 		tmp = stree_expr_new(ec_binop);
 		tmp->u.binop = binop;
+		tmp->cspan = cspan_merge(cs, b->cspan);
+		binop->expr = tmp;
+
 		a = tmp;
+		cs = tmp->cspan;
 	}
 
@@ -244,8 +343,10 @@
 	stree_unop_t *unop;
 	unop_class_t uc;
+	cspan_t *cs0;
 
 	switch (lcur_lc(parse)) {
 	case lc_plus:
 	case lc_minus:
+	case lc_not:
 		if (parse_is_error(parse))
 			return parse_recovery_expr(parse);
@@ -254,7 +355,9 @@
 		case lc_plus: uc = uo_plus; break;
 		case lc_minus: uc = uo_minus; break;
+		case lc_not: uc = uo_not; break;
 		default: assert(b_false);
 		}
 
+		cs0 = lcur_span(parse);
 		lskip(parse);
 		a = parse_postfix(parse);
@@ -265,4 +368,6 @@
 		tmp = stree_expr_new(ec_unop);
 		tmp->u.unop = unop;
+		tmp->cspan = cspan_merge(cs0, a->cspan);
+		unop->expr = tmp;
 		a = tmp;
 		break;
@@ -287,13 +392,13 @@
 	stree_new_t *new_op;
 	stree_expr_t *expr;
-
+	stree_expr_t *arg;
+	cspan_t *cs0, *cs1;
+
+	cs0 = lcur_span(parse);
 	lmatch(parse, lc_new);
 	texpr = parse_texpr(parse);
 
-	/* Parenthesis should be present except for arrays. */
-	if (texpr->tc != tc_tindex) {
-		lmatch(parse, lc_lparen);
-		lmatch(parse, lc_rparen);
-	}
+	/* XXX Take span from texpr */
+	cs1 = lprev_span(parse);
 
 	new_op = stree_new_new();
@@ -302,4 +407,30 @@
 	expr->u.new_op = new_op;
 
+	list_init(&new_op->ctor_args);
+
+	/* Parenthesized arguments should be present except for arrays. */
+	if (texpr->tc != tc_tindex) {
+		lmatch(parse, lc_lparen);
+
+		/* Parse constructor arguments */
+
+		if (lcur_lc(parse) != lc_rparen) {
+			while (!parse_is_error(parse)) {
+				arg = parse_expr(parse);
+				list_append(&new_op->ctor_args, arg);
+
+				if (lcur_lc(parse) == lc_rparen)
+					break;
+				lmatch(parse, lc_comma);
+			}
+		}
+
+		lmatch(parse, lc_rparen);
+		cs1 = cspan_merge(cs0, lprev_span(parse));
+	}
+
+	expr->cspan = cspan_merge(cs0, cs1);
+	new_op->expr = expr;
+
 	return expr;
 }
@@ -354,7 +485,11 @@
 	stree_expr_t *expr;
 	stree_access_t *access;
+	cspan_t *cs1;
 
 	lmatch(parse, lc_period);
 	ident = parse_ident(parse);
+
+	/* XXX Take span from ident */
+	cs1 = lprev_span(parse);
 
 	access = stree_access_new();
@@ -364,4 +499,7 @@
 	expr = stree_expr_new(ec_access);
 	expr->u.access = access;
+	expr->cspan = cspan_merge(a->cspan, cs1);
+
+	access->expr = expr;
 
 	return expr;
@@ -377,4 +515,5 @@
 	stree_call_t *call;
 	stree_expr_t *arg;
+	cspan_t *cs1;
 
 	lmatch(parse, lc_lparen);
@@ -398,7 +537,10 @@
 
 	lmatch(parse, lc_rparen);
+	cs1 = lprev_span(parse);
 
 	expr = stree_expr_new(ec_call);
 	expr->u.call = call;
+	expr->cspan = cspan_merge(a->cspan, cs1);
+	call->expr = expr;
 
 	return expr;
@@ -414,4 +556,5 @@
 	stree_index_t *index;
 	stree_expr_t *arg;
+	cspan_t *cs1;
 
 	lmatch(parse, lc_lsbr);
@@ -435,7 +578,10 @@
 
 	lmatch(parse, lc_rsbr);
+	cs1 = lprev_span(parse);
 
 	expr = stree_expr_new(ec_index);
 	expr->u.index = index;
+	expr->cspan = cspan_merge(a->cspan, cs1);
+	index->expr = expr;
 
 	return expr;
@@ -451,13 +597,21 @@
 	stree_texpr_t *texpr;
 	stree_as_t *as_op;
+	cspan_t *cs1;
 
 	lmatch(parse, lc_as);
 	texpr = parse_texpr(parse);
+
+	/* XXX Take span from texpr */
+	cs1 = lprev_span(parse);
 
 	as_op = stree_as_new();
 	as_op->arg = a;
 	as_op->dtype = texpr;
+
 	expr = stree_expr_new(ec_as);
 	expr->u.as_op = as_op;
+	expr->cspan = cspan_merge(a->cspan, cs1);
+
+	as_op->expr = expr;
 
 	return expr;
@@ -471,9 +625,14 @@
 {
 	stree_expr_t *expr;
+	cspan_t *cs0, *cs1;
 
 	if (lcur_lc(parse) == lc_lparen) {
+		cs0 = lcur_span(parse);
 		lskip(parse);
 		expr = parse_expr(parse);
 		lmatch(parse, lc_rparen);
+		cs1 = lprev_span(parse);
+
+		expr->cspan = cspan_merge(cs0, cs1);
 	} else {
 		expr = parse_primitive(parse);
@@ -482,5 +641,4 @@
 	return expr;
 }
-
 
 /** Parse primitive expression.
@@ -536,4 +694,6 @@
 	expr = stree_expr_new(ec_nameref);
 	expr->u.nameref = nameref;
+	expr->cspan = lprev_span(parse);
+	nameref->expr = expr;
 
 	return expr;
@@ -563,4 +723,6 @@
 	expr = stree_expr_new(ec_literal);
 	expr->u.literal = literal;
+	expr->cspan = lprev_span(parse);
+	literal->expr = expr;
 
 	return expr;
@@ -586,4 +748,6 @@
 	expr = stree_expr_new(ec_literal);
 	expr->u.literal = literal;
+	expr->cspan = lprev_span(parse);
+	literal->expr = expr;
 
 	return expr;
@@ -609,4 +773,6 @@
 	expr = stree_expr_new(ec_literal);
 	expr->u.literal = literal;
+	expr->cspan = lprev_span(parse);
+	literal->expr = expr;
 
 	return expr;
@@ -628,4 +794,6 @@
 	expr = stree_expr_new(ec_literal);
 	expr->u.literal = literal;
+	expr->cspan = lprev_span(parse);
+	literal->expr = expr;
 
 	return expr;
@@ -650,4 +818,6 @@
 	expr = stree_expr_new(ec_literal);
 	expr->u.literal = literal;
+	expr->cspan = lprev_span(parse);
+	literal->expr = expr;
 
 	return expr;
@@ -669,4 +839,6 @@
 	expr = stree_expr_new(ec_self_ref);
 	expr->u.self_ref = self_ref;
+	expr->cspan = lprev_span(parse);
+	self_ref->expr = expr;
 
 	return expr;
@@ -688,5 +860,6 @@
 	expr = stree_expr_new(ec_literal);
 	expr->u.literal = literal;
-
-	return expr;
-}
+	literal->expr = expr;
+
+	return expr;
+}
