Move 'as' precedence up to just above relational; support indexing str and vec by all integral types. Closes #94.

This commit is contained in:
Graydon Hoare 2010-08-05 10:04:11 -07:00
parent 718c0b5963
commit 29987b56e1
6 changed files with 67 additions and 37 deletions

View File

@ -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 \

View File

@ -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

View File

@ -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
@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}