Skip to content

Commit

Permalink
Move 'as' precedence up to just above relational; support indexing st…
Browse files Browse the repository at this point in the history
…r and vec by all integral types. Closes rust-lang#94.
  • Loading branch information
graydon committed Aug 5, 2010
1 parent 718c0b5 commit 29987b5
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 37 deletions.
1 change: 1 addition & 0 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,7 @@ TEST_XFAILS_LLVM := $(TASK_XFAILS) \
i8-incr.rs \
import.rs \
inner-module.rs \
integral-indexing.rs \
iter-range.rs \
iter-ret.rs \
large-records.rs \
Expand Down
19 changes: 12 additions & 7 deletions src/boot/be/x86.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1936,15 +1936,20 @@ let zero (dst:Il.cell) (count:Il.operand) : Asm.frag =
;;

let mov (signed:bool) (dst:Il.cell) (src:Il.operand) : Asm.frag =
if is_ty8 (Il.cell_scalar_ty dst) || is_ty8 (Il.operand_scalar_ty src)
if is_ty8 (Il.cell_scalar_ty dst)
then
begin
(match dst with
Il.Reg (Il.Hreg r, _)
-> assert (is_ok_r8 r) | _ -> ());
(match src with
Il.Cell (Il.Reg (Il.Hreg r, _))
-> assert (is_ok_r8 r) | _ -> ());
match dst with
Il.Reg (Il.Hreg r, _) -> assert (is_ok_r8 r)
| _ -> ()
end;

if is_ty8 (Il.operand_scalar_ty src)
then
begin
match src with
Il.Cell (Il.Reg (Il.Hreg r, _)) -> assert (is_ok_r8 r)
| _ -> ()
end;

match (signed, dst, src) with
Expand Down
50 changes: 25 additions & 25 deletions src/boot/fe/pexp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -817,11 +817,33 @@ and parse_or_pexp (ps:pstate) : pexp =
step lhs


and parse_as_pexp (ps:pstate) : pexp =
let apos = lexpos ps in
let pexp = ctxt "as pexp" parse_or_pexp ps in
let rec step accum =
match peek ps with
AS ->
bump ps;
let tapos = lexpos ps in
let t = parse_ty ps in
let bpos = lexpos ps in
let t = span ps tapos bpos t in
let node =
span ps apos bpos
(PEXP_unop ((Ast.UNOP_cast t), accum))
in
step node

| _ -> accum
in
step pexp


and parse_relational_pexp (ps:pstate) : pexp =
let name = "relational pexp" in
let apos = lexpos ps in
let lhs = ctxt (name ^ " lhs") parse_or_pexp ps in
let build = binop_build ps name apos parse_or_pexp in
let lhs = ctxt (name ^ " lhs") parse_as_pexp ps in
let build = binop_build ps name apos parse_as_pexp in
let rec step accum =
match peek ps with
LT -> build accum step Ast.BINOP_lt
Expand Down Expand Up @@ -883,30 +905,8 @@ and parse_oror_pexp (ps:pstate) : pexp =
step lhs


and parse_as_pexp (ps:pstate) : pexp =
let apos = lexpos ps in
let pexp = ctxt "as pexp" parse_oror_pexp ps in
let rec step accum =
match peek ps with
AS ->
bump ps;
let tapos = lexpos ps in
let t = parse_ty ps in
let bpos = lexpos ps in
let t = span ps tapos bpos t in
let node =
span ps apos bpos
(PEXP_unop ((Ast.UNOP_cast t), accum))
in
step node

| _ -> accum
in
step pexp


and parse_pexp (ps:pstate) : pexp =
parse_as_pexp ps
parse_oror_pexp ps

and parse_mutable_and_pexp (ps:pstate) : (Ast.mutability * pexp) =
let mutability = parse_mutability ps in
Expand Down
3 changes: 2 additions & 1 deletion src/boot/me/trans.ml
Original file line number Diff line number Diff line change
Expand Up @@ -914,7 +914,8 @@ let trans_visitor
let atop = trans_atom at in
let unit_sz = ty_sz_in_current_frame ty in
let idx = next_vreg_cell word_sty in
emit (Il.binary Il.UMUL idx atop unit_sz);
mov idx atop;
emit (Il.binary Il.UMUL idx (Il.Cell idx) unit_sz);
let elt_mem = trans_bounds_check (deref cell) (Il.Cell idx) in
(Il.Mem (elt_mem, referent_type abi ty), ty)
in
Expand Down
9 changes: 5 additions & 4 deletions src/boot/me/type.ml
Original file line number Diff line number Diff line change
Expand Up @@ -380,19 +380,20 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
sprintf_itype ()

| `Type (Ast.TY_vec ty_vec), Ast.COMP_atom atom ->
demand Ast.TY_int (check_atom atom);
demand_integer (check_atom atom);
LTYPE_mono ty_vec

| `Type (Ast.TY_vec _), _ ->
Common.err None "the vector type '%a' must be indexed via an int"
Common.err None
"the vector type '%a' must be indexed by an integral type"
sprintf_itype ()

| `Type Ast.TY_str, Ast.COMP_atom atom ->
demand Ast.TY_int (check_atom atom);
demand_integer (check_atom atom);
LTYPE_mono (Ast.TY_mach Common.TY_u8)

| `Type Ast.TY_str, _ ->
Common.err None "strings must be indexed via an int"
Common.err None "strings must be indexed by an integral type"

| `Type (Ast.TY_box ty_box), Ast.COMP_deref -> LTYPE_mono ty_box

Expand Down
22 changes: 22 additions & 0 deletions src/test/run-pass/integral-indexing.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// This is a testcase for issue #94.

fn main() {

let vec[int] v = vec(0, 1, 2, 3, 4, 5);
let str s = "abcdef";
check (v.(3u) == 3);
check (v.(3u8) == 3);
check (v.(3i8) == 3);
check (v.(3u32) == 3);
check (v.(3i32) == 3);

log v.(3u8);

check (s.(3u) == 'd' as u8);
check (s.(3u8) == 'd' as u8);
check (s.(3i8) == 'd' as u8);
check (s.(3u32) == 'd' as u8);
check (s.(3i32) == 'd' as u8);

log s.(3u8);
}

0 comments on commit 29987b5

Please sign in to comment.