Move 'as' precedence up to just above relational; support indexing str and vec by all integral types. Closes #94.
This commit is contained in:
parent
718c0b5963
commit
29987b56e1
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
22
src/test/run-pass/integral-indexing.rs
Normal file
22
src/test/run-pass/integral-indexing.rs
Normal 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user