Skip to content

Commit 29987b5

Browse files
committed
Move 'as' precedence up to just above relational; support indexing str and vec by all integral types. Closes #94.
1 parent 718c0b5 commit 29987b5

File tree

6 files changed

+67
-37
lines changed

6 files changed

+67
-37
lines changed

src/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,7 @@ TEST_XFAILS_LLVM := $(TASK_XFAILS) \
464464
i8-incr.rs \
465465
import.rs \
466466
inner-module.rs \
467+
integral-indexing.rs \
467468
iter-range.rs \
468469
iter-ret.rs \
469470
large-records.rs \

src/boot/be/x86.ml

+12-7
Original file line numberDiff line numberDiff line change
@@ -1936,15 +1936,20 @@ let zero (dst:Il.cell) (count:Il.operand) : Asm.frag =
19361936
;;
19371937

19381938
let mov (signed:bool) (dst:Il.cell) (src:Il.operand) : Asm.frag =
1939-
if is_ty8 (Il.cell_scalar_ty dst) || is_ty8 (Il.operand_scalar_ty src)
1939+
if is_ty8 (Il.cell_scalar_ty dst)
19401940
then
19411941
begin
1942-
(match dst with
1943-
Il.Reg (Il.Hreg r, _)
1944-
-> assert (is_ok_r8 r) | _ -> ());
1945-
(match src with
1946-
Il.Cell (Il.Reg (Il.Hreg r, _))
1947-
-> assert (is_ok_r8 r) | _ -> ());
1942+
match dst with
1943+
Il.Reg (Il.Hreg r, _) -> assert (is_ok_r8 r)
1944+
| _ -> ()
1945+
end;
1946+
1947+
if is_ty8 (Il.operand_scalar_ty src)
1948+
then
1949+
begin
1950+
match src with
1951+
Il.Cell (Il.Reg (Il.Hreg r, _)) -> assert (is_ok_r8 r)
1952+
| _ -> ()
19481953
end;
19491954

19501955
match (signed, dst, src) with

src/boot/fe/pexp.ml

+25-25
Original file line numberDiff line numberDiff line change
@@ -817,11 +817,33 @@ and parse_or_pexp (ps:pstate) : pexp =
817817
step lhs
818818

819819

820+
and parse_as_pexp (ps:pstate) : pexp =
821+
let apos = lexpos ps in
822+
let pexp = ctxt "as pexp" parse_or_pexp ps in
823+
let rec step accum =
824+
match peek ps with
825+
AS ->
826+
bump ps;
827+
let tapos = lexpos ps in
828+
let t = parse_ty ps in
829+
let bpos = lexpos ps in
830+
let t = span ps tapos bpos t in
831+
let node =
832+
span ps apos bpos
833+
(PEXP_unop ((Ast.UNOP_cast t), accum))
834+
in
835+
step node
836+
837+
| _ -> accum
838+
in
839+
step pexp
840+
841+
820842
and parse_relational_pexp (ps:pstate) : pexp =
821843
let name = "relational pexp" in
822844
let apos = lexpos ps in
823-
let lhs = ctxt (name ^ " lhs") parse_or_pexp ps in
824-
let build = binop_build ps name apos parse_or_pexp in
845+
let lhs = ctxt (name ^ " lhs") parse_as_pexp ps in
846+
let build = binop_build ps name apos parse_as_pexp in
825847
let rec step accum =
826848
match peek ps with
827849
LT -> build accum step Ast.BINOP_lt
@@ -883,30 +905,8 @@ and parse_oror_pexp (ps:pstate) : pexp =
883905
step lhs
884906

885907

886-
and parse_as_pexp (ps:pstate) : pexp =
887-
let apos = lexpos ps in
888-
let pexp = ctxt "as pexp" parse_oror_pexp ps in
889-
let rec step accum =
890-
match peek ps with
891-
AS ->
892-
bump ps;
893-
let tapos = lexpos ps in
894-
let t = parse_ty ps in
895-
let bpos = lexpos ps in
896-
let t = span ps tapos bpos t in
897-
let node =
898-
span ps apos bpos
899-
(PEXP_unop ((Ast.UNOP_cast t), accum))
900-
in
901-
step node
902-
903-
| _ -> accum
904-
in
905-
step pexp
906-
907-
908908
and parse_pexp (ps:pstate) : pexp =
909-
parse_as_pexp ps
909+
parse_oror_pexp ps
910910

911911
and parse_mutable_and_pexp (ps:pstate) : (Ast.mutability * pexp) =
912912
let mutability = parse_mutability ps in

src/boot/me/trans.ml

+2-1
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,8 @@ let trans_visitor
914914
let atop = trans_atom at in
915915
let unit_sz = ty_sz_in_current_frame ty in
916916
let idx = next_vreg_cell word_sty in
917-
emit (Il.binary Il.UMUL idx atop unit_sz);
917+
mov idx atop;
918+
emit (Il.binary Il.UMUL idx (Il.Cell idx) unit_sz);
918919
let elt_mem = trans_bounds_check (deref cell) (Il.Cell idx) in
919920
(Il.Mem (elt_mem, referent_type abi ty), ty)
920921
in

src/boot/me/type.ml

+5-4
Original file line numberDiff line numberDiff line change
@@ -380,19 +380,20 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
380380
sprintf_itype ()
381381

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

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

390391
| `Type Ast.TY_str, Ast.COMP_atom atom ->
391-
demand Ast.TY_int (check_atom atom);
392+
demand_integer (check_atom atom);
392393
LTYPE_mono (Ast.TY_mach Common.TY_u8)
393394

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

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

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// This is a testcase for issue #94.
2+
3+
fn main() {
4+
5+
let vec[int] v = vec(0, 1, 2, 3, 4, 5);
6+
let str s = "abcdef";
7+
check (v.(3u) == 3);
8+
check (v.(3u8) == 3);
9+
check (v.(3i8) == 3);
10+
check (v.(3u32) == 3);
11+
check (v.(3i32) == 3);
12+
13+
log v.(3u8);
14+
15+
check (s.(3u) == 'd' as u8);
16+
check (s.(3u8) == 'd' as u8);
17+
check (s.(3i8) == 'd' as u8);
18+
check (s.(3u32) == 'd' as u8);
19+
check (s.(3i32) == 'd' as u8);
20+
21+
log s.(3u8);
22+
}

0 commit comments

Comments
 (0)