Merge branch 'master' of git://github.com/graydon/rust

This commit is contained in:
Lindsey Kuper 2011-03-18 12:32:54 -07:00
commit 6dee1ac161
43 changed files with 1836 additions and 724 deletions

402
Makefile.in Normal file
View file

@ -0,0 +1,402 @@
######################################################################
# Residual auto-configuration
######################################################################
include config.mk
MKFILES := Makefile config.mk
ifneq ($(MAKE_RESTARTS),)
CFG_INFO := $(info cfg: make restarts: $(MAKE_RESTARTS))
endif
CFG_INFO := $(info cfg: building on $(CFG_OSTYPE) $(CFG_CPUTYPE))
CFG_GCC_CFLAGS :=
CFG_GCC_LINK_FLAGS :=
CFG_BOOT_FLAGS := $(BOOT_FLAGS)
CFG_RUSTC_FLAGS := -nowarn
# On Darwin, we need to run dsymutil so the debugging information ends
# up in the right place. On other platforms, it automatically gets
# embedded into the executable, so use a no-op command.
CFG_DSYMUTIL := true
ifeq ($(CFG_OSTYPE), FreeBSD)
LIB := lib$(1).so
CFG_GCC_CFLAGS += -fPIC -march=i686 -I/usr/local/include
CFG_GCC_LINK_FLAGS += -shared -fPIC -lpthread -lrt
ifeq ($(CFG_CPUTYPE), x86_64)
CFG_GCC_CFLAGS += -m32
CFG_GCC_LINK_FLAGS += -m32
endif
CFG_UNIXY := 1
endif
ifeq ($(CFG_OSTYPE), Linux)
LIB := lib$(1).so
CFG_GCC_CFLAGS += -fPIC -march=i686
CFG_GCC_LINK_FLAGS += -shared -fPIC -ldl -lpthread -lrt
ifeq ($(CFG_CPUTYPE), x86_64)
CFG_GCC_CFLAGS += -m32
CFG_GCC_LINK_FLAGS += -m32
endif
CFG_UNIXY := 1
endif
ifeq ($(CFG_OSTYPE), Darwin)
LIB := lib$(1).dylib
CFG_UNIXY := 1
CFG_GCC_LINK_FLAGS += -dynamiclib -lpthread
# Darwin has a very blurry notion of "64 bit", and claims it's running
# "on an i386" when the whole userspace is 64-bit and the compiler
# emits 64-bit binaries by default. So we just force -m32 here. Smarter
# approaches welcome!
CFG_GCC_CFLAGS += -m32
CFG_GCC_LINK_FLAGS += -m32
CFG_DSYMUTIL := dsymutil
endif
ifneq ($(findstring MINGW,$(CFG_OSTYPE)),)
CFG_WINDOWSY := 1
endif
ifdef CFG_WINDOWSY
CFG_INFO := $(info cfg: windows-y environment)
CFG_EXE_SUFFIX := .exe
CFG_LIB_NAME=$(1).dll
CFG_RUN_PROGRAM=$(1)
CFG_PATH_MUNGE := | sed -e 's/\\\(.\)/\/\1/g'
ifdef CFG_FLEXLINK
CFG_BOOT_NATIVE := 1
endif
CFG_GCC_CFLAGS += -march=i686
CFG_GCC_LINK_FLAGS += -shared -fPIC
endif
ifdef CFG_UNIXY
CFG_INFO := $(info cfg: unix-y environment)
CFG_EXE_SUFFIX :=
CFG_RUN_PROGRAM = LD_LIBRARY_PATH=$(dir $(1)) $(CFG_VALGRIND) $(1)
CFG_BOOT_NATIVE := 1
ifdef MINGW_CROSS
CFG_EXE_SUFFIX := .exe
CFG_LIB_NAME=$(1).dll
CFG_RUN_PROGRAM=$(1)
CFG_INFO := $(info cfg: mingw-cross)
CFG_GCC_CROSS := i586-mingw32msvc-
CFG_BOOT_FLAGS += -t win32-x86-pe
ifdef CFG_VALGRIND
CFG_VALGRIND += wine
endif
CFG_GCC_CFLAGS := -march=i686
CFG_GCC_LINK_FLAGS := -shared
ifeq ($(CFG_CPUTYPE), x86_64)
CFG_GCC_CFLAGS += -m32
CFG_GCC_LINK_FLAGS += -m32
endif
endif
ifdef CFG_VALGRIND
CFG_VALGRIND += --leak-check=full \
--error-exitcode=1 \
--quiet --vex-iropt-level=0 \
--suppressions=etc/x86.supp
endif
endif
CFG_RUNTIME :=$(call CFG_LIB_NAME,rustrt)
CFG_LLVMEXT :=$(call CFG_LIB_NAME,llvmext)
CFG_STDLIB :=$(call CFG_LIB_NAME,std)
ifdef CFG_GCC
CFG_INFO := $(info cfg: using gcc)
CFG_GCC_CFLAGS += -Wall -Werror -fno-rtti -fno-exceptions -g
CFG_GCC_LINK_FLAGS += -g
CFG_COMPILE_C = $(CFG_GCC_CROSS)g++ $(CFG_GCC_CFLAGS) -c -o $(1) $(2)
CFG_LINK_C = $(CFG_GCC_CROSS)g++ $(CFG_GCC_LINK_FLAGS) -o $(1)
CFG_DEPEND_C = $(CFG_GCC_CROSS)g++ $(CFG_GCC_CFLAGS) -MT "$(1)" -MM $(2)
else
CFG_ERR := $(error please try on a system with gcc)
endif
ifdef CFG_OCAMLC_OPT
$(info cfg: have ocaml native compiler)
OPT=.opt
else
$(info cfg: have only ocaml bytecode compiler)
endif
ifdef BOOT_PROFILE
$(info cfg: forcing native bootstrap compiler (BOOT_PROFILE))
CFG_BOOT_NATIVE := 1
CFG_OCAMLOPT_PROFILE_FLAGS := -p
endif
ifdef BOOT_DEBUG
$(info cfg: forcing bytecode bootstrap compiler (DEBUG))
CFG_BOOT_NATIVE :=
endif
ifdef CFG_BOOT_NATIVE
$(info cfg: building native bootstrap compiler)
else
$(info cfg: building bytecode bootstrap compiler)
endif
ifdef NO_VALGRIND
$(info cfg: disabling valgrind (NO_VALGRIND))
CFG_VALGRIND :=
endif
######################################################################
# Target-and-rule "utility variables"
######################################################################
ifdef VERBOSE
Q :=
E =
else
Q := @
E = echo $(1)
endif
R := $(CFG_RUN_PROGRAM)
S := $(CFG_SRC_DIR)
X := $(CFG_EXE_SUFFIX)
# Look in doc and src dirs.
VPATH := $(S)doc $(S)src
# Compilers we build, we now know how to run.
BOOT := $(Q)OCAMLRUNPARAM="b1" boot/rustboot$(X) $(CFG_BOOT_FLAGS)
STAGE0 := $(Q)stage0/rustc$(X) $(CFG_RUSTC_FLAGS)
STAGE1 := $(Q)stage1/rustc$(X) $(CFG_RUSTC_FLAGS)
STAGE2 := $(Q)stage2/rustc$(X) $(CFG_RUSTC_FLAGS)
# "Source" files we generate in builddir along the way.
GENERATED := boot/fe/lexer.ml boot/version.ml
# Delete the built-in rules.
.SUFFIXES:
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
######################################################################
# Bootstrap compiler variables
######################################################################
# We must list them in link order.
# Nobody calculates the link-order DAG automatically, sadly.
BOOT_MLS := \
$(addsuffix .ml, \
boot/version \
$(addprefix boot/util/, fmt common bits) \
$(addprefix boot/driver/, session) \
$(addprefix boot/fe/, ast token lexer parser \
extfmt pexp item cexp fuzz) \
$(addprefix boot/be/, asm il abi) \
$(addprefix boot/me/, walk semant resolve alias \
simplify type dead layer effect typestate \
loop layout transutil trans dwarf) \
$(addprefix boot/be/, x86 ra pe elf macho) \
$(addprefix boot/driver/, lib glue main)) \
BOOT_CMOS := $(BOOT_MLS:.ml=.cmo)
BOOT_CMXS := $(BOOT_MLS:.ml=.cmx)
BOOT_OBJS := $(BOOT_MLS:.ml=.o)
BOOT_CMIS := $(BOOT_MLS:.ml=.cmi)
BS := $(S)/src/boot/
BOOT_ML_DEP_INCS := -I $(BS)/fe -I $(BS)/me \
-I $(BS)/be -I $(BS)/driver \
-I $(BS)/util -I boot
BOOT_ML_INCS := -I boot/fe -I boot/me \
-I boot/be -I boot/driver \
-I boot/util -I boot
BOOT_ML_LIBS := unix.cma nums.cma bigarray.cma
BOOT_ML_NATIVE_LIBS := unix.cmxa nums.cmxa bigarray.cmxa
BOOT_OCAMLC_FLAGS := -g $(BOOT_ML_INCS) -w Ael -warn-error Ael
BOOT_OCAMLOPT_FLAGS := -g $(BOOT_ML_INCS) -w Ael -warn-error Ael
######################################################################
# Runtime (C++) library variables
######################################################################
RUNTIME_CS := rt/sync/timer.cpp \
rt/sync/sync.cpp \
rt/sync/lock_and_signal.cpp \
rt/rust.cpp \
rt/rust_builtin.cpp \
rt/rust_run_program.cpp \
rt/rust_crate.cpp \
rt/rust_crate_cache.cpp \
rt/rust_crate_reader.cpp \
rt/rust_comm.cpp \
rt/rust_dom.cpp \
rt/rust_task.cpp \
rt/rust_task_list.cpp \
rt/rust_proxy.cpp \
rt/rust_chan.cpp \
rt/rust_port.cpp \
rt/rust_upcall.cpp \
rt/rust_log.cpp \
rt/rust_message.cpp \
rt/rust_timer.cpp \
rt/circular_buffer.cpp \
rt/isaac/randport.cpp \
rt/rust_srv.cpp \
rt/rust_kernel.cpp \
rt/memory_region.cpp \
rt/test/rust_test_harness.cpp \
rt/test/rust_test_runtime.cpp \
rt/test/rust_test_util.cpp
RUNTIME_HDR := rt/globals.h \
rt/rust.h \
rt/rust_dwarf.h \
rt/rust_internal.h \
rt/rust_util.h \
rt/rust_chan.h \
rt/rust_port.h \
rt/rust_dom.h \
rt/rust_task.h \
rt/rust_task_list.h \
rt/rust_proxy.h \
rt/rust_log.h \
rt/rust_message.h \
rt/circular_buffer.h \
rt/util/array_list.h \
rt/util/indexed_list.h \
rt/util/synchronized_indexed_list.h \
rt/util/hash_map.h \
rt/sync/sync.h \
rt/sync/timer.h \
rt/sync/lock_free_queue.h \
rt/rust_srv.h \
rt/rust_kernel.h \
rt/memory_region.h \
rt/memory.h \
rt/test/rust_test_harness.h \
rt/test/rust_test_runtime.h \
rt/test/rust_test_util.h
RUNTIME_INCS := -I $(S)src/rt/isaac -I $(S)src/rt/uthash
RUNTIME_OBJS := $(RUNTIME_CS:.cpp=.o)
######################################################################
# rustc LLVM-extensions (C++) library variables
######################################################################
LLVMEXT_CS := $(addprefix llvmext/, \
MachOObjectFile.cpp Object.cpp RustWrapper.cpp)
LLVMEXT_HDR := llvmext/include/llvm-c/Object.h
LLVMEXT_INCS := -iquote $(CFG_LLVM_INCDIR) -iquote llvmext/include
LLVMEXT_OBJS := $(LLVMEXT_CS:.cpp=.o)
LLVMEXT_LIBS := $(CFG_LLVM_LDFLAGS) $(CFG_LLVM_LIBS)
######################################################################
# Standard library variables
######################################################################
STDLIB_CRATE := lib/std.rc
STDLIB_INPUTS := $(wildcard $(addprefix $(S)src/lib/,*.rc *.rs */*.rs))
######################################################################
# rustc crate variables
######################################################################
COMPILER_CRATE := comp/rustc.rc
COMPILER_INPUTS := $(wildcard $(addprefix $(S)/src/comp/, \
rustc.rc *.rs */*.rs))
######################################################################
# Single-target rules
######################################################################
all: boot/rustboot$(X) rt/$(CFG_RUNTIME) llvmext/$(CFG_LLVMEXT)
rt/$(CFG_RUNTIME): $(RUNTIME_OBJS) $(MKFILES) $(RUNTIME_HDR)
@$(call E, link: $@)
$(Q)$(call CFG_LINK_C, $@) $(RUNTIME_OBJS)
llvmext/$(CFG_LLVMEXT): $(LLVMEXT_OBJS) $(MKFILES) $(LLVMEXT_HDR)
@$(call E, link: $@)
$(Q)$(call CFG_LINK_C, $@ $(LLVMEXT_OBJS) \
$(CFG_LLVM_LIBS) $(CFG_LLVM_LDFLAGS))
ifdef CFG_BOOT_NATIVE
boot/rustboot$(X): $(BOOT_CMXS) $(MKFILES)
@$(call E, link: $@)
$(Q)ocamlopt$(OPT) -o $@ $(BOOT_OCAMLOPT_FLAGS) $(BOOT_ML_NATIVE_LIBS) \
$(BOOT_CMXS)
else
boot/rustboot$(X): $(BOOT_CMOS) $(MKFILES)
@$(call E, link: $@)
$(Q)ocamlc$(OPT) -o $@ $(BOOT_OCAMLC_FLAGS) $(BOOT_ML_LIBS) $(BOOT_CMOS)
endif
boot/version.ml: $(MKFILES)
@$(call E, git: $@)
$(Q)git log -1 \
--pretty=format:'let version = "prerelease (%h %ci)";;' >$@ || exit 1
######################################################################
# Pattern rules
######################################################################
rt/%.o: rt/%.cpp $(MKFILES)
@$(call E, compile: $@)
$(Q)$(call CFG_COMPILE_C, $@, $(RUNTIME_INCS)) $<
llvmext/%.o: llvmext/%.cpp $(MKFILES)
@$(call E, compile: $@)
$(Q)$(call CFG_COMPILE_C, $@, $(CFG_LLVM_CXXFLAGS) \
$(SUPPORT_INCS)) $<
%.cmo: %.ml $(MKFILES)
@$(call E, compile: $@)
$(Q)ocamlc$(OPT) -c -o $@ $(BOOT_OCAMLC_FLAGS) $<
%.cmo: %.cmi $(MKFILES)
%.cmx %.o: %.ml $(MKFILES)
@$(call E, compile: $@)
$(Q)ocamlopt$(OPT) -c -o $@ $(BOOT_OCAMLOPT_FLAGS) $<
%.ml: %.mll $(MKFILES)
@$(call E, lex-gen: $@)
$(Q)ocamllex$(OPT) -q -o $@ $<
######################################################################
# Cleanup
######################################################################
.PHONY: clean
clean:
@$(call E, cleaning)
$(Q)rm -f $(foreach ext, cmx cmi cmo cma bc o a d $(X) \
h cpp ml s \
out bc dSYM \
, \
$(wildcard *.$(ext) \
*/*.$(ext) \
*/*/*.$(ext) \
*/*/*/*.$(ext) \
))

133
configure vendored Executable file
View file

@ -0,0 +1,133 @@
#!/bin/sh
CFG_SRC_DIR=${0%${0##*/}}
CFG_BUILD_DIR=$PWD
msg() {
echo "configure: $1"
}
err() {
echo "configure: error: $1"
exit 1
}
make_dir() {
if [ ! -d $1 ]
then
msg "mkdir -p $1"
mkdir -p $1
fi
}
copy() {
msg "cp $1 $1"
cp $1 $2
}
make_test_subdirs() {
for t in run-pass run-fail compile-fail
do
make_dir $1/test/$t
done
}
putvar() {
local T
eval T=\$$1
printf "%-20s := %s\n" $1 "$T"
printf "%-20s := %s\n" $1 "$T" >>config.mk
}
probe() {
local V=$1
local P=$2
local T
T=$(which $P 2>&1)
if [ $? -ne 0 ]
then
T=""
fi
eval $V=\$T
putvar $V
}
probe_need() {
local V=$1
local P=$2
probe $1 $2
eval VV=\$$V
if [ -z "$VV" ]
then
err "required program '$P' not found"
fi
}
msg "recreating config.mk"
echo '' >config.mk
msg "making directories"
for i in \
doc \
boot/fe boot/me boot/be boot/driver boot/util \
rt/isaac rt/bigint rt/sync rt/test
do
make_dir $i
done
make_test_subdirs boot
for i in 0 1 2
do
make_dir stage$i
make_test_subdirs stage$i
done
msg "inspecting environment"
CFG_OSTYPE=$(uname -s)
CFG_CPUTYPE=$(uname -m)
putvar CFG_SRC_DIR
putvar CFG_BUILD_DIR
putvar CFG_OSTYPE
putvar CFG_CPUTYPE
msg "looking for programs"
probe_need CFG_GCC gcc
probe_need CFG_LLVM_CONFIG llvm-config
probe_need CFG_OCAMLC ocamlc
probe_need CFG_PERL perl
probe_need CFG_SED sed
probe CFG_VALGRIND valgrind
probe CFG_OCAMLOPT ocamlopt
probe CFG_OCAMLC_OPT ocamlc.opt
probe CFG_OCAMLOPT_OPT ocamlopt.opt
probe CFG_FLEXLINK flexlink
CFG_LLVM_VERSION=$(llvm-config --version)
case $CFG_LLVM_VERSION in
(3.0svn | 3.0)
msg "found ok version of LLVM: $CFG_LLVM_VERSION"
;;
(*)
err "bad LLVM version: $CFG_LLVM_VERSION, need >=3.0svn"
;;
esac
CFG_LLVM_INCDIR=$(llvm-config --includedir)
CFG_LLVM_BINDIR=$(llvm-config --bindir)
CFG_LLVM_CXXFLAGS=$(llvm-config --cxxflags)
CFG_LLVM_LDFLAGS=$(llvm-config --ldflags)
CFG_LLVM_LIBS=$(llvm-config --libs)
putvar CFG_LLVM_INCDIR
putvar CFG_LLVM_BINDIR
putvar CFG_LLVM_CXXFLAGS
putvar CFG_LLVM_LDFLAGS
putvar CFG_LLVM_LIBS
copy ${CFG_SRC_DIR}Makefile.in ./Makefile
echo "configure: complete"

View file

@ -1,3 +1,13 @@
# Delete the built-in rules.
# This speeds builds up substantially on win32, maybe elsewhere.
.SUFFIXES:
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
######################################################################
# Auto-configuration
######################################################################
@ -446,6 +456,7 @@ TEST_XFAILS_BOOT := $(TASK_XFAILS) \
test/run-pass/iter-ret.rs \
test/run-pass/leak-tag-copy.rs \
test/run-pass/lib-io.rs \
test/run-pass/maybe-mutable.rs \
test/run-pass/mlist-cycle.rs \
test/run-pass/obj-as.rs \
test/run-pass/seq-compare.rs \
@ -469,7 +480,6 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \
acyclic-unwind.rs \
alt-pattern-drop.rs \
alt-type-simple.rs \
append-units.rs \
basic-1.rs \
basic-2.rs \
basic.rs \
@ -489,6 +499,7 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \
lib-sha1.rs \
lib-sort.rs \
lib-str.rs \
lib-str-buf.rs \
lib-task.rs \
lib-uint.rs \
lib-vec-str-conversions.rs \

View file

@ -1,129 +0,0 @@
######################################################################
# Residual auto-configuration
######################################################################
include config.mk
MKFILES := Makefile config.mk
ifneq ($(MAKE_RESTARTS),)
CFG_INFO := $(info cfg: make restarts: $(MAKE_RESTARTS))
endif
CFG_INFO := $(info cfg: building on $(CFG_OSTYPE) $(CFG_CPUTYPE))
ifdef CFG_OCAMLC_OPT
$(info cfg: using ocaml native compiler)
OPT=.opt
else
$(info cfg: using ocaml bytecode compiler)
endif
ifdef PROFILE_BOOT
$(info cfg: building bootstrap compiler with profiling (forcing native))
CFG_NATIVE_BOOT := 1
CFG_OCAMLOPT_PROFILE_FLAGS := -p
endif
ifdef DEBUG
$(info cfg: forcing bytecode bootstrap compiler)
CFG_NATIVE_BOOT :=
endif
ifdef CFG_NATIVE_BOOT
$(info cfg: building native bootstrap compiler)
else
$(info cfg: building bytecode bootstrap compiler)
endif
ifdef NO_VALGRIND
CFG_VALGRIND :=
endif
######################################################################
# Bootstrap compiler variables
######################################################################
# We must list them in link order.
# Nobody calculates the link-order DAG automatically, sadly.
BOOT_MLS := \
$(addsuffix .ml, \
$(addprefix boot/util/, version fmt common bits) \
$(addprefix boot/driver/, session) \
$(addprefix boot/fe/, ast token lexer parser \
extfmt pexp item cexp fuzz) \
$(addprefix boot/be/, asm il abi) \
$(addprefix boot/me/, walk semant resolve alias \
simplify type dead layer effect typestate \
loop layout transutil trans dwarf) \
$(addprefix boot/be/, x86 ra pe elf macho) \
$(addprefix boot/driver/, lib glue main)) \
BOOT_CMOS := $(BOOT_MLS:.ml=.cmo)
BOOT_CMXS := $(BOOT_MLS:.ml=.cmx)
BOOT_OBJS := $(BOOT_MLS:.ml=.o)
BOOT_CMIS := $(BOOT_MLS:.ml=.cmi)
ML_DEP_INCS := -I $(S)boot/fe -I $(S)boot/me -I $(S)boot/be \
-I $(S)boot/driver -I $(S)boot/util
ML_INCS := $(ML_DEP_INCS)
ML_LIBS := unix.cma nums.cma bigarray.cma
ML_NATIVE_LIBS := unix.cmxa nums.cmxa bigarray.cmxa
OCAMLC_FLAGS := -g $(ML_INCS) -w Ael -warn-error Ael
######################################################################
# Target-and-rule "utility variables"
######################################################################
ifdef VERBOSE
Q :=
E =
else
Q := @
E = echo $(1)
endif
S := $(CFG_SRC_DIR)
X := $(CFG_EXE_SUFFIX)
# Look in src dir.
VPATH := $(CFG_SRC_DIR)
# Delete the built-in rules.
.SUFFIXES:
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
######################################################################
# Targets and rules
######################################################################
all: rustboot$(X)
ifdef CFG_NATIVE_BOOT
rustboot$(X): $(BOOT_CMXS) $(MKFILES)
@$(call E, compile: $@)
$(Q)ocamlopt$(OPT) -o $@ $(OCAMLOPT_FLAGS) $(ML_NATIVE_LIBS) \
$(BOOT_CMXS)
else
rustboot$(X): $(BOOT_CMOS) $(MKFILES)
@$(call E, compile: $@)
$(Q)ocamlc$(OPT) -o $@ $(OCAMLC_FLAGS) $(ML_LIBS) $(BOOT_CMOS)
endif
boot/util/version.ml: $(MKFILES)
$(Q)git log -1 \
--pretty=format:'let version = "prerelease (%h %ci)";;' >$@ || exit 1
%.cmo: %.ml $(MKFILES)
@$(call E, compile: $@)
$(Q)ocamlc$(OPT) -c -o $@ $(OCAMLC_FLAGS) $<
%.cmo: %.cmi $(MKFILES)

View file

@ -159,7 +159,14 @@ and parse_effect (ps:pstate) : Ast.effect =
and parse_mutability (ps:pstate) : Ast.mutability =
match peek ps with
MUTABLE -> bump ps; Ast.MUT_mutable
MUTABLE ->
begin
(* HACK: ignore "mutable?" *)
bump ps;
match peek ps with
QUES -> bump ps; Ast.MUT_immutable
| _ -> Ast.MUT_mutable
end
| _ -> Ast.MUT_immutable
and parse_ty_fn
@ -310,7 +317,12 @@ and parse_atomic_ty (ps:pstate) : Ast.ty =
| MUTABLE ->
bump ps;
Ast.TY_mutable (parse_ty ps)
begin
(* HACK: ignore "mutable?" *)
match peek ps with
QUES -> bump ps; parse_ty ps
| _ -> Ast.TY_mutable (parse_ty ps)
end
| LPAREN ->
begin

View file

@ -993,8 +993,7 @@ let check_block (cx:Semant.ctxt) : (fn_ctx -> Ast.block -> unit) =
let src_ty = check_atom ~deref:true src in
let dst_ty = check_lval dst in
match fundamental_ty dst_ty, fundamental_ty src_ty with
Ast.TY_vec elt1, Ast.TY_vec elt2
| Ast.TY_vec elt1, elt2 ->
Ast.TY_vec elt1, Ast.TY_vec elt2 ->
if elt1 = elt2
then ()
else
@ -1002,7 +1001,6 @@ let check_block (cx:Semant.ctxt) : (fn_ctx -> Ast.block -> unit) =
"mismatched types in vec-append: %s += %s"
(pretty_ty_str dst_ty)
(pretty_ty_str src_ty)
| Ast.TY_str, (Ast.TY_mach Common.TY_u8)
| Ast.TY_str, Ast.TY_str -> ()
| _ ->
infer_lval src_ty dst;

View file

@ -212,10 +212,10 @@ fn copy_arg(uint i) -> str {
+ store_esp_to_rust_sp_second_arg()
+ load_esp_from_runtime_sp_second_arg()
+ vec("subl $" + wstr(n_args + 1) + ", %esp # esp -= args",
+ vec("subl $" + wstr(n_args) + ", %esp # esp -= args",
"andl $~0xf, %esp # align esp down")
+ _vec.init_fn[str](carg, (n_args + 1) as uint)
+ _vec.init_fn[str](carg, (n_args) as uint)
+ vec("movl %edx, %edi # save task from edx to edi",
"call *%ecx # call *%ecx",
@ -268,7 +268,7 @@ fn get_module_asm() -> str {
rust_yield_glue()))
+ _vec.init_fn[str](bind decl_upcall_glue(align, prefix, _),
abi.n_upcall_glues as uint);
(abi.n_upcall_glues + 1) as uint);
ret _str.connect(glues, "\n\n");
}

View file

@ -203,8 +203,8 @@ fn get_os() -> session.os {
alt (output_file) {
case (none[str]) {
let vec[str] parts = _str.split(ifile, '.' as u8);
parts = _vec.pop[str](parts);
parts += ".bc";
_vec.pop[str](parts);
parts += vec(".bc");
auto ofile = _str.concat(parts);
compile_input(sess, env, ifile, ofile, shared,
library_search_paths);

View file

@ -45,6 +45,15 @@ fn bug(str msg) {
fail;
}
fn span_unimpl(span sp, str msg) {
log #fmt("%s:%u:%u:%u:%u: error: unimplemented %s",
sp.filename,
sp.lo.line, sp.lo.col,
sp.hi.line, sp.hi.col,
msg);
fail;
}
fn unimpl(str msg) {
log #fmt("error: unimplemented %s", msg);
fail;

View file

@ -91,6 +91,7 @@
tag mutability {
mut;
imm;
maybe_mut;
}
tag opacity {
@ -168,7 +169,6 @@ fn binop_to_str(binop op) -> str {
bitnot;
not;
neg;
_mutable;
}
fn unop_to_str(unop op) -> str {
@ -178,7 +178,6 @@ fn unop_to_str(unop op) -> str {
case (bitnot) {ret "~";}
case (not) {ret "!";}
case (neg) {ret "-";}
case (_mutable) {ret "mutable";}
}
}
@ -215,7 +214,7 @@ fn unop_to_str(unop op) -> str {
type expr = spanned[expr_];
tag expr_ {
expr_vec(vec[@expr], ann);
expr_vec(vec[@expr], mutability, ann);
expr_tup(vec[elt], ann);
expr_rec(vec[field], option.t[@expr], ann);
expr_call(@expr, vec[@expr], ann);
@ -263,7 +262,8 @@ fn unop_to_str(unop op) -> str {
// NB: If you change this, you'll probably want to change the corresponding
// type structure in middle/ty.rs as well.
type ty_field = rec(ident ident, @ty ty);
type mt = rec(@ty ty, mutability mut);
type ty_field = rec(ident ident, mt mt);
type ty_arg = rec(mode mode, @ty ty);
// TODO: effect
type ty_method = rec(proto proto, ident ident,
@ -277,16 +277,15 @@ fn unop_to_str(unop op) -> str {
ty_machine(util.common.ty_mach);
ty_char;
ty_str;
ty_box(@ty);
ty_vec(@ty);
ty_box(mt);
ty_vec(mt);
ty_port(@ty);
ty_chan(@ty);
ty_tup(vec[@ty]);
ty_tup(vec[mt]);
ty_rec(vec[ty_field]);
ty_fn(proto, vec[ty_arg], @ty); // TODO: effect
ty_obj(vec[ty_method]);
ty_path(path, option.t[def]);
ty_mutable(@ty);
ty_type;
ty_constr(@ty, vec[@constr]);
}

View file

@ -13,7 +13,6 @@
import front.parser.parse_mod_items;
import util.common;
import util.common.filename;
import util.common.append;
import util.common.span;
import util.common.new_str_hash;
@ -394,7 +393,7 @@ fn val_eq(session.session sess, span sp, val av, val bv) -> bool {
auto im = ast.item_mod(id, m0, next_id);
auto i = @spanned(cdir.span, cdir.span, im);
ast.index_item(index, i);
append[@ast.item](items, i);
_vec.push[@ast.item](items, i);
}
case (ast.cdir_dir_mod(?id, ?dir_opt, ?cdirs)) {
@ -412,11 +411,11 @@ fn val_eq(session.session sess, span sp, val av, val bv) -> bool {
auto im = ast.item_mod(id, m0, p.next_def_id());
auto i = @spanned(cdir.span, cdir.span, im);
ast.index_item(index, i);
append[@ast.item](items, i);
_vec.push[@ast.item](items, i);
}
case (ast.cdir_view_item(?vi)) {
append[@ast.view_item](view_items, vi);
_vec.push[@ast.view_item](view_items, vi);
ast.index_view_item(index, vi);
}

View file

@ -113,7 +113,7 @@ fn parse_fmt_string(str s) -> vec[piece] {
fn flush_buf(str buf, &vec[piece] pieces) -> str {
if (_str.byte_len(buf) > 0u) {
auto piece = piece_string(buf);
pieces += piece;
pieces += vec(piece);
}
ret "";
}
@ -133,7 +133,7 @@ fn flush_buf(str buf, &vec[piece] pieces) -> str {
} else {
buf = flush_buf(buf, pieces);
auto res = parse_conversion(s, i, lim);
pieces += res._0;
pieces += vec(res._0);
i = res._1;
}
} else {

View file

@ -420,7 +420,7 @@ fn is_whitespace(char c) -> bool {
if (is_alpha(c) || c == '_') {
while (is_alnum(c) || c == '_') {
accum_str += (c as u8);
_str.push_byte(accum_str, (c as u8));
rdr.bump();
c = rdr.curr();
}
@ -580,23 +580,23 @@ fn is_whitespace(char c) -> bool {
alt (rdr.next()) {
case ('n') {
rdr.bump();
accum_str += '\n' as u8;
_str.push_byte(accum_str, '\n' as u8);
}
case ('r') {
rdr.bump();
accum_str += '\r' as u8;
_str.push_byte(accum_str, '\r' as u8);
}
case ('t') {
rdr.bump();
accum_str += '\t' as u8;
_str.push_byte(accum_str, '\t' as u8);
}
case ('\\') {
rdr.bump();
accum_str += '\\' as u8;
_str.push_byte(accum_str, '\\' as u8);
}
case ('"') {
rdr.bump();
accum_str += '"' as u8;
_str.push_byte(accum_str, '"' as u8);
}
// FIXME: unicode numeric escapes.
case (?c2) {
@ -607,7 +607,7 @@ fn is_whitespace(char c) -> bool {
}
}
case (_) {
accum_str += rdr.curr() as u8;
_str.push_byte(accum_str, rdr.curr() as u8);
}
}
rdr.bump();

View file

@ -9,7 +9,6 @@
import driver.session;
import util.common;
import util.common.filename;
import util.common.append;
import util.common.span;
import util.common.new_str_hash;
@ -190,6 +189,11 @@ fn spanned[T](&span lo, &span hi, &T node) -> ast.spanned[T] {
if (p.peek() == token.BINOP(token.AND)) {
p.bump();
mode = ast.alias;
if (p.peek() == token.MUTABLE) {
p.bump();
// TODO: handle mutable alias args
}
} else {
mode = ast.val;
}
@ -263,10 +267,16 @@ fn spanned[T](&span lo, &span hi, &T node) -> ast.spanned[T] {
ret ast.ty_obj(meths.node);
}
impure fn parse_mt(parser p) -> ast.mt {
auto mut = parse_mutability(p);
auto t = parse_ty(p);
ret rec(ty=t, mut=mut);
}
impure fn parse_ty_field(parser p) -> ast.ty_field {
auto ty = parse_ty(p);
auto mt = parse_mt(p);
auto id = parse_ident(p);
ret rec(ident=id, ty=ty);
ret rec(ident=id, mt=mt);
}
impure fn parse_constr_arg(parser p) -> @ast.constr_arg {
@ -303,7 +313,7 @@ fn spanned[T](&span lo, &span hi, &T node) -> ast.spanned[T] {
case (token.IDENT(_)) {
auto constr = parse_ty_constr(p);
hi = constr.span;
append[@ast.constr](constrs, constr);
_vec.push[@ast.constr](constrs, constr);
if (p.peek() == token.COMMA) {
p.bump();
more = false;
@ -361,25 +371,25 @@ fn spanned[T](&span lo, &span hi, &T node) -> ast.spanned[T] {
case (token.AT) {
p.bump();
auto t0 = parse_ty(p);
hi = t0.span;
t = ast.ty_box(t0);
auto mt = parse_mt(p);
hi = mt.ty.span;
t = ast.ty_box(mt);
}
case (token.VEC) {
p.bump();
expect(p, token.LBRACKET);
t = ast.ty_vec(parse_ty(p));
t = ast.ty_vec(parse_mt(p));
hi = p.get_span();
expect(p, token.RBRACKET);
}
case (token.TUP) {
p.bump();
auto f = parse_ty; // FIXME: trans_const_lval bug
auto elems = parse_seq[@ast.ty] (token.LPAREN,
token.RPAREN,
some(token.COMMA), f, p);
auto f = parse_mt; // FIXME: trans_const_lval bug
auto elems = parse_seq[ast.mt] (token.LPAREN,
token.RPAREN,
some(token.COMMA), f, p);
hi = elems.span;
t = ast.ty_tup(elems.node);
}
@ -396,13 +406,6 @@ fn spanned[T](&span lo, &span hi, &T node) -> ast.spanned[T] {
t = ast.ty_rec(elems.node);
}
case (token.MUTABLE) {
p.bump();
auto t0 = parse_ty(p);
hi = t0.span;
t = ast.ty_mutable(t0);
}
case (token.FN) {
auto flo = p.get_span();
p.bump();
@ -464,20 +467,22 @@ fn spanned[T](&span lo, &span hi, &T node) -> ast.spanned[T] {
if (p.peek() == token.BINOP(token.AND)) {
m = ast.alias;
p.bump();
if (p.peek() == token.MUTABLE) {
// TODO: handle mutable alias args
p.bump();
}
}
let @ast.ty t = parse_ty(p);
let ast.ident i = parse_ident(p);
ret rec(mode=m, ty=t, ident=i, id=p.next_def_id());
}
impure fn parse_seq[T](token.token bra,
token.token ket,
option.t[token.token] sep,
(impure fn(parser) -> T) f,
parser p) -> util.common.spanned[vec[T]] {
impure fn parse_seq_to_end[T](token.token ket,
option.t[token.token] sep,
(impure fn(parser) -> T) f,
parser p) -> vec[T] {
let bool first = true;
auto lo = p.get_span();
expect(p, bra);
let vec[T] v = vec();
while (p.peek() != ket) {
alt(sep) {
@ -495,9 +500,20 @@ fn spanned[T](&span lo, &span hi, &T node) -> ast.spanned[T] {
let T t = f(p);
v += vec(t);
}
auto hi = p.get_span();
expect(p, ket);
ret spanned(lo, hi, v);
ret v;
}
impure fn parse_seq[T](token.token bra,
token.token ket,
option.t[token.token] sep,
(impure fn(parser) -> T) f,
parser p) -> util.common.spanned[vec[T]] {
auto lo = p.get_span();
expect(p, bra);
auto result = parse_seq_to_end[T](ket, sep, f, p);
auto hi = p.get_span();
ret spanned(lo, hi, result);
}
impure fn parse_lit(parser p) -> ast.lit {
@ -573,7 +589,7 @@ fn is_ident(token.token t) -> bool {
alt (p.peek()) {
case (token.IDENT(?i)) {
hi = p.get_span();
ids += i;
ids += vec(i);
p.bump();
if (p.peek() == token.DOT) {
if (g == GREEDY) {
@ -596,16 +612,20 @@ fn is_ident(token.token t) -> bool {
ret spanned(lo, tys.span, rec(idents=ids, types=tys.node));
}
impure fn parse_mutabliity(parser p) -> ast.mutability {
impure fn parse_mutability(parser p) -> ast.mutability {
if (p.peek() == token.MUTABLE) {
p.bump();
if (p.peek() == token.QUES) {
p.bump();
ret ast.maybe_mut;
}
ret ast.mut;
}
ret ast.imm;
}
impure fn parse_field(parser p) -> ast.field {
auto m = parse_mutabliity(p);
auto m = parse_mutability(p);
auto i = parse_ident(p);
expect(p, token.EQ);
auto e = parse_expr(p);
@ -651,7 +671,7 @@ fn is_ident(token.token t) -> bool {
case (token.TUP) {
p.bump();
impure fn parse_elt(parser p) -> ast.elt {
auto m = parse_mutabliity(p);
auto m = parse_mutability(p);
auto e = parse_expr(p);
ret rec(mut=m, expr=e);
}
@ -668,12 +688,15 @@ fn is_ident(token.token t) -> bool {
case (token.VEC) {
p.bump();
auto pf = parse_expr;
auto es = parse_seq[@ast.expr](token.LPAREN,
token.RPAREN,
some(token.COMMA),
pf, p);
hi = es.span;
ex = ast.expr_vec(es.node, ast.ann_none);
expect(p, token.LPAREN);
auto mut = parse_mutability(p);
auto es = parse_seq_to_end[@ast.expr](token.RPAREN,
some(token.COMMA),
pf, p);
hi = p.get_span();
ex = ast.expr_vec(es, mut, ast.ann_none);
}
case (token.REC) {
@ -699,7 +722,7 @@ fn is_ident(token.token t) -> bool {
}
case (token.COMMA) {
p.bump();
fields += parse_field(p);
fields += vec(parse_field(p));
}
case (?t) {
unexpected(p, t);
@ -877,7 +900,7 @@ fn is_ident(token.token t) -> bool {
case (ast.expr_path(?pth, ?def, ?ann)) {
if (_vec.len[@ast.ty](pth.node.types) == 0u) {
auto idents_ = pth.node.idents;
idents_ += i;
idents_ += vec(i);
auto tys = parse_ty_args(p, hi);
auto pth_ = spanned(pth.span, tys.span,
rec(idents=idents_,
@ -1005,13 +1028,6 @@ fn is_ident(token.token t) -> bool {
ex = ast.expr_unary(ast.box, e, ast.ann_none);
}
case (token.MUTABLE) {
p.bump();
auto e = parse_prefix_expr(p);
hi = e.span;
ex = ast.expr_unary(ast._mutable, e, ast.ann_none);
}
case (_) {
ret parse_dot_or_call_expr(p);
}
@ -1559,7 +1575,7 @@ fn stmt_ends_with_semi(@ast.stmt stmt) -> bool {
}
case (ast.stmt_expr(?e)) {
alt (e.node) {
case (ast.expr_vec(_,_)) { ret true; }
case (ast.expr_vec(_,_,_)) { ret true; }
case (ast.expr_tup(_,_)) { ret true; }
case (ast.expr_rec(_,_,_)) { ret true; }
case (ast.expr_call(_,_,_)) { ret true; }
@ -1723,6 +1739,7 @@ fn stmt_ends_with_semi(@ast.stmt stmt) -> bool {
impure fn parse_obj_field(parser p) -> ast.obj_field {
auto mut = parse_mutability(p); // TODO: store this, use it in typeck
auto ty = parse_ty(p);
auto ident = parse_ident(p);
ret rec(ty=ty, ident=ident, id=p.next_def_id(), ann=ast.ann_none);
@ -1763,8 +1780,8 @@ fn stmt_ends_with_semi(@ast.stmt stmt) -> bool {
dtor = some[ast.block](parse_block(p));
}
case (_) {
append[@ast.method](meths,
parse_method(p));
_vec.push[@ast.method](meths,
parse_method(p));
}
}
}
@ -2161,12 +2178,11 @@ fn peeking_at_item(parser p) -> bool {
-> @ast.view_item {
auto lo = p.get_span();
auto hi = lo;
let vec[ast.ident] identifiers = vec();
identifiers += first;
let vec[ast.ident] identifiers = vec(first);
while (p.peek() != token.SEMI) {
expect(p, token.DOT);
auto i = parse_ident(p);
identifiers += i;
identifiers += vec(i);
}
p.bump();
auto defined_id;
@ -2402,7 +2418,7 @@ fn is_view_item(token.token t) -> bool {
while (p.peek() != term) {
auto cdir = @parse_crate_directive(p);
append[@ast.crate_directive](cdirs, cdir);
_vec.push[@ast.crate_directive](cdirs, cdir);
}
ret cdirs;

View file

@ -3,6 +3,7 @@
import util.common.new_str_hash;
import std._int;
import std._uint;
import std._str;
tag binop {
PLUS;
@ -302,8 +303,8 @@ fn to_str(token t) -> str {
case (LIT_CHAR(?c)) {
// FIXME: escape and encode.
auto tmp = "'";
tmp += c as u8;
tmp += '\'' as u8;
_str.push_byte(tmp, c as u8);
_str.push_byte(tmp, '\'' as u8);
ret tmp;
}

View file

@ -7,7 +7,6 @@
import util.common.spanned;
import util.common.span;
import util.common.ty_mach;
import util.common.append;
import front.ast;
import front.ast.fn_decl;
@ -29,6 +28,7 @@
import front.ast.def;
import front.ast.def_id;
import front.ast.ann;
import front.ast.mt;
import std._uint;
import std._vec;
@ -47,10 +47,10 @@
(fn(&ENV e, &span sp, ty_mach tm) -> @ty) fold_ty_machine,
(fn(&ENV e, &span sp) -> @ty) fold_ty_char,
(fn(&ENV e, &span sp) -> @ty) fold_ty_str,
(fn(&ENV e, &span sp, @ty t) -> @ty) fold_ty_box,
(fn(&ENV e, &span sp, @ty t) -> @ty) fold_ty_vec,
(fn(&ENV e, &span sp, &mt tm) -> @ty) fold_ty_box,
(fn(&ENV e, &span sp, &mt tm) -> @ty) fold_ty_vec,
(fn(&ENV e, &span sp, vec[@ty] elts) -> @ty) fold_ty_tup,
(fn(&ENV e, &span sp, vec[mt] elts) -> @ty) fold_ty_tup,
(fn(&ENV e, &span sp,
vec[ast.ty_field] elts) -> @ty) fold_ty_rec,
@ -66,13 +66,13 @@
(fn(&ENV e, &span sp, ast.path p,
&option.t[def] d) -> @ty) fold_ty_path,
(fn(&ENV e, &span sp, @ty t) -> @ty) fold_ty_mutable,
(fn(&ENV e, &span sp, @ty t) -> @ty) fold_ty_chan,
(fn(&ENV e, &span sp, @ty t) -> @ty) fold_ty_port,
// Expr folds.
(fn(&ENV e, &span sp,
vec[@expr] es, ann a) -> @expr) fold_expr_vec,
vec[@expr] es, ast.mutability mut,
ann a) -> @expr) fold_expr_vec,
(fn(&ENV e, &span sp,
vec[ast.elt] es, ann a) -> @expr) fold_expr_tup,
@ -318,7 +318,7 @@
fn fold_path[ENV](&ENV env, ast_fold[ENV] fld, &path p) -> path {
let vec[@ast.ty] tys_ = vec();
for (@ast.ty t in p.node.types) {
append[@ast.ty](tys_, fold_ty(env, fld, t));
_vec.push[@ast.ty](tys_, fold_ty(env, fld, t));
}
let ast.path_ p_ = rec(idents=p.node.idents, types=tys_);
ret fld.fold_path(env, p.span, p_);
@ -344,20 +344,21 @@ fn fold_ty[ENV](&ENV env, ast_fold[ENV] fld, @ty t) -> @ty {
case (ast.ty_char) { ret fld.fold_ty_char(env_, t.span); }
case (ast.ty_str) { ret fld.fold_ty_str(env_, t.span); }
case (ast.ty_box(?ty)) {
auto ty_ = fold_ty(env, fld, ty);
ret fld.fold_ty_box(env_, t.span, ty_);
case (ast.ty_box(?tm)) {
auto ty_ = fold_ty(env, fld, tm.ty);
ret fld.fold_ty_box(env_, t.span, rec(ty=ty_, mut=tm.mut));
}
case (ast.ty_vec(?ty)) {
auto ty_ = fold_ty(env, fld, ty);
ret fld.fold_ty_vec(env_, t.span, ty_);
case (ast.ty_vec(?tm)) {
auto ty_ = fold_ty(env, fld, tm.ty);
ret fld.fold_ty_vec(env_, t.span, rec(ty=ty_, mut=tm.mut));
}
case (ast.ty_tup(?elts)) {
let vec[@ty] elts_ = vec();
for (@ty elt in elts) {
append[@ty](elts_,fold_ty(env, fld, elt));
let vec[mt] elts_ = vec();
for (mt elt in elts) {
auto ty_ = fold_ty(env, fld, elt.ty);
_vec.push[mt](elts_, rec(ty=ty_, mut=elt.mut));
}
ret fld.fold_ty_tup(env_, t.span, elts_);
}
@ -365,8 +366,9 @@ fn fold_ty[ENV](&ENV env, ast_fold[ENV] fld, @ty t) -> @ty {
case (ast.ty_rec(?flds)) {
let vec[ast.ty_field] flds_ = vec();
for (ast.ty_field f in flds) {
append[ast.ty_field]
(flds_, rec(ty=fold_ty(env, fld, f.ty) with f));
auto ty_ = fold_ty(env, fld, f.mt.ty);
_vec.push[ast.ty_field]
(flds_, rec(mt=rec(ty=ty_, mut=f.mt.mut) with f));
}
ret fld.fold_ty_rec(env_, t.span, flds_);
}
@ -378,7 +380,7 @@ fn fold_ty[ENV](&ENV env, ast_fold[ENV] fld, @ty t) -> @ty {
m.inputs, m.output);
alt (tfn.node) {
case (ast.ty_fn(?p, ?ins, ?out)) {
append[ast.ty_method]
_vec.push[ast.ty_method]
(meths_, rec(proto=p, inputs=ins, output=out
with m));
}
@ -392,11 +394,6 @@ fn fold_ty[ENV](&ENV env, ast_fold[ENV] fld, @ty t) -> @ty {
ret fld.fold_ty_path(env_, t.span, pth_, ref_opt);
}
case (ast.ty_mutable(?ty)) {
auto ty_ = fold_ty(env, fld, ty);
ret fld.fold_ty_mutable(env_, t.span, ty_);
}
case (ast.ty_fn(?proto, ?inputs, ?output)) {
ret fold_ty_fn(env_, fld, t.span, proto, inputs, output);
}
@ -494,7 +491,7 @@ fn fold_pat[ENV](&ENV env, ast_fold[ENV] fld, @ast.pat p) -> @ast.pat {
fn fold_exprs[ENV](&ENV env, ast_fold[ENV] fld, vec[@expr] es) -> vec[@expr] {
let vec[@expr] exprs = vec();
for (@expr e in es) {
append[@expr](exprs, fold_expr(env, fld, e));
_vec.push[@expr](exprs, fold_expr(env, fld, e));
}
ret exprs;
}
@ -517,15 +514,15 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
}
alt (e.node) {
case (ast.expr_vec(?es, ?t)) {
case (ast.expr_vec(?es, ?mut, ?t)) {
auto ees = fold_exprs(env_, fld, es);
ret fld.fold_expr_vec(env_, e.span, ees, t);
ret fld.fold_expr_vec(env_, e.span, ees, mut, t);
}
case (ast.expr_tup(?es, ?t)) {
let vec[ast.elt] elts = vec();
for (ast.elt e in es) {
elts += fold_tup_elt[ENV](env, fld, e);
elts += vec(fold_tup_elt[ENV](env, fld, e));
}
ret fld.fold_expr_tup(env_, e.span, elts, t);
}
@ -534,7 +531,7 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
let vec[ast.field] fields = vec();
let option.t[@expr] b = none[@expr];
for (ast.field f in fs) {
fields += fold_rec_field(env, fld, f);
fields += vec(fold_rec_field(env, fld, f));
}
alt (base) {
case (none[@ast.expr]) { }
@ -557,7 +554,7 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
for (option.t[@ast.expr] t_opt in args_opt) {
alt (t_opt) {
case (none[@ast.expr]) {
aargs_opt += none[@ast.expr];
aargs_opt += vec(none[@ast.expr]);
}
case (some[@ast.expr](?e)) {
aargs_opt += vec(some(fold_expr(env_, fld, e)));
@ -779,7 +776,7 @@ fn fold_block[ENV](&ENV env, ast_fold[ENV] fld, &block blk) -> block {
let vec[@ast.stmt] stmts = vec();
for (@ast.stmt s in blk.node.stmts) {
auto new_stmt = fold_stmt[ENV](env_, fld, s);
append[@ast.stmt](stmts, new_stmt);
_vec.push[@ast.stmt](stmts, new_stmt);
ast.index_stmt(index, new_stmt);
}
@ -812,7 +809,7 @@ fn fold_fn_decl[ENV](&ENV env, ast_fold[ENV] fld,
&ast.fn_decl decl) -> ast.fn_decl {
let vec[ast.arg] inputs = vec();
for (ast.arg a in decl.inputs) {
inputs += fold_arg(env, fld, a);
inputs += vec(fold_arg(env, fld, a));
}
auto output = fold_ty[ENV](env, fld, decl.output);
ret fld.fold_fn_decl(env, decl.effect, inputs, output);
@ -846,7 +843,7 @@ fn fold_obj[ENV](&ENV env, ast_fold[ENV] fld, &ast._obj ob) -> ast._obj {
let vec[ast.obj_field] fields = vec();
let vec[@ast.method] meths = vec();
for (ast.obj_field f in ob.fields) {
fields += fold_obj_field(env, fld, f);
fields += vec(fold_obj_field(env, fld, f));
}
let option.t[block] dtor = none[block];
alt (ob.dtor) {
@ -867,7 +864,7 @@ fn fold_obj[ENV](&ENV env, ast_fold[ENV] fld, &ast._obj ob) -> ast._obj {
m.node.ann),
span=m.span);
let ENV _env = fld.update_env_for_item(env, i);
append[@ast.method](meths, fold_method(_env, fld, m));
_vec.push[@ast.method](meths, fold_method(_env, fld, m));
}
ret fld.fold_obj(env, fields, meths, dtor);
}
@ -944,8 +941,8 @@ fn fold_item[ENV](&ENV env, ast_fold[ENV] fld, @item i) -> @item {
auto new_ty = fold_ty[ENV](env_, fld, va.ty);
new_args += vec(rec(ty=new_ty, id=va.id));
}
new_variants += rec(name=v.name, args=new_args, id=v.id,
ann=v.ann);
new_variants += vec(rec(name=v.name, args=new_args, id=v.id,
ann=v.ann));
}
ret fld.fold_item_tag(env_, i.span, ident, new_variants,
ty_params, id);
@ -969,13 +966,13 @@ fn fold_mod[ENV](&ENV e, ast_fold[ENV] fld, &ast._mod m) -> ast._mod {
for (@view_item vi in m.view_items) {
auto new_vi = fold_view_item[ENV](e, fld, vi);
append[@view_item](view_items, new_vi);
_vec.push[@view_item](view_items, new_vi);
ast.index_view_item(index, new_vi);
}
for (@item i in m.items) {
auto new_item = fold_item[ENV](e, fld, i);
append[@item](items, new_item);
_vec.push[@item](items, new_item);
ast.index_item(index, new_item);
}
@ -1009,12 +1006,12 @@ fn fold_native_mod[ENV](&ENV e, ast_fold[ENV] fld,
for (@view_item vi in m.view_items) {
auto new_vi = fold_view_item[ENV](e, fld, vi);
append[@view_item](view_items, new_vi);
_vec.push[@view_item](view_items, new_vi);
}
for (@native_item i in m.items) {
auto new_item = fold_native_item[ENV](e, fld, i);
append[@native_item](items, new_item);
_vec.push[@native_item](items, new_item);
ast.index_native_item(index, new_item);
}
@ -1078,16 +1075,16 @@ fn identity_fold_ty_str[ENV](&ENV env, &span sp) -> @ty {
ret @respan(sp, ast.ty_str);
}
fn identity_fold_ty_box[ENV](&ENV env, &span sp, @ty t) -> @ty {
ret @respan(sp, ast.ty_box(t));
fn identity_fold_ty_box[ENV](&ENV env, &span sp, &mt tm) -> @ty {
ret @respan(sp, ast.ty_box(tm));
}
fn identity_fold_ty_vec[ENV](&ENV env, &span sp, @ty t) -> @ty {
ret @respan(sp, ast.ty_vec(t));
fn identity_fold_ty_vec[ENV](&ENV env, &span sp, &mt tm) -> @ty {
ret @respan(sp, ast.ty_vec(tm));
}
fn identity_fold_ty_tup[ENV](&ENV env, &span sp,
vec[@ty] elts) -> @ty {
vec[mt] elts) -> @ty {
ret @respan(sp, ast.ty_tup(elts));
}
@ -1113,10 +1110,6 @@ fn identity_fold_ty_path[ENV](&ENV env, &span sp, ast.path p,
ret @respan(sp, ast.ty_path(p, d));
}
fn identity_fold_ty_mutable[ENV](&ENV env, &span sp, @ty t) -> @ty {
ret @respan(sp, ast.ty_mutable(t));
}
fn identity_fold_ty_chan[ENV](&ENV env, &span sp, @ty t) -> @ty {
ret @respan(sp, ast.ty_chan(t));
}
@ -1128,8 +1121,8 @@ fn identity_fold_ty_port[ENV](&ENV env, &span sp, @ty t) -> @ty {
// Expr identities.
fn identity_fold_expr_vec[ENV](&ENV env, &span sp, vec[@expr] es,
ann a) -> @expr {
ret @respan(sp, ast.expr_vec(es, a));
ast.mutability mut, ann a) -> @expr {
ret @respan(sp, ast.expr_vec(es, mut, a));
}
fn identity_fold_expr_tup[ENV](&ENV env, &span sp,
@ -1529,11 +1522,10 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
fold_ty_obj = bind identity_fold_ty_obj[ENV](_,_,_),
fold_ty_fn = bind identity_fold_ty_fn[ENV](_,_,_,_,_),
fold_ty_path = bind identity_fold_ty_path[ENV](_,_,_,_),
fold_ty_mutable = bind identity_fold_ty_mutable[ENV](_,_,_),
fold_ty_chan = bind identity_fold_ty_chan[ENV](_,_,_),
fold_ty_port = bind identity_fold_ty_port[ENV](_,_,_),
fold_expr_vec = bind identity_fold_expr_vec[ENV](_,_,_,_),
fold_expr_vec = bind identity_fold_expr_vec[ENV](_,_,_,_,_),
fold_expr_tup = bind identity_fold_expr_tup[ENV](_,_,_,_),
fold_expr_rec = bind identity_fold_expr_rec[ENV](_,_,_,_,_),
fold_expr_call = bind identity_fold_expr_call[ENV](_,_,_,_,_),

View file

@ -20,7 +20,6 @@
import middle.ty.plain_ty;
import util.common;
import util.common.append;
import util.common.istr;
import util.common.new_def_hash;
import util.common.new_str_hash;
@ -476,7 +475,7 @@ fn type_of_explicit_args(@crate_ctxt cx,
for (ty.arg arg in inputs) {
if (ty.type_has_dynamic_size(arg.ty)) {
check (arg.mode == ast.alias);
atys += T_typaram_ptr(cx.tn);
atys += vec(T_typaram_ptr(cx.tn));
} else {
let TypeRef t;
alt (arg.mode) {
@ -487,7 +486,7 @@ fn type_of_explicit_args(@crate_ctxt cx,
t = type_of_inner(cx, arg.ty, false);
}
}
atys += t;
atys += vec(t);
}
}
ret atys;
@ -510,22 +509,22 @@ fn type_of_fn_full(@crate_ctxt cx,
// Arg 0: Output pointer.
if (ty.type_has_dynamic_size(output)) {
atys += T_typaram_ptr(cx.tn);
atys += vec(T_typaram_ptr(cx.tn));
} else {
atys += T_ptr(type_of_inner(cx, output, false));
atys += vec(T_ptr(type_of_inner(cx, output, false)));
}
// Arg 1: Task pointer.
atys += T_taskptr(cx.tn);
atys += vec(T_taskptr(cx.tn));
// Arg 2: Env (closure-bindings / self-obj)
alt (obj_self) {
case (some[TypeRef](?t)) {
check (t as int != 0);
atys += t;
atys += vec(t);
}
case (_) {
atys += T_opaque_closure_ptr(cx.tn);
atys += vec(T_opaque_closure_ptr(cx.tn));
}
}
@ -533,7 +532,7 @@ fn type_of_fn_full(@crate_ctxt cx,
if (obj_self == none[TypeRef]) {
auto i = 0u;
while (i < ty_param_count) {
atys += T_ptr(T_tydesc(cx.tn));
atys += vec(T_ptr(T_tydesc(cx.tn)));
i += 1u;
}
}
@ -542,10 +541,11 @@ fn type_of_fn_full(@crate_ctxt cx,
// If it's an iter, the 'output' type of the iter is actually the
// *input* type of the function we're given as our iter-block
// argument.
atys += T_fn_pair(cx.tn,
atys +=
vec(T_fn_pair(cx.tn,
type_of_fn_full(cx, ast.proto_fn, none[TypeRef],
vec(rec(mode=ast.val, ty=output)),
plain_ty(ty.ty_nil), 0u));
plain_ty(ty.ty_nil), 0u)));
}
// ... then explicit args.
@ -568,12 +568,12 @@ fn type_of_native_fn(@crate_ctxt cx, ast.native_abi abi,
@ty.t output) -> TypeRef {
let vec[TypeRef] atys = vec();
if (abi == ast.native_abi_rust) {
atys += T_taskptr(cx.tn);
atys += vec(T_taskptr(cx.tn));
auto t = ty.ty_native_fn(abi, inputs, output);
auto ty_param_count = ty.count_ty_params(plain_ty(t));
auto i = 0u;
while (i < ty_param_count) {
atys += T_ptr(T_tydesc(cx.tn));
atys += vec(T_ptr(T_tydesc(cx.tn)));
i += 1u;
}
}
@ -614,23 +614,23 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t, bool boxed) -> TypeRef {
llty = T_tag(cx.tn, size);
}
}
case (ty.ty_box(?t)) {
llty = T_ptr(T_box(type_of_inner(cx, t, true)));
case (ty.ty_box(?mt)) {
llty = T_ptr(T_box(type_of_inner(cx, mt.ty, true)));
}
case (ty.ty_vec(?t)) {
llty = T_ptr(T_vec(type_of_inner(cx, t, true)));
case (ty.ty_vec(?mt)) {
llty = T_ptr(T_vec(type_of_inner(cx, mt.ty, true)));
}
case (ty.ty_tup(?elts)) {
let vec[TypeRef] tys = vec();
for (@ty.t elt in elts) {
tys += type_of_inner(cx, elt, boxed);
for (ty.mt elt in elts) {
tys += vec(type_of_inner(cx, elt.ty, boxed));
}
llty = T_struct(tys);
}
case (ty.ty_rec(?fields)) {
let vec[TypeRef] tys = vec();
for (ty.field f in fields) {
tys += type_of_inner(cx, f.ty, boxed);
tys += vec(type_of_inner(cx, f.mt.ty, boxed));
}
llty = T_struct(tys);
}
@ -650,7 +650,7 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t, bool boxed) -> TypeRef {
type_of_fn_full(cx, m.proto,
some[TypeRef](self_ty),
m.inputs, m.output, 0u);
mtys += T_ptr(mty);
mtys += vec(T_ptr(mty));
}
let TypeRef vtbl = T_struct(mtys);
let TypeRef pair = T_struct(vec(T_ptr(vtbl),
@ -832,8 +832,7 @@ fn decl_upcall_glue(ModuleRef llmod, type_names tn, uint _n) -> ValueRef {
let int n = _n as int;
let str s = abi.upcall_glue_name(n);
let vec[TypeRef] args =
vec(T_int(), // callee
T_int()) // taskptr
vec(T_int()) // callee
+ _vec.init_elt[TypeRef](T_int(), n as uint);
ret decl_fastcall_fn(llmod, s, T_fn(args, T_int()));
@ -864,16 +863,16 @@ fn trans_upcall2(builder b, @glue_fns glues, ValueRef lltaskptr,
&hashmap[str, ValueRef] upcalls,
type_names tn, ModuleRef llmod, str name,
vec[ValueRef] args) -> ValueRef {
let int n = _vec.len[ValueRef](args) as int;
let int n = (_vec.len[ValueRef](args) as int) + 1;
let ValueRef llupcall = get_upcall(upcalls, tn, llmod, name, n);
llupcall = llvm.LLVMConstPointerCast(llupcall, T_int());
let ValueRef llglue = glues.upcall_glues.(n);
let vec[ValueRef] call_args = vec(llupcall);
call_args += b.PtrToInt(lltaskptr, T_int());
call_args += vec( b.PtrToInt(lltaskptr, T_int()));
for (ValueRef a in args) {
call_args += b.ZExtOrBitCast(a, T_int());
call_args += vec(b.ZExtOrBitCast(a, T_int()));
}
ret b.FastCall(llglue, call_args);
@ -972,8 +971,7 @@ fn static_size_of_tag(@crate_ctxt cx, @ty.t t) -> uint {
auto max_size = 0u;
auto variants = tag_variants(cx, tid);
for (ast.variant variant in variants) {
let vec[@ty.t] tys = variant_types(cx, variant);
auto tup_ty = ty.plain_ty(ty.ty_tup(tys));
auto tup_ty = ty.plain_tup_ty(variant_types(cx, variant));
// Perform any type parameter substitutions.
tup_ty = ty.substitute_ty_params(ty_params, subtys, tup_ty);
@ -1022,12 +1020,16 @@ fn align_elements(@block_ctxt cx, vec[@ty.t] elts) -> result {
ret res(szptr.bcx, szptr.bcx.build.Load(szptr.val));
}
case (ty.ty_tup(?elts)) {
ret align_elements(cx, elts);
let vec[@ty.t] tys = vec();
for (ty.mt mt in elts) {
tys += vec(mt.ty);
}
ret align_elements(cx, tys);
}
case (ty.ty_rec(?flds)) {
let vec[@ty.t] tys = vec();
for (ty.field f in flds) {
tys += vec(f.ty);
tys += vec(f.mt.ty);
}
ret align_elements(cx, tys);
}
@ -1073,8 +1075,8 @@ fn dynamic_align_of(@block_ctxt cx, @ty.t t) -> result {
case (ty.ty_tup(?elts)) {
auto a = C_int(1);
auto bcx = cx;
for (@ty.t e in elts) {
auto align = align_of(bcx, e);
for (ty.mt e in elts) {
auto align = align_of(bcx, e.ty);
bcx = align.bcx;
a = umax(bcx, a, align.val);
}
@ -1084,7 +1086,7 @@ fn dynamic_align_of(@block_ctxt cx, @ty.t t) -> result {
auto a = C_int(1);
auto bcx = cx;
for (ty.field f in flds) {
auto align = align_of(bcx, f.ty);
auto align = align_of(bcx, f.mt.ty);
bcx = align.bcx;
a = umax(bcx, a, align.val);
}
@ -1112,7 +1114,7 @@ fn GEP_tup_like(@block_ctxt cx, @ty.t t,
if (! ty.type_has_dynamic_size(t)) {
let vec[ValueRef] v = vec();
for (int i in ixs) {
v += C_int(i);
v += vec(C_int(i));
}
ret res(cx, cx.build.GEP(base, v));
}
@ -1159,8 +1161,8 @@ fn split_type(@ty.t t, vec[int] ixs, uint n)
let vec[@ty.t] prefix = vec();
let int i = 0;
while (i < ix) {
append[@ty.t](prefix, ty.get_element_type(t, i as uint));
i +=1 ;
_vec.push[@ty.t](prefix, ty.get_element_type(t, i as uint));
i += 1 ;
}
auto selected = ty.get_element_type(t, i as uint);
@ -1184,7 +1186,7 @@ fn split_type(@ty.t t, vec[int] ixs, uint n)
// flattened the incoming structure.
auto s = split_type(t, ixs, 0u);
auto prefix_ty = plain_ty(ty.ty_tup(s.prefix));
auto prefix_ty = ty.plain_tup_ty(s.prefix);
auto bcx = cx;
auto sz = size_of(bcx, prefix_ty);
bcx = sz.bcx;
@ -1228,7 +1230,8 @@ fn GEP_tag(@block_ctxt cx,
i += 1;
}
auto tup_ty = ty.plain_ty(ty.ty_tup(true_arg_tys));
auto tup_ty = ty.plain_tup_ty(true_arg_tys);
// Cast the blob pointer to the appropriate type, if we need to (i.e. if
// the blob pointer isn't dynamically sized).
@ -1268,8 +1271,8 @@ fn trans_raw_malloc(@block_ctxt cx, TypeRef llptr_ty, ValueRef llsize)
fn trans_malloc_boxed(@block_ctxt cx, @ty.t t) -> result {
// Synthesize a fake box type structurally so we have something
// to measure the size of.
auto boxed_body = plain_ty(ty.ty_tup(vec(plain_ty(ty.ty_int), t)));
auto box_ptr = plain_ty(ty.ty_box(t));
auto boxed_body = ty.plain_tup_ty(vec(plain_ty(ty.ty_int), t));
auto box_ptr = ty.plain_box_ty(t);
auto sz = size_of(cx, boxed_body);
auto llty = type_of(cx.fcx.ccx, box_ptr);
ret trans_raw_malloc(sz.bcx, llty, sz.val);
@ -1310,8 +1313,8 @@ fn fold_simple_ty(@ty.t t) -> @ty.t {
}
}
if (!seen) {
r.vals += r.cx.fcx.lltydescs.get(pid);
r.defs += pid;
r.vals += vec(r.cx.fcx.lltydescs.get(pid));
r.defs += vec(pid);
}
}
case (_) { }
@ -1567,7 +1570,7 @@ fn hit_zero(@block_ctxt cx, ValueRef v,
T_int(), C_int(0));
}
case (ty.ty_box(?body_ty)) {
case (ty.ty_box(?body_mt)) {
fn hit_zero(@block_ctxt cx, ValueRef v,
@ty.t body_ty) -> result {
auto body = cx.build.GEP(v,
@ -1580,7 +1583,7 @@ fn hit_zero(@block_ctxt cx, ValueRef v,
ret trans_non_gc_free(res.bcx, v);
}
ret decr_refcnt_and_if_zero(cx, v,
bind hit_zero(_, v, body_ty),
bind hit_zero(_, v, body_mt.ty),
"free box",
T_int(), C_int(0));
}
@ -1832,7 +1835,7 @@ fn iter_boxpp(@block_ctxt cx,
auto box_a_ptr = cx.build.Load(box_a_cell);
auto box_b_ptr = cx.build.Load(box_b_cell);
auto tnil = plain_ty(ty.ty_nil);
auto tbox = plain_ty(ty.ty_box(tnil));
auto tbox = ty.plain_box_ty(tnil);
auto inner_cx = new_sub_block_ctxt(cx, "iter box");
auto next_cx = new_sub_block_ctxt(cx, "next");
@ -1847,15 +1850,15 @@ fn iter_boxpp(@block_ctxt cx,
alt (t.struct) {
case (ty.ty_tup(?args)) {
let int i = 0;
for (@ty.t arg in args) {
for (ty.mt arg in args) {
r = GEP_tup_like(r.bcx, t, av, vec(0, i));
auto elt_a = r.val;
r = GEP_tup_like(r.bcx, t, bv, vec(0, i));
auto elt_b = r.val;
r = f(r.bcx,
load_scalar_or_boxed(r.bcx, elt_a, arg),
load_scalar_or_boxed(r.bcx, elt_b, arg),
arg);
load_scalar_or_boxed(r.bcx, elt_a, arg.ty),
load_scalar_or_boxed(r.bcx, elt_b, arg.ty),
arg.ty);
i += 1;
}
}
@ -1867,9 +1870,9 @@ fn iter_boxpp(@block_ctxt cx,
r = GEP_tup_like(r.bcx, t, bv, vec(0, i));
auto llfld_b = r.val;
r = f(r.bcx,
load_scalar_or_boxed(r.bcx, llfld_a, fld.ty),
load_scalar_or_boxed(r.bcx, llfld_b, fld.ty),
fld.ty);
load_scalar_or_boxed(r.bcx, llfld_a, fld.mt.ty),
load_scalar_or_boxed(r.bcx, llfld_b, fld.mt.ty),
fld.mt.ty);
i += 1;
}
}
@ -2107,8 +2110,8 @@ fn iter_sequence_body(@block_ctxt cx,
}
alt (t.struct) {
case (ty.ty_vec(?et)) {
ret iter_sequence_body(cx, v, et, f, false);
case (ty.ty_vec(?elt)) {
ret iter_sequence_body(cx, v, elt.ty, f, false);
}
case (ty.ty_str) {
auto et = plain_ty(ty.ty_machine(common.ty_u8));
@ -2365,7 +2368,7 @@ fn trans_unary(@block_ctxt cx, ast.unop op,
auto box_ty = node_ann_type(sub.bcx.fcx.ccx, a);
sub = trans_malloc_boxed(sub.bcx, e_ty);
find_scope_cx(cx).cleanups +=
clean(bind drop_ty(_, sub.val, box_ty));
vec(clean(bind drop_ty(_, sub.val, box_ty)));
auto box = sub.val;
auto rc = sub.bcx.build.GEP(box,
@ -2398,9 +2401,6 @@ fn trans_unary(@block_ctxt cx, ast.unop op,
}
ret res(sub.bcx, val);
}
case (ast._mutable) {
ret trans_expr(cx, e);
}
}
fail;
}
@ -2646,7 +2646,8 @@ fn trans_vec_add(@block_ctxt cx, @ty.t t,
r = copy_ty(r.bcx, INIT, tmp, lhs, t);
auto bcx = trans_vec_append(r.bcx, t, tmp, rhs).bcx;
tmp = load_scalar_or_boxed(bcx, tmp, t);
find_scope_cx(cx).cleanups += clean(bind drop_ty(_, tmp, t));
find_scope_cx(cx).cleanups +=
vec(clean(bind drop_ty(_, tmp, t)));
ret res(bcx, tmp);
}
@ -2698,12 +2699,12 @@ fn autoderef(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
while (true) {
alt (t1.struct) {
case (ty.ty_box(?inner)) {
case (ty.ty_box(?mt)) {
auto body = cx.build.GEP(v1,
vec(C_int(0),
C_int(abi.box_rc_field_body)));
t1 = inner;
v1 = load_scalar_or_boxed(cx, body, inner);
t1 = mt.ty;
v1 = load_scalar_or_boxed(cx, body, t1);
}
case (_) {
ret res(cx, v1);
@ -2717,8 +2718,8 @@ fn autoderefed_ty(@ty.t t) -> @ty.t {
while (true) {
alt (t1.struct) {
case (ty.ty_box(?inner)) {
t1 = inner;
case (ty.ty_box(?mt)) {
t1 = mt.ty;
}
case (_) {
ret t1;
@ -2800,9 +2801,9 @@ fn join_results(@block_ctxt parent_cx,
for (result r in ins) {
if (! is_terminated(r.bcx)) {
live += r;
vals += r.val;
bbs += r.bcx.llbb;
live += vec(r);
vals += vec(r.val);
bbs += vec(r.bcx.llbb);
}
}
@ -2875,7 +2876,8 @@ fn inner(@block_ctxt cx,
cx.build.Br(scope_cx.llbb);
auto local_res = alloc_local(scope_cx, local);
auto bcx = copy_ty(local_res.bcx, INIT, local_res.val, curr, t).bcx;
scope_cx.cleanups += clean(bind drop_slot(_, local_res.val, t));
scope_cx.cleanups +=
vec(clean(bind drop_slot(_, local_res.val, t)));
bcx = trans_block(bcx, body).bcx;
bcx.build.Br(next_cx.llbb);
ret res(next_cx, C_nil());
@ -3245,7 +3247,8 @@ fn trans_pat_binding(@block_ctxt cx, @ast.pat pat, ValueRef llval)
llvm.LLVMSetValueName(dst, _str.buf(id));
bcx.fcx.lllocals.insert(def_id, dst);
bcx.cleanups += clean(bind drop_slot(_, dst, ty));
bcx.cleanups +=
vec(clean(bind drop_slot(_, dst, ty)));
ret copy_ty(bcx, INIT, dst, llval, ty);
}
@ -3368,7 +3371,7 @@ fn lval_generic_fn(@block_ctxt cx,
for (@ty.t t in tys) {
auto td = get_tydesc(bcx, t);
bcx = td.bcx;
append[ValueRef](tydescs, td.val);
_vec.push[ValueRef](tydescs, td.val);
}
auto gen = rec( item_type = tpt._1,
tydescs = tydescs );
@ -3481,7 +3484,7 @@ fn trans_field(@block_ctxt cx, &ast.span sp, @ast.expr base,
r = autoderef(r.bcx, r.val, t);
t = autoderefed_ty(t);
alt (t.struct) {
case (ty.ty_tup(?fields)) {
case (ty.ty_tup(_)) {
let uint ix = ty.field_num(cx.fcx.ccx.sess, sp, field);
auto v = GEP_tup_like(r.bcx, t, r.val, vec(0, ix as int));
ret lval_mem(v.bcx, v.val);
@ -3621,7 +3624,7 @@ fn trans_bind_thunk(@crate_ctxt cx,
auto fcx = new_fn_ctxt(cx, llthunk);
auto bcx = new_top_block_ctxt(fcx);
auto llclosure_ptr_ty = type_of(cx, plain_ty(ty.ty_box(closure_ty)));
auto llclosure_ptr_ty = type_of(cx, ty.plain_box_ty(closure_ty));
auto llclosure = bcx.build.PointerCast(fcx.llenv, llclosure_ptr_ty);
auto lltarget = GEP_tup_like(bcx, closure_ty, llclosure,
@ -3692,7 +3695,7 @@ fn trans_bind_thunk(@crate_ctxt cx,
val = bcx.build.PointerCast(val, llout_arg_ty);
}
llargs += val;
llargs += vec(val);
b += 1;
}
@ -3706,7 +3709,7 @@ fn trans_bind_thunk(@crate_ctxt cx,
llout_arg_ty);
}
llargs += passed_arg;
llargs += vec(passed_arg);
a += 1u;
}
}
@ -3750,7 +3753,7 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
case (none[@ast.expr]) {
}
case (some[@ast.expr](?e)) {
append[@ast.expr](bound, e);
_vec.push[@ast.expr](bound, e);
}
}
}
@ -3786,14 +3789,14 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
auto arg = trans_expr(bcx, e);
bcx = arg.bcx;
append[ValueRef](bound_vals, arg.val);
append[@ty.t](bound_tys, ty.expr_ty(e));
_vec.push[ValueRef](bound_vals, arg.val);
_vec.push[@ty.t](bound_tys, ty.expr_ty(e));
i += 1u;
}
// Synthesize a closure type.
let @ty.t bindings_ty = plain_ty(ty.ty_tup(bound_tys));
let @ty.t bindings_ty = ty.plain_tup_ty(bound_tys);
// NB: keep this in sync with T_closure_ptr; we're making
// a ty.t structure that has the same "shape" as the LLVM type
@ -3807,9 +3810,9 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
vec(tydesc_ty,
outgoing_fty,
bindings_ty,
plain_ty(ty.ty_tup(captured_tys)));
ty.plain_tup_ty(captured_tys));
let @ty.t closure_ty = plain_ty(ty.ty_tup(closure_tys));
let @ty.t closure_ty = ty.plain_tup_ty(closure_tys);
auto r = trans_malloc_boxed(bcx, closure_ty);
auto box = r.val;
@ -3914,7 +3917,7 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
pair_box);
find_scope_cx(cx).cleanups +=
clean(bind drop_slot(_, pair_v, pair_ty));
vec(clean(bind drop_slot(_, pair_v, pair_ty)));
ret res(bcx, pair_v);
}
@ -3959,23 +3962,24 @@ fn trans_args(@block_ctxt cx,
}
}
if (ty.type_has_dynamic_size(retty)) {
llargs += bcx.build.PointerCast(llretslot,
T_typaram_ptr(cx.fcx.ccx.tn));
llargs += vec(bcx.build.PointerCast(llretslot,
T_typaram_ptr(cx.fcx.ccx.tn)));
} else if (ty.count_ty_params(retty) != 0u) {
// It's possible that the callee has some generic-ness somewhere in
// its return value -- say a method signature within an obj or a fn
// type deep in a structure -- which the caller has a concrete view
// of. If so, cast the caller's view of the restlot to the callee's
// view, for the sake of making a type-compatible call.
llargs += cx.build.PointerCast(llretslot,
T_ptr(type_of(bcx.fcx.ccx, retty)));
llargs +=
vec(cx.build.PointerCast(llretslot,
T_ptr(type_of(bcx.fcx.ccx, retty))));
} else {
llargs += llretslot;
llargs += vec(llretslot);
}
// Arg 1: Task pointer.
llargs += bcx.fcx.lltaskptr;
llargs += vec(bcx.fcx.lltaskptr);
// Arg 2: Env (closure-bindings / self-obj)
alt (llobj) {
@ -3983,10 +3987,10 @@ fn trans_args(@block_ctxt cx,
// Every object is always found in memory,
// and not-yet-loaded (as part of an lval x.y
// doted method-call).
llargs += bcx.build.Load(ob);
llargs += vec(bcx.build.Load(ob));
}
case (_) {
llargs += llenv;
llargs += vec(llenv);
}
}
@ -3997,7 +4001,7 @@ fn trans_args(@block_ctxt cx,
alt (lliterbody) {
case (none[ValueRef]) {}
case (some[ValueRef](?lli)) {
llargs += lli;
llargs += vec(lli);
}
}
@ -4054,7 +4058,7 @@ fn trans_args(@block_ctxt cx,
val = bcx.build.PointerCast(val, lldestty);
}
llargs += val;
llargs += vec(val);
i += 1u;
}
@ -4116,7 +4120,8 @@ fn trans_call(@block_ctxt cx, @ast.expr f,
// Retval doesn't correspond to anything really tangible in the frame,
// but it's a ref all the same, so we put a note here to drop it when
// we're done in this scope.
find_scope_cx(cx).cleanups += clean(bind drop_ty(_, retval, ret_ty));
find_scope_cx(cx).cleanups +=
vec(clean(bind drop_ty(_, retval, ret_ty)));
}
ret res(bcx, retval);
@ -4130,7 +4135,8 @@ fn trans_tup(@block_ctxt cx, vec[ast.elt] elts,
auto tup_val = tup_res.val;
bcx = tup_res.bcx;
find_scope_cx(cx).cleanups += clean(bind drop_ty(_, tup_val, t));
find_scope_cx(cx).cleanups +=
vec(clean(bind drop_ty(_, tup_val, t)));
let int i = 0;
for (ast.elt e in elts) {
@ -4150,8 +4156,8 @@ fn trans_vec(@block_ctxt cx, vec[@ast.expr] args,
auto t = node_ann_type(cx.fcx.ccx, ann);
auto unit_ty = t;
alt (t.struct) {
case (ty.ty_vec(?t)) {
unit_ty = t;
case (ty.ty_vec(?mt)) {
unit_ty = mt.ty;
}
case (_) {
cx.fcx.ccx.sess.bug("non-vec type in trans_vec");
@ -4171,14 +4177,15 @@ fn trans_vec(@block_ctxt cx, vec[@ast.expr] args,
auto llty = type_of(bcx.fcx.ccx, t);
auto vec_val = vi2p(bcx, sub.val, llty);
find_scope_cx(bcx).cleanups += clean(bind drop_ty(_, vec_val, t));
find_scope_cx(bcx).cleanups +=
vec(clean(bind drop_ty(_, vec_val, t)));
auto body = bcx.build.GEP(vec_val, vec(C_int(0),
C_int(abi.vec_elt_data)));
auto pseudo_tup_ty =
plain_ty(ty.ty_tup(_vec.init_elt[@ty.t](unit_ty,
_vec.len[@ast.expr](args))));
ty.plain_tup_ty(_vec.init_elt[@ty.t](unit_ty,
_vec.len[@ast.expr](args)));
let int i = 0;
for (@ast.expr e in args) {
@ -4226,7 +4233,8 @@ fn trans_rec(@block_ctxt cx, vec[ast.field] fields,
auto rec_val = rec_res.val;
bcx = rec_res.bcx;
find_scope_cx(cx).cleanups += clean(bind drop_ty(_, rec_val, t));
find_scope_cx(cx).cleanups +=
vec(clean(bind drop_ty(_, rec_val, t)));
let int i = 0;
auto base_val = C_nil();
@ -4246,7 +4254,7 @@ fn trans_rec(@block_ctxt cx, vec[ast.field] fields,
}
for (ty.field tf in ty_fields) {
auto e_ty = tf.ty;
auto e_ty = tf.mt.ty;
auto dst_res = GEP_tup_like(bcx, t, rec_val, vec(0, i));
bcx = dst_res.bcx;
@ -4352,7 +4360,7 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
ret trans_cast(cx, e, ann);
}
case (ast.expr_vec(?args, ?ann)) {
case (ast.expr_vec(?args, _, ?ann)) {
ret trans_vec(cx, args, ann);
}
@ -4499,7 +4507,7 @@ fn trans_put(@block_ctxt cx, &option.t[@ast.expr] e) -> result {
llarg = bcx.build.Load(llarg);
}
llargs += llarg;
llargs += vec(llarg);
}
}
@ -4557,7 +4565,7 @@ fn init_local(@block_ctxt cx, @ast.local local) -> result {
auto bcx = cx;
find_scope_cx(cx).cleanups +=
clean(bind drop_slot(_, llptr, ty));
vec(clean(bind drop_slot(_, llptr, ty)));
alt (local.init) {
case (some[@ast.expr](?e)) {
@ -4903,7 +4911,7 @@ fn populate_fn_ctxt_from_llself(@block_ctxt cx, ValueRef llself) -> result {
// Synthesize a tuple type for the fields so that GEP_tup_like() can work
// its magic.
auto fields_tup_ty = ty.plain_ty(ty.ty_tup(field_tys));
auto fields_tup_ty = ty.plain_tup_ty(field_tys);
auto n_typarams = _vec.len[ast.ty_param](bcx.fcx.ccx.obj_typarams);
let TypeRef llobj_box_ty = T_obj_ptr(bcx.fcx.ccx.tn, n_typarams);
@ -5026,7 +5034,7 @@ fn meth_lteq(&@ast.method a, &@ast.method b) -> bool {
trans_fn(mcx, m.node.meth, m.node.id, some[TypeRef](self_ty),
ty_params, m.node.ann);
methods += llfn;
methods += vec(llfn);
}
auto vtbl = C_struct(methods);
auto gvar = llvm.LLVMAddGlobal(cx.llmod,
@ -5085,22 +5093,22 @@ fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
// Malloc a box for the body and copy args in.
let vec[@ty.t] obj_fields = vec();
for (ty.arg a in arg_tys) {
append[@ty.t](obj_fields, a.ty);
_vec.push[@ty.t](obj_fields, a.ty);
}
// Synthesize an obj body type.
auto tydesc_ty = plain_ty(ty.ty_type);
let vec[@ty.t] tps = vec();
for (ast.ty_param tp in ty_params) {
append[@ty.t](tps, tydesc_ty);
_vec.push[@ty.t](tps, tydesc_ty);
}
let @ty.t typarams_ty = plain_ty(ty.ty_tup(tps));
let @ty.t fields_ty = plain_ty(ty.ty_tup(obj_fields));
let @ty.t body_ty = plain_ty(ty.ty_tup(vec(tydesc_ty,
typarams_ty,
fields_ty)));
let @ty.t boxed_body_ty = plain_ty(ty.ty_box(body_ty));
let @ty.t typarams_ty = ty.plain_tup_ty(tps);
let @ty.t fields_ty = ty.plain_tup_ty(obj_fields);
let @ty.t body_ty = ty.plain_tup_ty(vec(tydesc_ty,
typarams_ty,
fields_ty));
let @ty.t boxed_body_ty = ty.plain_box_ty(body_ty);
// Malloc a box for the body.
auto box = trans_malloc_boxed(bcx, body_ty);
@ -6090,7 +6098,7 @@ fn make_glues(ModuleRef llmod, type_names tn) -> @glue_fns {
upcall_glues =
_vec.init_fn[ValueRef](bind decl_upcall_glue(llmod, tn, _),
abi.n_upcall_glues as uint),
abi.n_upcall_glues + 1 as uint),
no_op_type_glue = decl_no_op_type_glue(llmod, tn),
memcpy_glue = decl_memcpy_glue(llmod),
bzero_glue = decl_bzero_glue(llmod),

View file

@ -11,22 +11,23 @@
import front.ast;
import front.ast.mutability;
import util.common;
import util.common.append;
import util.common.new_def_hash;
import util.common.span;
// Data types
type arg = rec(ast.mode mode, @t ty);
type field = rec(ast.ident ident, @t ty);
type field = rec(ast.ident ident, mt mt);
type method = rec(ast.proto proto,
ast.ident ident,
vec[arg] inputs,
@t output);
type mt = rec(@t ty, ast.mutability mut);
// NB: If you change this, you'll probably want to change the corresponding
// AST structure in front/ast.rs as well.
type t = rec(sty struct, mutability mut, option.t[str] cname);
type t = rec(sty struct, option.t[str] cname);
tag sty {
ty_nil;
ty_bool;
@ -36,11 +37,11 @@
ty_char;
ty_str;
ty_tag(ast.def_id, vec[@t]);
ty_box(@t);
ty_vec(@t);
ty_box(mt);
ty_vec(mt);
ty_port(@t);
ty_chan(@t);
ty_tup(vec[@t]);
ty_tup(vec[mt]);
ty_rec(vec[field]);
ty_fn(ast.proto, vec[arg], @t); // TODO: effect
ty_native_fn(ast.native_abi, vec[arg], @t); // TODO: effect
@ -66,6 +67,8 @@ fn unify_actual_param(ast.def_id id, @t expected, @t actual)
tag type_err {
terr_mismatch;
terr_box_mutability;
terr_vec_mutability;
terr_tuple_size(uint, uint);
terr_tuple_mutability;
terr_record_size(uint, uint);
@ -139,44 +142,51 @@ fn method_to_str(&method m) -> str {
}
fn field_to_str(&field f) -> str {
ret ty_to_str(f.ty) + " " + f.ident;
ret mt_to_str(f.mt) + " " + f.ident;
}
fn mt_to_str(&mt m) -> str {
auto mstr;
alt (m.mut) {
case (ast.mut) { mstr = "mutable "; }
case (ast.imm) { mstr = ""; }
case (ast.maybe_mut) { mstr = "mutable? "; }
}
ret mstr + ty_to_str(m.ty);
}
auto s = "";
if (typ.mut == ast.mut) {
s += "mutable ";
}
alt (typ.struct) {
case (ty_native) { s = "native"; }
case (ty_nil) { s = "()"; }
case (ty_bool) { s = "bool"; }
case (ty_int) { s = "int"; }
case (ty_uint) { s = "uint"; }
case (ty_machine(?tm)) { s = common.ty_mach_to_str(tm); }
case (ty_char) { s = "char"; }
case (ty_str) { s = "str"; }
case (ty_box(?t)) { s = "@" + ty_to_str(t); }
case (ty_vec(?t)) { s = "vec[" + ty_to_str(t) + "]"; }
case (ty_port(?t)) { s = "port[" + ty_to_str(t) + "]"; }
case (ty_chan(?t)) { s = "chan[" + ty_to_str(t) + "]"; }
case (ty_type) { s = "type"; }
case (ty_native) { s += "native"; }
case (ty_nil) { s += "()"; }
case (ty_bool) { s += "bool"; }
case (ty_int) { s += "int"; }
case (ty_uint) { s += "uint"; }
case (ty_machine(?tm)) { s += common.ty_mach_to_str(tm); }
case (ty_char) { s += "char"; }
case (ty_str) { s += "str"; }
case (ty_box(?tm)) { s += "@" + mt_to_str(tm); }
case (ty_vec(?tm)) { s += "vec[" + mt_to_str(tm) + "]"; }
case (ty_port(?t)) { s += "port[" + ty_to_str(t) + "]"; }
case (ty_chan(?t)) { s += "chan[" + ty_to_str(t) + "]"; }
case (ty_type) { s += "type"; }
case (ty_tup(?elems)) {
auto f = ty_to_str;
auto strs = _vec.map[@t,str](f, elems);
s = "tup(" + _str.connect(strs, ",") + ")";
auto f = mt_to_str;
auto strs = _vec.map[mt,str](f, elems);
s += "tup(" + _str.connect(strs, ",") + ")";
}
case (ty_rec(?elems)) {
auto f = field_to_str;
auto strs = _vec.map[field,str](f, elems);
s = "rec(" + _str.connect(strs, ",") + ")";
s += "rec(" + _str.connect(strs, ",") + ")";
}
case (ty_tag(?id, ?tps)) {
// The user should never see this if the cname is set properly!
s = "<tag#" + util.common.istr(id._0) + ":" +
s += "<tag#" + util.common.istr(id._0) + ":" +
util.common.istr(id._1) + ">";
if (_vec.len[@t](tps) > 0u) {
auto f = ty_to_str;
@ -186,31 +196,31 @@ fn field_to_str(&field f) -> str {
}
case (ty_fn(?proto, ?inputs, ?output)) {
s = fn_to_str(proto, none[ast.ident], inputs, output);
s += fn_to_str(proto, none[ast.ident], inputs, output);
}
case (ty_native_fn(_, ?inputs, ?output)) {
s = fn_to_str(ast.proto_fn, none[ast.ident], inputs, output);
s += fn_to_str(ast.proto_fn, none[ast.ident], inputs, output);
}
case (ty_obj(?meths)) {
auto f = method_to_str;
auto m = _vec.map[method,str](f, meths);
s = "obj {\n\t" + _str.connect(m, "\n\t") + "\n}";
s += "obj {\n\t" + _str.connect(m, "\n\t") + "\n}";
}
case (ty_var(?v)) {
s = "<T" + util.common.istr(v) + ">";
s += "<T" + util.common.istr(v) + ">";
}
case (ty_local(?id)) {
s = "<L" + util.common.istr(id._0) + ":" + util.common.istr(id._1)
+ ">";
s += "<L" + util.common.istr(id._0) + ":" +
util.common.istr(id._1) + ">";
}
case (ty_param(?id)) {
s = "<P" + util.common.istr(id._0) + ":" + util.common.istr(id._1)
+ ">";
s += "<P" + util.common.istr(id._0) + ":" +
util.common.istr(id._1) + ">";
}
}
@ -225,7 +235,7 @@ fn field_to_str(&field f) -> str {
fn fold_ty(ty_fold fld, @t ty) -> @t {
fn rewrap(@t orig, &sty new) -> @t {
ret @rec(struct=new, mut=orig.mut, cname=orig.cname);
ret @rec(struct=new, cname=orig.cname);
}
alt (ty.struct) {
@ -238,11 +248,11 @@ fn rewrap(@t orig, &sty new) -> @t {
case (ty_str) { ret fld.fold_simple_ty(ty); }
case (ty_type) { ret fld.fold_simple_ty(ty); }
case (ty_native) { ret fld.fold_simple_ty(ty); }
case (ty_box(?subty)) {
ret rewrap(ty, ty_box(fold_ty(fld, subty)));
case (ty_box(?tm)) {
ret rewrap(ty, ty_box(rec(ty=fold_ty(fld, tm.ty), mut=tm.mut)));
}
case (ty_vec(?subty)) {
ret rewrap(ty, ty_vec(fold_ty(fld, subty)));
case (ty_vec(?tm)) {
ret rewrap(ty, ty_vec(rec(ty=fold_ty(fld, tm.ty), mut=tm.mut)));
}
case (ty_port(?subty)) {
ret rewrap(ty, ty_port(fold_ty(fld, subty)));
@ -257,18 +267,20 @@ fn rewrap(@t orig, &sty new) -> @t {
}
ret rewrap(ty, ty_tag(tid, new_subtys));
}
case (ty_tup(?subtys)) {
let vec[@t] new_subtys = vec();
for (@t subty in subtys) {
new_subtys += vec(fold_ty(fld, subty));
case (ty_tup(?mts)) {
let vec[mt] new_mts = vec();
for (mt tm in mts) {
auto new_subty = fold_ty(fld, tm.ty);
new_mts += vec(rec(ty=new_subty, mut=tm.mut));
}
ret rewrap(ty, ty_tup(new_subtys));
ret rewrap(ty, ty_tup(new_mts));
}
case (ty_rec(?fields)) {
let vec[field] new_fields = vec();
for (field fl in fields) {
auto new_ty = fold_ty(fld, fl.ty);
new_fields += vec(rec(ident=fl.ident, ty=new_ty));
auto new_ty = fold_ty(fld, fl.mt.ty);
auto new_mt = rec(ty=new_ty, mut=fl.mt.mut);
new_fields += vec(rec(ident=fl.ident, mt=new_mt));
}
ret rewrap(ty, ty_rec(new_fields));
}
@ -352,8 +364,8 @@ fn type_is_sequence(@t ty) -> bool {
fn sequence_element_type(@t ty) -> @t {
alt (ty.struct) {
case (ty_str) { ret plain_ty(ty_machine(common.ty_u8)); }
case (ty_vec(?e)) { ret e; }
case (ty_str) { ret plain_ty(ty_machine(common.ty_u8)); }
case (ty_vec(?mt)) { ret mt.ty; }
}
fail;
}
@ -373,11 +385,11 @@ fn type_is_tup_like(@t ty) -> bool {
fn get_element_type(@t ty, uint i) -> @t {
check (type_is_tup_like(ty));
alt (ty.struct) {
case (ty_tup(?tys)) {
ret tys.(i);
case (ty_tup(?mts)) {
ret mts.(i).ty;
}
case (ty_rec(?flds)) {
ret flds.(i).ty;
ret flds.(i).mt.ty;
}
}
fail;
@ -410,6 +422,7 @@ fn type_is_scalar(@t ty) -> bool {
case (ty_machine(_)) { ret true; }
case (ty_char) { ret true; }
case (ty_type) { ret true; }
case (ty_native) { ret true; }
case (_) { ret false; }
}
fail;
@ -427,17 +440,17 @@ fn type_is_native(@t ty) -> bool {
fn type_has_dynamic_size(@t ty) -> bool {
alt (ty.struct) {
case (ty_tup(?ts)) {
case (ty_tup(?mts)) {
auto i = 0u;
while (i < _vec.len[@t](ts)) {
if (type_has_dynamic_size(ts.(i))) { ret true; }
while (i < _vec.len[mt](mts)) {
if (type_has_dynamic_size(mts.(i).ty)) { ret true; }
i += 1u;
}
}
case (ty_rec(?fields)) {
auto i = 0u;
while (i < _vec.len[field](fields)) {
if (type_has_dynamic_size(fields.(i).ty)) { ret true; }
if (type_has_dynamic_size(fields.(i).mt.ty)) { ret true; }
i += 1u;
}
}
@ -518,7 +531,19 @@ fn type_param(@t ty) -> option.t[ast.def_id] {
}
fn plain_ty(&sty st) -> @t {
ret @rec(struct=st, mut=ast.imm, cname=none[str]);
ret @rec(struct=st, cname=none[str]);
}
fn plain_box_ty(@t subty) -> @t {
ret plain_ty(ty_box(rec(ty=subty, mut=ast.imm)));
}
fn plain_tup_ty(vec[@t] elem_tys) -> @t {
let vec[ty.mt] mts = vec();
for (@ty.t typ in elem_tys) {
mts += vec(rec(ty=typ, mut=ast.imm));
}
ret plain_ty(ty_tup(mts));
}
fn hash_ty(&@t ty) -> uint {
@ -703,7 +728,7 @@ fn pat_ty(@ast.pat pat) -> @t {
fn expr_ty(@ast.expr expr) -> @t {
alt (expr.node) {
case (ast.expr_vec(_, ?ann)) { ret ann_to_type(ann); }
case (ast.expr_vec(_, _, ?ann)) { ret ann_to_type(ann); }
case (ast.expr_tup(_, ?ann)) { ret ann_to_type(ann); }
case (ast.expr_rec(_, _, ?ann)) { ret ann_to_type(ann); }
case (ast.expr_bind(_, _, ?ann)) { ret ann_to_type(ann); }
@ -756,7 +781,7 @@ fn field_num(session.session sess, &span sp, &ast.ident id) -> uint {
accum += (c as uint) - ('0' as uint);
} else {
auto s = "";
s += c;
s += _str.unsafe_from_byte(c);
sess.span_err(sp,
"bad numeric field on tuple: "
+ " non-digit character: "
@ -794,6 +819,14 @@ fn method_idx(session.session sess, &span sp,
fail;
}
fn sort_methods(vec[method] meths) -> vec[method] {
fn method_lteq(&method a, &method b) -> bool {
ret _str.lteq(a.ident, b.ident);
}
ret std.sort.merge_sort[method](bind method_lteq(_,_), meths);
}
fn is_lval(@ast.expr expr) -> bool {
alt (expr.node) {
case (ast.expr_field(_,_,_)) { ret true; }
@ -826,6 +859,21 @@ fn struct_cmp(@ty.t expected, @ty.t actual) -> unify_result {
ret ures_err(terr_mismatch, expected, actual);
}
// Unifies two mutability flags.
fn unify_mut(ast.mutability expected, ast.mutability actual)
-> option.t[ast.mutability] {
if (expected == actual) {
ret some[ast.mutability](expected);
}
if (expected == ast.maybe_mut) {
ret some[ast.mutability](actual);
}
if (actual == ast.maybe_mut) {
ret some[ast.mutability](expected);
}
ret none[ast.mutability];
}
tag fn_common_res {
fn_common_res_err(unify_result);
fn_common_res_ok(vec[arg], @t);
@ -1104,7 +1152,7 @@ fn unify_step(@hashmap[int,@ty.t] bindings, @ty.t in_expected,
alt (result) {
case (ures_ok(?rty)) {
append[@ty.t](result_tps, rty);
_vec.push[@ty.t](result_tps, rty);
}
case (_) {
ret result;
@ -1123,16 +1171,26 @@ fn unify_step(@hashmap[int,@ty.t] bindings, @ty.t in_expected,
ret ures_err(terr_mismatch, expected, actual);
}
case (ty.ty_box(?expected_sub)) {
case (ty.ty_box(?expected_mt)) {
alt (actual.struct) {
case (ty.ty_box(?actual_sub)) {
case (ty.ty_box(?actual_mt)) {
auto mut;
alt (unify_mut(expected_mt.mut, actual_mt.mut)) {
case (none[ast.mutability]) {
ret ures_err(terr_box_mutability, expected,
actual);
}
case (some[ast.mutability](?m)) { mut = m; }
}
auto result = unify_step(bindings,
expected_sub,
actual_sub,
expected_mt.ty,
actual_mt.ty,
handler);
alt (result) {
case (ures_ok(?result_sub)) {
ret ures_ok(plain_ty(ty.ty_box(result_sub)));
auto mt = rec(ty=result_sub, mut=mut);
ret ures_ok(plain_ty(ty.ty_box(mt)));
}
case (_) {
ret result;
@ -1146,16 +1204,26 @@ fn unify_step(@hashmap[int,@ty.t] bindings, @ty.t in_expected,
}
}
case (ty.ty_vec(?expected_sub)) {
case (ty.ty_vec(?expected_mt)) {
alt (actual.struct) {
case (ty.ty_vec(?actual_sub)) {
case (ty.ty_vec(?actual_mt)) {
auto mut;
alt (unify_mut(expected_mt.mut, actual_mt.mut)) {
case (none[ast.mutability]) {
ret ures_err(terr_vec_mutability, expected,
actual);
}
case (some[ast.mutability](?m)) { mut = m; }
}
auto result = unify_step(bindings,
expected_sub,
actual_sub,
expected_mt.ty,
actual_mt.ty,
handler);
alt (result) {
case (ures_ok(?result_sub)) {
ret ures_ok(plain_ty(ty.ty_vec(result_sub)));
auto mt = rec(ty=result_sub, mut=mut);
ret ures_ok(plain_ty(ty.ty_vec(mt)));
}
case (_) {
ret result;
@ -1218,8 +1286,8 @@ fn unify_step(@hashmap[int,@ty.t] bindings, @ty.t in_expected,
case (ty.ty_tup(?expected_elems)) {
alt (actual.struct) {
case (ty.ty_tup(?actual_elems)) {
auto expected_len = _vec.len[@ty.t](expected_elems);
auto actual_len = _vec.len[@ty.t](actual_elems);
auto expected_len = _vec.len[ty.mt](expected_elems);
auto actual_len = _vec.len[ty.mt](actual_elems);
if (expected_len != actual_len) {
auto err = terr_tuple_size(expected_len,
actual_len);
@ -1228,23 +1296,30 @@ fn unify_step(@hashmap[int,@ty.t] bindings, @ty.t in_expected,
// TODO: implement an iterator that can iterate over
// two arrays simultaneously.
let vec[@ty.t] result_elems = vec();
let vec[ty.mt] result_elems = vec();
auto i = 0u;
while (i < expected_len) {
auto expected_elem = expected_elems.(i);
auto actual_elem = actual_elems.(i);
if (expected_elem.mut != actual_elem.mut) {
auto err = terr_tuple_mutability;
ret ures_err(err, expected, actual);
auto mut;
alt (unify_mut(expected_elem.mut,
actual_elem.mut)) {
case (none[ast.mutability]) {
auto err = terr_tuple_mutability;
ret ures_err(err, expected, actual);
}
case (some[ast.mutability](?m)) { mut = m; }
}
auto result = unify_step(bindings,
expected_elem,
actual_elem,
expected_elem.ty,
actual_elem.ty,
handler);
alt (result) {
case (ures_ok(?rty)) {
append[@ty.t](result_elems,rty);
auto mt = rec(ty=rty, mut=mut);
result_elems += vec(mt);
}
case (_) {
ret result;
@ -1281,14 +1356,19 @@ fn unify_step(@hashmap[int,@ty.t] bindings, @ty.t in_expected,
while (i < expected_len) {
auto expected_field = expected_fields.(i);
auto actual_field = actual_fields.(i);
if (expected_field.ty.mut
!= actual_field.ty.mut) {
auto err = terr_record_mutability;
ret ures_err(err, expected, actual);
auto mut;
alt (unify_mut(expected_field.mt.mut,
actual_field.mt.mut)) {
case (none[ast.mutability]) {
ret ures_err(terr_record_mutability,
expected, actual);
}
case (some[ast.mutability](?m)) { mut = m; }
}
if (!_str.eq(expected_field.ident,
actual_field.ident)) {
actual_field.ident)) {
auto err =
terr_record_fields(expected_field.ident,
actual_field.ident);
@ -1296,14 +1376,15 @@ fn unify_step(@hashmap[int,@ty.t] bindings, @ty.t in_expected,
}
auto result = unify_step(bindings,
expected_field.ty,
actual_field.ty,
expected_field.mt.ty,
actual_field.mt.ty,
handler);
alt (result) {
case (ures_ok(?rty)) {
append[field]
auto mt = rec(ty=rty, mut=mut);
_vec.push[field]
(result_fields,
rec(ty=rty with expected_field));
rec(mt=mt with expected_field));
}
case (_) {
ret result;
@ -1440,6 +1521,12 @@ fn type_err_to_str(&ty.type_err err) -> str {
case (terr_mismatch) {
ret "types differ";
}
case (terr_box_mutability) {
ret "boxed values differ in mutability";
}
case (terr_vec_mutability) {
ret "vectors differ in mutability";
}
case (terr_tuple_size(?e_sz, ?a_sz)) {
ret "expected a tuple with " + _uint.to_str(e_sz, 10u) +
" elements but found one with " + _uint.to_str(a_sz, 10u) +

View file

@ -4,7 +4,6 @@
import middle.fold;
import driver.session;
import util.common;
import util.common.append;
import util.common.span;
import middle.ty;
@ -277,6 +276,10 @@ fn ast_arg_to_arg(ty_getter getter, &rec(ast.mode mode, @ast.ty ty) arg)
ret rec(mode=arg.mode, ty=ast_ty_to_ty(getter, arg.ty));
}
fn ast_mt_to_mt(ty_getter getter, &ast.mt mt) -> ty.mt {
ret rec(ty=ast_ty_to_ty(getter, mt.ty), mut=mt.mut);
}
fn instantiate(ty_getter getter, ast.def_id id,
vec[@ast.ty] args) -> @ty.t {
// TODO: maybe record cname chains so we can do
@ -306,8 +309,8 @@ fn instantiate(ty_getter getter, ast.def_id id,
case (ast.ty_machine(?tm)) { sty = ty.ty_machine(tm); }
case (ast.ty_char) { sty = ty.ty_char; }
case (ast.ty_str) { sty = ty.ty_str; }
case (ast.ty_box(?t)) { sty = ty.ty_box(ast_ty_to_ty(getter, t)); }
case (ast.ty_vec(?t)) { sty = ty.ty_vec(ast_ty_to_ty(getter, t)); }
case (ast.ty_box(?mt)) { sty = ty.ty_box(ast_mt_to_mt(getter, mt)); }
case (ast.ty_vec(?mt)) { sty = ty.ty_vec(ast_mt_to_mt(getter, mt)); }
case (ast.ty_port(?t)) {
sty = ty.ty_port(ast_ty_to_ty(getter, t));
@ -318,17 +321,17 @@ fn instantiate(ty_getter getter, ast.def_id id,
}
case (ast.ty_tup(?fields)) {
let vec[@ty.t] flds = vec();
for (@ast.ty field in fields) {
append[@ty.t](flds, ast_ty_to_ty(getter, field));
let vec[ty.mt] flds = vec();
for (ast.mt field in fields) {
_vec.push[ty.mt](flds, ast_mt_to_mt(getter, field));
}
sty = ty.ty_tup(flds);
}
case (ast.ty_rec(?fields)) {
let vec[field] flds = vec();
for (ast.ty_field f in fields) {
append[field](flds, rec(ident=f.ident,
ty=ast_ty_to_ty(getter, f.ty)));
_vec.push[field](flds, rec(ident=f.ident,
mt=ast_mt_to_mt(getter, f.mt)));
}
sty = ty.ty_rec(flds);
}
@ -358,30 +361,24 @@ fn instantiate(ty_getter getter, ast.def_id id,
cname = some(path_to_str(path));
}
case (ast.ty_mutable(?t)) {
mut = ast.mut;
auto t0 = ast_ty_to_ty(getter, t);
sty = t0.struct;
cname = t0.cname;
}
case (ast.ty_obj(?meths)) {
let vec[ty.method] tmeths = vec();
auto f = bind ast_arg_to_arg(getter, _);
for (ast.ty_method m in meths) {
auto ins = _vec.map[ast.ty_arg, arg](f, m.inputs);
auto out = ast_ty_to_ty(getter, m.output);
append[ty.method](tmeths,
_vec.push[ty.method](tmeths,
rec(proto=m.proto,
ident=m.ident,
inputs=ins,
output=out));
}
sty = ty.ty_obj(tmeths);
sty = ty.ty_obj(ty.sort_methods(tmeths));
}
}
ret @rec(struct=sty, mut=mut, cname=cname);
ret @rec(struct=sty, cname=cname);
}
fn actual_type(@ty.t t, @ast.item item) -> @ty.t {
@ -546,14 +543,7 @@ fn ty_of_obj(@ty_item_table id_to_ty_item,
auto methods =
_vec.map[@ast.method,method](f, obj_info.methods);
fn method_lteq(&method a, &method b) -> bool {
ret _str.lteq(a.ident, b.ident);
}
methods = std.sort.merge_sort[method](bind method_lteq(_,_),
methods);
auto t_obj = plain_ty(ty.ty_obj(methods));
auto t_obj = plain_ty(ty.ty_obj(ty.sort_methods(methods)));
ret t_obj;
}
@ -565,7 +555,7 @@ fn ty_of_obj_ctor(@ty_item_table id_to_ty_item,
for (ast.obj_field f in obj_info.fields) {
auto g = bind getter(id_to_ty_item, item_to_ty, _);
auto t_field = ast_ty_to_ty(g, f.ty);
append[arg](t_inputs, rec(mode=ast.alias, ty=t_field));
_vec.push[arg](t_inputs, rec(mode=ast.alias, ty=t_field));
}
auto t_fn = plain_ty(ty.ty_fn(ast.proto_fn, t_inputs, t_obj));
ret t_fn;
@ -645,8 +635,7 @@ fn ty_of_native_item(@ty_item_table id_to_ty_item,
// Avoid repeating work.
ret item_to_ty.get(def_id);
}
auto x =
@rec(struct=ty.ty_native, mut=ast.imm, cname=none[str]);
auto x = @rec(struct=ty.ty_native, cname=none[str]);
item_to_ty.insert(def_id, x);
ret x;
}
@ -870,7 +859,7 @@ fn fold_item_obj(&@env e, &span sp, ast.ident i,
with meth.node
);
m = @rec(node=m_ with *meth);
append[@ast.method](methods, m);
_vec.push[@ast.method](methods, m);
}
auto g = bind getter(e.id_to_ty_item, e.item_to_ty, _);
for (ast.obj_field fld in ob.fields) {
@ -879,7 +868,7 @@ fn fold_item_obj(&@env e, &span sp, ast.ident i,
ann=ast.ann_type(fty, none[vec[@ty.t]])
with fld
);
append[ast.obj_field](fields, f);
_vec.push[ast.obj_field](fields, f);
}
auto ob_ = rec(methods = methods,
@ -980,7 +969,7 @@ fn strip_boxes(@ty.t t) -> @ty.t {
auto t1 = t;
while (true) {
alt (t1.struct) {
case (ty.ty_box(?inner)) { t1 = inner; }
case (ty.ty_box(?inner)) { t1 = inner.ty; }
case (_) { ret t1; }
}
}
@ -990,7 +979,7 @@ fn strip_boxes(@ty.t t) -> @ty.t {
fn add_boxes(uint n, @ty.t t) -> @ty.t {
auto t1 = t;
while (n != 0u) {
t1 = plain_ty(ty.ty_box(t1));
t1 = ty.plain_box_ty(t1);
n -= 1u;
}
ret t1;
@ -1002,7 +991,7 @@ fn count_boxes(@ty.t t) -> uint {
auto t1 = t;
while (true) {
alt (t1.struct) {
case (ty.ty_box(?inner)) { n += 1u; t1 = inner; }
case (ty.ty_box(?inner)) { n += 1u; t1 = inner.ty; }
case (_) { ret n; }
}
}
@ -1150,13 +1139,15 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
auto e_1;
alt (e.node) {
case (ast.expr_vec(?es_0, ?ann)) {
case (ast.expr_vec(?es_0, ?mut, ?ann)) {
// TODO: enforce mutability
auto t = demand(fcx, e.span, expected, ann_to_type(ann));
let vec[@ast.expr] es_1 = vec();
alt (t.struct) {
case (ty.ty_vec(?subty)) {
case (ty.ty_vec(?mt)) {
for (@ast.expr e_0 in es_0) {
es_1 += vec(demand_expr(fcx, subty, e_0));
es_1 += vec(demand_expr(fcx, mt.ty, e_0));
}
}
case (_) {
@ -1164,16 +1155,16 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
fail;
}
}
e_1 = ast.expr_vec(es_1, ast.ann_type(t, none[vec[@ty.t]]));
e_1 = ast.expr_vec(es_1, mut, ast.ann_type(t, none[vec[@ty.t]]));
}
case (ast.expr_tup(?es_0, ?ann)) {
auto t = demand(fcx, e.span, expected, ann_to_type(ann));
let vec[ast.elt] elts_1 = vec();
alt (t.struct) {
case (ty.ty_tup(?subtys)) {
case (ty.ty_tup(?mts)) {
auto i = 0u;
for (ast.elt elt_0 in es_0) {
auto e_1 = demand_expr(fcx, subtys.(i), elt_0.expr);
auto e_1 = demand_expr(fcx, mts.(i).ty, elt_0.expr);
elts_1 += vec(rec(mut=elt_0.mut, expr=e_1));
i += 1u;
}
@ -1192,15 +1183,15 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
auto t = demand(fcx, e.span, expected, ann_to_type(ann));
let vec[ast.field] fields_1 = vec();
alt (t.struct) {
case (ty.ty_rec(?field_tys)) {
case (ty.ty_rec(?field_mts)) {
alt (base_0) {
case (none[@ast.expr]) {
auto i = 0u;
for (ast.field field_0 in fields_0) {
check (_str.eq(field_0.ident,
field_tys.(i).ident));
field_mts.(i).ident));
auto e_1 = demand_expr(fcx,
field_tys.(i).ty,
field_mts.(i).mt.ty,
field_0.expr);
fields_1 += vec(rec(mut=field_0.mut,
ident=field_0.ident,
@ -1217,9 +1208,9 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
for (ast.field field_0 in fields_0) {
for (ty.field ft in field_tys) {
for (ty.field ft in field_mts) {
if (_str.eq(field_0.ident, ft.ident)) {
auto e_1 = demand_expr(fcx, ft.ty,
auto e_1 = demand_expr(fcx, ft.mt.ty,
field_0.expr);
fields_1 +=
vec(rec(mut=field_0.mut,
@ -1411,7 +1402,8 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
}
case (_) {
fcx.ccx.sess.unimpl("type unification for expression variant");
fcx.ccx.sess.span_unimpl(e.span,
"type unification for expression variant");
fail;
}
}
@ -1438,8 +1430,10 @@ fn demand_block(&@fn_ctxt fcx, @ty.t expected, &ast.block bloc) -> ast.block {
// Writeback: the phase that writes inferred types back into the AST.
fn writeback_local(&@fn_ctxt fcx, &span sp, @ast.local local)
fn writeback_local(&option.t[@fn_ctxt] env, &span sp, @ast.local local)
-> @ast.decl {
auto fcx = option.get[@fn_ctxt](env);
if (!fcx.locals.contains_key(local.id)) {
fcx.ccx.sess.span_err(sp, "unable to determine type of local: "
+ local.ident);
@ -1453,10 +1447,25 @@ fn writeback_local(&@fn_ctxt fcx, &span sp, @ast.local local)
}
fn writeback(&@fn_ctxt fcx, &ast.block block) -> ast.block {
auto fld = fold.new_identity_fold[@fn_ctxt]();
auto f = writeback_local;
fld = @rec(fold_decl_local = f with *fld);
ret fold.fold_block[@fn_ctxt](fcx, fld, block);
fn update_env_for_item(&option.t[@fn_ctxt] env, @ast.item i)
-> option.t[@fn_ctxt] {
ret none[@fn_ctxt];
}
fn keep_going(&option.t[@fn_ctxt] env) -> bool {
ret !option.is_none[@fn_ctxt](env);
}
auto fld = fold.new_identity_fold[option.t[@fn_ctxt]]();
auto wbl = writeback_local;
auto uefi = update_env_for_item;
auto kg = keep_going;
fld = @rec(
fold_decl_local = wbl,
update_env_for_item = uefi,
keep_going = kg
with *fld
);
ret fold.fold_block[option.t[@fn_ctxt]](some[@fn_ctxt](fcx), fld, block);
}
// AST fragment checking
@ -1572,14 +1581,14 @@ fn check_call_or_bind(&@fn_ctxt fcx, &@ast.expr f,
// FIXME: this breaks aliases. We need a ty_fn_arg.
auto arg_ty = rec(mode=ast.val, ty=expr_ty(a_0));
append[arg](arg_tys_0, arg_ty);
_vec.push[arg](arg_tys_0, arg_ty);
}
case (none[@ast.expr]) {
args_0 += vec(none[@ast.expr]);
// FIXME: breaks aliases too?
auto typ = next_ty_var(fcx.ccx);
append[arg](arg_tys_0, rec(mode=ast.val, ty=typ));
_vec.push[arg](arg_tys_0, rec(mode=ast.val, ty=typ));
}
}
}
@ -1623,10 +1632,11 @@ fn check_call_or_bind(&@fn_ctxt fcx, &@ast.expr f,
case (some[@ast.expr](?e_0)) {
auto arg_ty_1 = arg_tys_1.(i);
auto e_1 = demand_expr(fcx, arg_ty_1.ty, e_0);
append[option.t[@ast.expr]](args_1, some[@ast.expr](e_1));
_vec.push[option.t[@ast.expr]](args_1,
some[@ast.expr](e_1));
}
case (none[@ast.expr]) {
append[option.t[@ast.expr]](args_1, none[@ast.expr]);
_vec.push[option.t[@ast.expr]](args_1, none[@ast.expr]);
}
}
@ -1693,11 +1703,14 @@ fn check_assignment(&@fn_ctxt fcx, @ast.expr lhs, @ast.expr rhs)
auto oper_1 = check_expr(fcx, oper);
auto oper_t = expr_ty(oper_1);
alt (unop) {
case (ast.box) { oper_t = plain_ty(ty.ty_box(oper_t)); }
case (ast.box) {
// TODO: mutable
oper_t = ty.plain_box_ty(oper_t);
}
case (ast.deref) {
alt (oper_t.struct) {
case (ty.ty_box(?inner_t)) {
oper_t = inner_t;
case (ty.ty_box(?inner)) {
oper_t = inner.ty;
}
case (_) {
fcx.ccx.sess.span_err
@ -1707,9 +1720,6 @@ fn check_assignment(&@fn_ctxt fcx, @ast.expr lhs, @ast.expr rhs)
}
}
}
case (ast._mutable) {
oper_t = @rec(mut=ast.mut with *oper_t);
}
case (_) { oper_t = strip_boxes(oper_t); }
}
@ -2096,12 +2106,9 @@ fn check_assignment(&@fn_ctxt fcx, @ast.expr lhs, @ast.expr rhs)
ast.expr_cast(e_1, t, ann));
}
case (ast.expr_vec(?args, _)) {
case (ast.expr_vec(?args, ?mut, _)) {
let vec[@ast.expr] args_1 = vec();
// FIXME: implement mutable vectors with leading 'mutable' flag
// marking the elements as mutable.
let @ty.t t;
if (_vec.len[@ast.expr](args) == 0u) {
t = next_ty_var(fcx.ccx);
@ -2114,28 +2121,27 @@ fn check_assignment(&@fn_ctxt fcx, @ast.expr lhs, @ast.expr rhs)
auto expr_1 = check_expr(fcx, e);
auto expr_t = expr_ty(expr_1);
demand(fcx, expr.span, t, expr_t);
append[@ast.expr](args_1,expr_1);
_vec.push[@ast.expr](args_1,expr_1);
}
auto ann = ast.ann_type(plain_ty(ty.ty_vec(t)), none[vec[@ty.t]]);
auto vec_sty = ty.ty_vec(rec(ty=t, mut=mut));
auto ann = ast.ann_type(plain_ty(vec_sty), none[vec[@ty.t]]);
ret @fold.respan[ast.expr_](expr.span,
ast.expr_vec(args_1, ann));
ast.expr_vec(args_1, mut, ann));
}
case (ast.expr_tup(?elts, _)) {
let vec[ast.elt] elts_1 = vec();
let vec[@ty.t] elts_t = vec();
let vec[ty.mt] elts_mt = vec();
for (ast.elt e in elts) {
auto expr_1 = check_expr(fcx, e.expr);
auto expr_t = expr_ty(expr_1);
if (e.mut == ast.mut) {
expr_t = @rec(mut=ast.mut with *expr_t);
}
append[ast.elt](elts_1, rec(expr=expr_1 with e));
append[@ty.t](elts_t, expr_t);
_vec.push[ast.elt](elts_1, rec(expr=expr_1 with e));
elts_mt += vec(rec(ty=expr_t, mut=e.mut));
}
auto ann = ast.ann_type(plain_ty(ty.ty_tup(elts_t)),
auto ann = ast.ann_type(plain_ty(ty.ty_tup(elts_mt)),
none[vec[@ty.t]]);
ret @fold.respan[ast.expr_](expr.span,
ast.expr_tup(elts_1, ann));
@ -2157,11 +2163,10 @@ fn check_assignment(&@fn_ctxt fcx, @ast.expr lhs, @ast.expr rhs)
for (ast.field f in fields) {
auto expr_1 = check_expr(fcx, f.expr);
auto expr_t = expr_ty(expr_1);
if (f.mut == ast.mut) {
expr_t = @rec(mut=ast.mut with *expr_t);
}
append[ast.field](fields_1, rec(expr=expr_1 with f));
append[field](fields_t, rec(ident=f.ident, ty=expr_t));
_vec.push[ast.field](fields_1, rec(expr=expr_1 with f));
auto expr_mt = rec(ty=expr_t, mut=f.mut);
_vec.push[field](fields_t, rec(ident=f.ident, mt=expr_mt));
}
auto ann = ast.ann_none;
@ -2195,7 +2200,7 @@ fn check_assignment(&@fn_ctxt fcx, @ast.expr lhs, @ast.expr rhs)
auto found = false;
for (ty.field bf in base_fields) {
if (_str.eq(f.ident, bf.ident)) {
demand(fcx, expr.span, f.ty, bf.ty);
demand(fcx, expr.span, f.mt.ty, bf.mt.ty);
found = true;
}
}
@ -2220,11 +2225,11 @@ fn check_assignment(&@fn_ctxt fcx, @ast.expr lhs, @ast.expr rhs)
case (ty.ty_tup(?args)) {
let uint ix = ty.field_num(fcx.ccx.sess,
expr.span, field);
if (ix >= _vec.len[@ty.t](args)) {
if (ix >= _vec.len[ty.mt](args)) {
fcx.ccx.sess.span_err(expr.span,
"bad index on tuple");
}
auto ann = ast.ann_type(args.(ix), none[vec[@ty.t]]);
auto ann = ast.ann_type(args.(ix).ty, none[vec[@ty.t]]);
ret @fold.respan[ast.expr_](expr.span,
ast.expr_field(base_1,
field,
@ -2238,7 +2243,8 @@ fn check_assignment(&@fn_ctxt fcx, @ast.expr lhs, @ast.expr rhs)
fcx.ccx.sess.span_err(expr.span,
"bad index on record");
}
auto ann = ast.ann_type(fields.(ix).ty, none[vec[@ty.t]]);
auto ann = ast.ann_type(fields.(ix).mt.ty,
none[vec[@ty.t]]);
ret @fold.respan[ast.expr_](expr.span,
ast.expr_field(base_1,
field,
@ -2278,14 +2284,14 @@ fn check_assignment(&@fn_ctxt fcx, @ast.expr lhs, @ast.expr rhs)
auto idx_t = expr_ty(idx_1);
alt (base_t.struct) {
case (ty.ty_vec(?t)) {
case (ty.ty_vec(?mt)) {
if (! type_is_integral(idx_t)) {
fcx.ccx.sess.span_err
(idx.span,
"non-integral type of vec index: "
+ ty_to_str(idx_t));
}
auto ann = ast.ann_type(t, none[vec[@ty.t]]);
auto ann = ast.ann_type(mt.ty, none[vec[@ty.t]]);
ret @fold.respan[ast.expr_](expr.span,
ast.expr_index(base_1,
idx_1,
@ -2418,7 +2424,7 @@ fn check_stmt(&@fn_ctxt fcx, &@ast.stmt stmt) -> @ast.stmt {
fn check_block(&@fn_ctxt fcx, &ast.block block) -> ast.block {
let vec[@ast.stmt] stmts = vec();
for (@ast.stmt s in block.node.stmts) {
append[@ast.stmt](stmts, check_stmt(fcx, s));
_vec.push[@ast.stmt](stmts, check_stmt(fcx, s));
}
auto expr = none[@ast.expr];

View file

@ -39,12 +39,12 @@ fn mkstate(io.writer out, uint width) -> ps {
impure fn push_context(ps p, contexttype tp, uint indent) {
before_print(p, false);
p.context = _vec.push[context](p.context, rec(tp=tp, indent=base_indent(p)
+ indent));
_vec.push[context](p.context, rec(tp=tp, indent=base_indent(p)
+ indent));
}
impure fn pop_context(ps p) {
p.context = _vec.pop[context](p.context);
fn pop_context(ps p) {
_vec.pop[context](p.context);
}
impure fn add_token(ps p, token tok) {
@ -110,7 +110,8 @@ fn mkstate(io.writer out, uint width) -> ps {
}
p.scandepth = 0u;
push_context(p, tp, indent);
for (token t in _vec.shift[token](p.buffered)) {add_token(p, t);}
_vec.shift[token](p.buffered);
for (token t in p.buffered) { add_token(p, t); }
}
impure fn finish_break_scan(ps p) {
@ -125,7 +126,8 @@ fn mkstate(io.writer out, uint width) -> ps {
p.col += width;
}
p.scandepth = 0u;
for (token t in _vec.shift[token](p.buffered)) {add_token(p, t);}
_vec.shift[token](p.buffered);
for (token t in p.buffered) { add_token(p, t); }
}
impure fn start_scan(ps p, token tok) {

View file

@ -48,7 +48,7 @@ fn ty_to_str(&@ast.ty ty) -> str {
end(s);
pp.cwrd(s, "}");
}
impure fn commasep[IN](ps s, vec[IN] elts, impure fn (ps, IN) op) {
impure fn commasep[IN](ps s, vec[IN] elts, impure fn (ps, &IN) op) {
auto first = true;
for (IN elt in elts) {
if (first) {first = false;}
@ -57,7 +57,16 @@ fn ty_to_str(&@ast.ty ty) -> str {
}
}
impure fn print_type(ps s, @ast.ty ty) {
impure fn print_mt(ps s, &ast.mt mt) {
alt (mt.mut) {
case (ast.mut) { wrd1(s, "mutable"); }
case (ast.maybe_mut) { wrd1(s, "mutable?"); }
case (ast.imm) { /* nothing */ }
}
print_type(s, mt.ty);
}
impure fn print_type(ps s, &@ast.ty ty) {
hbox(s);
alt (ty.node) {
case (ast.ty_nil) {wrd(s, "()");}
@ -67,22 +76,22 @@ fn ty_to_str(&@ast.ty ty) -> str {
case (ast.ty_machine(?tm)) {wrd(s, util.common.ty_mach_to_str(tm));}
case (ast.ty_char) {wrd(s, "char");}
case (ast.ty_str) {wrd(s, "str");}
case (ast.ty_box(?t)) {wrd(s, "@"); print_type(s, t);}
case (ast.ty_vec(?t)) {wrd(s, "vec["); print_type(s, t); wrd(s, "]");}
case (ast.ty_box(?mt)) {wrd(s, "@"); print_mt(s, mt);}
case (ast.ty_vec(?mt)) {wrd(s, "vec["); print_mt(s, mt); wrd(s, "]");}
case (ast.ty_type) {wrd(s, "type");}
case (ast.ty_tup(?elts)) {
wrd(s, "tup");
popen(s);
auto f = print_type;
commasep[@ast.ty](s, elts, f);
auto f = print_mt;
commasep[ast.mt](s, elts, f);
pclose(s);
}
case (ast.ty_rec(?fields)) {
wrd(s, "rec");
popen(s);
impure fn print_field(ps s, ast.ty_field f) {
impure fn print_field(ps s, &ast.ty_field f) {
hbox(s);
print_type(s, f.ty);
print_mt(s, f.mt);
space(s);
wrd(s, f.ident);
end(s);
@ -110,10 +119,6 @@ fn ty_to_str(&@ast.ty ty) -> str {
case (ast.ty_path(?path,_)) {
print_path(s, path);
}
case (ast.ty_mutable(?t)) {
wrd1(s, "mutable");
print_type(s, t);
}
}
end(s);
}
@ -186,7 +191,7 @@ fn ty_to_str(&@ast.ty ty) -> str {
wrd(s, v.name);
if (_vec.len[ast.variant_arg](v.args) > 0u) {
popen(s);
impure fn print_variant_arg(ps s, ast.variant_arg arg) {
impure fn print_variant_arg(ps s, &ast.variant_arg arg) {
print_type(s, arg.ty);
}
auto f = print_variant_arg;
@ -203,7 +208,7 @@ fn ty_to_str(&@ast.ty ty) -> str {
wrd(s, id);
print_type_params(s, params);
popen(s);
impure fn print_field(ps s, ast.obj_field field) {
impure fn print_field(ps s, &ast.obj_field field) {
hbox(s);
print_type(s, field.ty);
space(s);
@ -285,18 +290,21 @@ fn ty_to_str(&@ast.ty ty) -> str {
}
}
impure fn print_expr(ps s, @ast.expr expr) {
impure fn print_expr(ps s, &@ast.expr expr) {
auto pe = print_expr;
hbox(s);
alt (expr.node) {
case (ast.expr_vec(?exprs,_)) {
case (ast.expr_vec(?exprs,?mut,_)) {
if (mut == ast.mut) {
wrd1(s, "mutable");
}
wrd(s, "vec");
popen(s);
commasep[@ast.expr](s, exprs, pe);
pclose(s);
}
case (ast.expr_tup(?exprs,_)) {
impure fn printElt(ps s, ast.elt elt) {
impure fn printElt(ps s, &ast.elt elt) {
hbox(s);
if (elt.mut == ast.mut) {wrd1(s, "mutable");}
print_expr(s, elt.expr);
@ -309,7 +317,7 @@ fn ty_to_str(&@ast.ty ty) -> str {
pclose(s);
}
case (ast.expr_rec(?fields,?wth,_)) {
impure fn print_field(ps s, ast.field field) {
impure fn print_field(ps s, &ast.field field) {
hbox(s);
if (field.mut == ast.mut) {wrd1(s, "mutable");}
wrd(s, field.ident);
@ -340,7 +348,7 @@ fn ty_to_str(&@ast.ty ty) -> str {
pclose(s);
}
case (ast.expr_bind(?func,?args,_)) {
impure fn print_opt(ps s, option.t[@ast.expr] expr) {
impure fn print_opt(ps s, &option.t[@ast.expr] expr) {
alt (expr) {
case (option.some[@ast.expr](?expr)) {
print_expr(s, expr);
@ -364,7 +372,6 @@ fn ty_to_str(&@ast.ty ty) -> str {
}
case (ast.expr_unary(?op,?expr,_)) {
wrd(s, ast.unop_to_str(op));
if (op == ast._mutable) {space(s);}
print_expr(s, expr);
}
case (ast.expr_lit(?lit,_)) {
@ -577,7 +584,7 @@ fn ty_to_str(&@ast.ty ty) -> str {
}
}
impure fn print_pat(ps s, @ast.pat pat) {
impure fn print_pat(ps s, &@ast.pat pat) {
alt (pat.node) {
case (ast.pat_wild(_)) {wrd(s, "_");}
case (ast.pat_bind(?id,_,_)) {wrd(s, "?" + id);}
@ -605,7 +612,7 @@ fn ty_to_str(&@ast.ty ty) -> str {
wrd(s, name);
print_type_params(s, typarams);
popen(s);
impure fn print_arg(ps s, ast.arg x) {
impure fn print_arg(ps s, &ast.arg x) {
hbox(s);
print_type(s, x.ty);
space(s);
@ -627,7 +634,7 @@ fn ty_to_str(&@ast.ty ty) -> str {
impure fn print_type_params(ps s, vec[ast.ty_param] params) {
if (_vec.len[ast.ty_param](params) > 0u) {
wrd(s, "[");
impure fn printParam(ps s, ast.ty_param param) {wrd(s, param.ident);}
impure fn printParam(ps s, &ast.ty_param param) {wrd(s, param.ident);}
auto f = printParam;
commasep[ast.ty_param](s, params, f);
wrd(s, "]");
@ -642,7 +649,7 @@ fn ty_to_str(&@ast.ty ty) -> str {
wrd(s, id);
if (_vec.len[@ast.meta_item](mta) > 0u) {
popen(s);
impure fn print_meta(ps s, @ast.meta_item item) {
impure fn print_meta(ps s, &@ast.meta_item item) {
hbox(s);
wrd1(s, item.node.name);
wrd1(s, "=");
@ -717,7 +724,7 @@ fn escape_str(str st, char to_escape) -> str {
case ('\\') {out += "\\\\";}
case (?cur) {
if (cur == to_escape) {out += "\\";}
out += cur as u8;
_str.push_byte(out, cur as u8);
}
}
i += 1u;
@ -738,7 +745,7 @@ fn escape_str(str st, char to_escape) -> str {
case (_) {}
}
popen(s);
impure fn print_arg(ps s, ast.ty_arg input) {
impure fn print_arg(ps s, &ast.ty_arg input) {
if (middle.ty.mode_is_alias(input.mode)) {wrd(s, "&");}
print_type(s, input.ty);
}

View file

@ -68,15 +68,6 @@ fn istr(int i) -> str {
ret _int.to_str(i, 10u);
}
// FIXME: Weird bug. Due to the way we auto-deref + in +=, we can't append a
// boxed value to a vector-of-boxes using +=. Best to figure out a way to fix
// this. Deref-on-demand or something? It's a hazard of the ambiguity between
// single-element and vector append.
fn append[T](&mutable vec[T] v, &T t) {
v += t;
}
//
// Local Variables:
// mode: rust

View file

@ -1,39 +0,0 @@
#!/bin/sh
CFG_SRC_DIR=${0%${0##*/}}
CFG_BUILD_DIR=$PWD
CFG_OSTYPE=$(uname -s)
CFG_CPUTYPE=$(uname -m)
echo "configuring on $CFG_CPUTYPE $CFG_OSTYPE"
echo "setting up build directories"
for i in boot/{fe,me,be,driver,util} \
rt/{isaac,bigint,sync,test} \
stage{0,1,2} \
test/{run-pass,compile-{pass,fail}}
do
mkdir -p -v $i
done
CFG_VALGRIND=$(sh which valgrind)
CFG_OCAMLC_OPT=$(sh which ocamlc.opt)
echo "copying Makefile"
cp -v ${CFG_SRC_DIR}Makefile.in ./Makefile
echo "writing config.mk"
cat >config.mk <<EOF
CFG_OSTYPE := $CFG_OSTYPE
CFG_CPUTYPE := $CFG_CPUTYPE
CFG_SRC_DIR := $CFG_SRC_DIR
CFG_BUILD_DIR := $CFG_BUILD_DIR
CFG_VALGRIND := $CFG_VALGRIND
CFG_OCAMLC_OPT := $CFG_OCAMLC_OPT
EOF
echo "configured ok"

View file

@ -8,6 +8,8 @@
fn str_byte_len(str s) -> uint;
fn str_alloc(uint n_bytes) -> str;
fn str_from_vec(vec[u8] b) -> str;
fn str_from_cstr(sbuf cstr) -> str;
fn str_from_buf(sbuf buf, uint len) -> str;
fn refcount[T](str s) -> uint;
}
@ -111,6 +113,19 @@ fn unsafe_from_bytes(vec[u8] v) -> str {
ret rustrt.str_from_vec(v);
}
fn unsafe_from_byte(u8 u) -> str {
ret rustrt.str_from_vec(vec(u));
}
unsafe fn str_from_cstr(sbuf cstr) -> str {
ret rustrt.str_from_cstr(cstr);
}
unsafe fn str_from_buf(sbuf buf, uint len) -> str {
ret rustrt.str_from_buf(buf, len);
}
fn refcount(str s) -> uint {
auto r = rustrt.refcount[u8](s);
if (r == dbg.const_refcount) {
@ -190,7 +205,6 @@ fn starts_with(str haystack, str needle) -> bool {
ret eq(substr(haystack, 0u, needle_len), needle);
}
fn ends_with(str haystack, str needle) -> bool {
let uint haystack_len = byte_len(haystack);
let uint needle_len = byte_len(needle);
@ -206,34 +220,60 @@ fn ends_with(str haystack, str needle) -> bool {
needle);
}
fn substr(str s, uint begin, uint len) -> str {
let str accum = "";
let uint i = begin;
while (i < begin+len) {
accum += s.(i);
accum += unsafe_from_byte(s.(i));
i += 1u;
}
ret accum;
}
fn shift_byte(&mutable str s) -> u8 {
auto len = byte_len(s);
check(len > 0u);
auto b = s.(0);
s = substr(s, 1u, len - 1u);
ret b;
}
fn pop_byte(&mutable str s) -> u8 {
auto len = byte_len(s);
check(len > 0u);
auto b = s.(len - 1u);
s = substr(s, 0u, len - 1u);
ret b;
}
fn push_byte(&mutable str s, u8 b) {
s += unsafe_from_byte(b);
}
fn unshift_byte(&mutable str s, u8 b) {
auto res = alloc(byte_len(s) + 1u);
res += unsafe_from_byte(b);
res += s;
s = res;
}
fn split(str s, u8 sep) -> vec[str] {
let vec[str] v = vec();
let str accum = "";
let bool ends_with_sep = false;
for (u8 c in s) {
if (c == sep) {
v += accum;
v += vec(accum);
accum = "";
ends_with_sep = true;
} else {
accum += c;
accum += unsafe_from_byte(c);
ends_with_sep = false;
}
}
if (_str.byte_len(accum) != 0u ||
ends_with_sep) {
v += accum;
v += vec(accum);
}
ret v;
}

View file

@ -61,7 +61,7 @@ fn digit(uint n) -> char {
let str s = "";
while (n != 0u) {
s += digit(n % radix) as u8;
s += _str.unsafe_from_byte(digit(n % radix) as u8);
n /= radix;
}
@ -69,7 +69,7 @@ fn digit(uint n) -> char {
let uint len = _str.byte_len(s);
while (len != 0u) {
len -= 1u;
s1 += s.(len);
s1 += _str.unsafe_from_byte(s.(len));
}
ret s1;

View file

@ -103,28 +103,32 @@ fn slice[T](vec[T] v, uint start, uint end) -> vec[T] {
ret result;
}
fn shift[T](vec[T] v) -> vec[T] {
check(len[T](v) > 0u);
ret slice[T](v, 1u, len[T](v));
fn shift[T](&mutable vec[T] v) -> T {
auto ln = len[T](v);
check(ln > 0u);
auto e = v.(0);
v = slice[T](v, 1u, ln);
ret e;
}
fn pop[T](vec[T] v) -> vec[T] {
check(len[T](v) > 0u);
ret slice[T](v, 0u, len[T](v) - 1u);
fn pop[T](&mutable vec[T] v) -> T {
auto ln = len[T](v);
check(ln > 0u);
ln -= 1u;
auto e = v.(ln);
v = slice[T](v, 0u, ln);
ret e;
}
fn push[T](vec[T] v, &T t) -> vec[T] {
v += t;
ret v;
fn push[T](&mutable vec[T] v, &T t) {
v += vec(t);
}
fn unshift[T](vec[T] v, &T t) -> vec[T] {
fn unshift[T](&mutable vec[T] v, &T t) {
auto res = alloc[T](len[T](v) + 1u);
res += t;
for (T t_ in v) {
res += t_;
}
ret res;
res += vec(t);
res += v;
v = res;
}
fn grow[T](&mutable vec[T] v, int n, &T initval) {
@ -152,7 +156,7 @@ fn map2[T,U,V](&operator2[T,U,V] f, &vec[T] v0, &vec[U] v1) -> vec[V] {
let vec[V] u = alloc[V](v0_len);
auto i = 0u;
while (i < v0_len) {
u += f(v0.(i), v1.(i));
u += vec(f(v0.(i), v1.(i)));
i += 1u;
}

View file

@ -38,8 +38,18 @@ fn connect(path pre, path post) -> path {
let vec[str] full_paths = vec();
for (str filename in os_fs.list_dir(p)) {
if (!_str.eq(filename, ".")) {if (!_str.eq(filename, "..")) {
full_paths = _vec.push[str](full_paths, p + filename);
_vec.push[str](full_paths, p + filename);
}}
}
ret full_paths;
}
// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:

View file

@ -52,7 +52,8 @@
auto buf = "";
while (true) {
auto ch = os.libc.fgetc(f);
if (ch == -1) {break;} if (ch == 10) {break;}
if (ch == -1) { ret buf; }
if (ch == 10) { ret buf; }
buf += _str.unsafe_from_bytes(vec(ch as u8));
}
ret buf;
@ -61,7 +62,7 @@
auto buf = "";
while (true) {
auto ch = os.libc.fgetc(f);
if (ch < 1) {break;}
if (ch < 1) { ret buf; }
buf += _str.unsafe_from_bytes(vec(ch as u8));
}
ret buf;

View file

@ -31,6 +31,13 @@ fn map[T, U](&operator[T, U] f, &t[T] opt) -> t[U] {
fail; // FIXME: remove me when exhaustiveness checking works
}
fn is_none[T](&t[T] opt) -> bool {
alt (opt) {
case (none[T]) { ret true; }
case (some[T](_)) { ret false; }
}
}
// Local Variables:
// mode: rust;
// fill-column: 78;

View file

@ -9,11 +9,23 @@
let vec[str] result = vec();
while (true) {
auto ent = os.libc.readdir(dir);
if (ent as int == 0) {break;}
result = _vec.push[str](result, rustrt.rust_dirent_filename(ent));
if (ent as int == 0) {
os.libc.closedir(dir);
ret result;
}
_vec.push[str](result, rustrt.rust_dirent_filename(ent));
}
os.libc.closedir(dir);
ret result;
}
const char path_sep = '/';
// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:

View file

@ -8,9 +8,9 @@
fn argvec(str prog, vec[str] args) -> vec[sbuf] {
auto argptrs = vec(_str.buf(prog));
for (str arg in args) {
argptrs = _vec.push[sbuf](argptrs, _str.buf(arg));
_vec.push[sbuf](argptrs, _str.buf(arg));
}
argptrs = _vec.push[sbuf](argptrs, 0 as sbuf);
_vec.push[sbuf](argptrs, 0 as sbuf);
ret argptrs;
}

View file

@ -169,10 +169,11 @@ fn circular_shift(u32 bits, u32 word) -> u32 {
let vec[u8] res = vec();
for (u32 hpart in st.h) {
res += (hpart >> 24u32) & 0xFFu32 as u8;
res += (hpart >> 16u32) & 0xFFu32 as u8;
res += (hpart >> 8u32) & 0xFFu32 as u8;
res += hpart & 0xFFu32 as u8;
auto a = (hpart >> 24u32) & 0xFFu32 as u8;
auto b = (hpart >> 16u32) & 0xFFu32 as u8;
auto c = (hpart >> 8u32) & 0xFFu32 as u8;
auto d = (hpart & 0xFFu32 as u8);
res += vec(a,b,c,d);
}
ret res;
}

View file

@ -5,38 +5,38 @@
fn merge_sort[T](lteq[T] le, vec[T] v) -> vec[T] {
fn merge[T](lteq[T] le, vec[T] a, vec[T] b) -> vec[T] {
let vec[T] res = vec();
let uint a_len = len[T](a);
let uint a_ix = 0u;
let uint b_len = len[T](b);
let uint b_ix = 0u;
while (a_ix < a_len && b_ix < b_len) {
if (le(a.(a_ix), b.(b_ix))) {
res += a.(a_ix);
a_ix += 1u;
} else {
res += b.(b_ix);
b_ix += 1u;
}
fn merge[T](lteq[T] le, vec[T] a, vec[T] b) -> vec[T] {
let vec[T] res = vec();
let uint a_len = len[T](a);
let uint a_ix = 0u;
let uint b_len = len[T](b);
let uint b_ix = 0u;
while (a_ix < a_len && b_ix < b_len) {
if (le(a.(a_ix), b.(b_ix))) {
res += vec(a.(a_ix));
a_ix += 1u;
} else {
res += vec(b.(b_ix));
b_ix += 1u;
}
}
res += slice[T](a, a_ix, a_len);
res += slice[T](b, b_ix, b_len);
ret res;
}
res += slice[T](a, a_ix, a_len);
res += slice[T](b, b_ix, b_len);
ret res;
}
let uint v_len = len[T](v);
let uint v_len = len[T](v);
if (v_len <= 1u) {
ret v;
}
if (v_len <= 1u) {
ret v;
}
let uint mid = v_len / 2u;
let vec[T] a = slice[T](v, 0u, mid);
let vec[T] b = slice[T](v, mid, v_len);
ret merge[T](le,
merge_sort[T](le, a),
merge_sort[T](le, b));
let uint mid = v_len / 2u;
let vec[T] a = slice[T](v, 0u, mid);
let vec[T] b = slice[T](v, mid, v_len);
ret merge[T](le,
merge_sort[T](le, a),
merge_sort[T](le, b));
}
// Local Variables:

View file

@ -34,6 +34,17 @@ auth _str = unsafe;
auth _vec = unsafe;
auth _task = unsafe;
// FIXME: impure on these will infect caller in a way that is totally
// beyond reason, if the caller's mutated-argument doesn't escape;
// 'impure' needs work.
auth _str.unshift_byte = impure;
auth _str.shift_byte = impure;
auth _str.pop_byte = impure;
auth _vec.shift = impure;
auth _vec.unshift = impure;
auth _vec.pop = impure;
auth dbg = unsafe;
auth _uint.next_power_of_two = unsafe;

View file

@ -8,3 +8,12 @@
}
const char path_sep = '\\';
// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:

473
src/llvmext/rustllvm.def Normal file
View file

@ -0,0 +1,473 @@
LIBRARY RUSTLLVM
EXPORTS
LLVMRustCreateMemoryBufferWithContentsOfFile
LLVMRustGetLastError
LLVMCreateObjectFile
LLVMDisposeObjectFile
LLVMGetSections
LLVMDisposeSectionIterator
LLVMIsSectionIteratorAtEnd
LLVMMoveToNextSection
LLVMGetSectionName
LLVMGetSectionSize
LLVMGetSectionContents
LLVMABIAlignmentOfType
LLVMABISizeOfType
LLVMAddAlias
LLVMAddAttribute
LLVMAddCase
LLVMAddDestination
LLVMAddFunction
LLVMAddFunctionAttr
LLVMAddGlobal
LLVMAddGlobalInAddressSpace
LLVMAddGlobalMapping
LLVMAddIncoming
LLVMAddInstrAttribute
LLVMAddModule
LLVMAddModuleProvider
LLVMAddTargetData
LLVMAddTypeName
LLVMAlignOf
LLVMAppendBasicBlock
LLVMAppendBasicBlockInContext
LLVMArrayType
LLVMBasicBlockAsValue
LLVMBlockAddress
LLVMBuildAShr
LLVMBuildAdd
LLVMBuildAggregateRet
LLVMBuildAlloca
LLVMBuildAnd
LLVMBuildArrayAlloca
LLVMBuildArrayMalloc
LLVMBuildBinOp
LLVMBuildBitCast
LLVMBuildBr
LLVMBuildCall
LLVMBuildCast
LLVMBuildCondBr
LLVMBuildExactSDiv
LLVMBuildExtractElement
LLVMBuildExtractValue
LLVMBuildFAdd
LLVMBuildFCmp
LLVMBuildFDiv
LLVMBuildFMul
LLVMBuildFNeg
LLVMBuildFPCast
LLVMBuildFPExt
LLVMBuildFPToSI
LLVMBuildFPToUI
LLVMBuildFPTrunc
LLVMBuildFRem
LLVMBuildFSub
LLVMBuildFree
LLVMBuildGEP
LLVMBuildGlobalString
LLVMBuildGlobalStringPtr
LLVMBuildICmp
LLVMBuildInBoundsGEP
LLVMBuildIndirectBr
LLVMBuildInsertElement
LLVMBuildInsertValue
LLVMBuildIntCast
LLVMBuildIntToPtr
LLVMBuildInvoke
LLVMBuildIsNotNull
LLVMBuildIsNull
LLVMBuildLShr
LLVMBuildLoad
LLVMBuildMalloc
LLVMBuildMul
LLVMBuildNSWAdd
LLVMBuildNSWMul
LLVMBuildNSWNeg
LLVMBuildNSWSub
LLVMBuildNUWAdd
LLVMBuildNUWMul
LLVMBuildNUWNeg
LLVMBuildNUWSub
LLVMBuildNeg
LLVMBuildNot
LLVMBuildOr
LLVMBuildPhi
LLVMBuildPointerCast
LLVMBuildPtrDiff
LLVMBuildPtrToInt
LLVMBuildRet
LLVMBuildRetVoid
LLVMBuildSDiv
LLVMBuildSExt
LLVMBuildSExtOrBitCast
LLVMBuildSIToFP
LLVMBuildSRem
LLVMBuildSelect
LLVMBuildShl
LLVMBuildShuffleVector
LLVMBuildStore
LLVMBuildStructGEP
LLVMBuildSub
LLVMBuildSwitch
LLVMBuildTrunc
LLVMBuildTruncOrBitCast
LLVMBuildUDiv
LLVMBuildUIToFP
LLVMBuildURem
LLVMBuildUnreachable
LLVMBuildUnwind
LLVMBuildVAArg
LLVMBuildXor
LLVMBuildZExt
LLVMBuildZExtOrBitCast
LLVMByteOrder
LLVMCallFrameAlignmentOfType
LLVMClearInsertionPosition
LLVMConstAShr
LLVMConstAdd
LLVMConstAllOnes
LLVMConstAnd
LLVMConstArray
LLVMConstBitCast
LLVMConstExactSDiv
LLVMConstExtractElement
LLVMConstExtractValue
LLVMConstFAdd
LLVMConstFCmp
LLVMConstFDiv
LLVMConstFMul
LLVMConstFNeg
LLVMConstFPCast
LLVMConstFPExt
LLVMConstFPToSI
LLVMConstFPToUI
LLVMConstFPTrunc
LLVMConstFRem
LLVMConstFSub
LLVMConstGEP
LLVMConstICmp
LLVMConstInBoundsGEP
LLVMConstInlineAsm
LLVMConstInsertElement
LLVMConstInsertValue
LLVMConstInt
LLVMConstIntCast
LLVMConstIntGetSExtValue
LLVMConstIntGetZExtValue
LLVMConstIntOfArbitraryPrecision
LLVMConstIntOfString
LLVMConstIntOfStringAndSize
LLVMConstIntToPtr
LLVMConstLShr
LLVMConstMul
LLVMConstNSWAdd
LLVMConstNSWMul
LLVMConstNSWNeg
LLVMConstNSWSub
LLVMConstNUWAdd
LLVMConstNUWMul
LLVMConstNUWNeg
LLVMConstNUWSub
LLVMConstNeg
LLVMConstNot
LLVMConstNull
LLVMConstOr
LLVMConstPointerCast
LLVMConstPointerNull
LLVMConstPtrToInt
LLVMConstReal
LLVMConstRealOfString
LLVMConstRealOfStringAndSize
LLVMConstSDiv
LLVMConstSExt
LLVMConstSExtOrBitCast
LLVMConstSIToFP
LLVMConstSRem
LLVMConstSelect
LLVMConstShl
LLVMConstShuffleVector
LLVMConstString
LLVMConstStringInContext
LLVMConstStruct
LLVMConstStructInContext
LLVMConstSub
LLVMConstTrunc
LLVMConstTruncOrBitCast
LLVMConstUDiv
LLVMConstUIToFP
LLVMConstURem
LLVMConstVector
LLVMConstXor
LLVMConstZExt
LLVMConstZExtOrBitCast
LLVMContextCreate
LLVMContextDispose
LLVMCopyStringRepOfTargetData
LLVMCountBasicBlocks
LLVMCountIncoming
LLVMCountParamTypes
LLVMCountParams
LLVMCountStructElementTypes
LLVMCreateBuilder
LLVMCreateBuilderInContext
LLVMCreateExecutionEngine
LLVMCreateExecutionEngineForModule
LLVMCreateFunctionPassManager
LLVMCreateFunctionPassManagerForModule
LLVMCreateGenericValueOfFloat
LLVMCreateGenericValueOfInt
LLVMCreateGenericValueOfPointer
LLVMCreateInterpreter
LLVMCreateInterpreterForModule
LLVMCreateJITCompiler
LLVMCreateJITCompilerForModule
LLVMCreateMemoryBufferWithContentsOfFile
LLVMCreateMemoryBufferWithSTDIN
LLVMCreateModuleProviderForExistingModule
LLVMCreateObjectFile
LLVMCreatePassManager
LLVMCreateTargetData
LLVMCreateTypeHandle
LLVMDeleteBasicBlock
LLVMDeleteFunction
LLVMDeleteGlobal
LLVMDeleteTypeName
LLVMDisposeBuilder
LLVMDisposeExecutionEngine
LLVMDisposeGenericValue
LLVMDisposeMemoryBuffer
LLVMDisposeMessage
LLVMDisposeModule
LLVMDisposeModuleProvider
LLVMDisposeObjectFile
LLVMDisposePassManager
LLVMDisposeSectionIterator
LLVMDisposeTargetData
LLVMDisposeTypeHandle
LLVMDoubleType
LLVMDoubleTypeInContext
LLVMDumpModule
LLVMDumpValue
LLVMElementAtOffset
LLVMFP128Type
LLVMFP128TypeInContext
LLVMFinalizeFunctionPassManager
LLVMFindFunction
LLVMFloatType
LLVMFloatTypeInContext
LLVMFreeMachineCodeForFunction
LLVMFunctionType
LLVMGenericValueIntWidth
LLVMGenericValueToFloat
LLVMGenericValueToInt
LLVMGenericValueToPointer
LLVMGetAlignment
LLVMGetArrayLength
LLVMGetAttribute
LLVMGetBasicBlockParent
LLVMGetBasicBlocks
LLVMGetBitcodeModule
LLVMGetBitcodeModuleInContext
LLVMGetBitcodeModuleProvider
LLVMGetBitcodeModuleProviderInContext
LLVMGetConstOpcode
LLVMGetCurrentDebugLocation
LLVMGetDataLayout
LLVMGetElementType
LLVMGetEntryBasicBlock
LLVMGetExecutionEngineTargetData
LLVMGetFirstBasicBlock
LLVMGetFirstFunction
LLVMGetFirstGlobal
LLVMGetFirstInstruction
LLVMGetFirstParam
LLVMGetFirstUse
LLVMGetFunctionAttr
LLVMGetFunctionCallConv
LLVMGetGC
LLVMGetGlobalContext
LLVMGetGlobalParent
LLVMGetGlobalPassRegistry
LLVMGetIncomingBlock
LLVMGetIncomingValue
LLVMGetInitializer
LLVMGetInsertBlock
LLVMGetInstructionCallConv
LLVMGetInstructionParent
LLVMGetIntTypeWidth
LLVMGetIntrinsicID
LLVMGetLastBasicBlock
LLVMGetLastFunction
LLVMGetLastGlobal
LLVMGetLastInstruction
LLVMGetLastParam
LLVMGetLinkage
LLVMGetMDKindID
LLVMGetMDKindIDInContext
LLVMGetMetadata
LLVMGetModuleContext
LLVMGetNamedFunction
LLVMGetNamedGlobal
LLVMGetNextBasicBlock
LLVMGetNextFunction
LLVMGetNextGlobal
LLVMGetNextInstruction
LLVMGetNextParam
LLVMGetNextUse
LLVMGetNumOperands
LLVMGetOperand
LLVMGetParam
LLVMGetParamParent
LLVMGetParamTypes
LLVMGetParams
LLVMGetPointerAddressSpace
LLVMGetPointerToGlobal
LLVMGetPreviousBasicBlock
LLVMGetPreviousFunction
LLVMGetPreviousGlobal
LLVMGetPreviousInstruction
LLVMGetPreviousParam
LLVMGetReturnType
LLVMGetSection
LLVMGetSectionContents
LLVMGetSectionName
LLVMGetSectionSize
LLVMGetSections
LLVMGetStructElementTypes
LLVMGetTarget
LLVMGetTypeByName
LLVMGetTypeContext
LLVMGetTypeKind
LLVMGetTypeName
LLVMGetUndef
LLVMGetUsedValue
LLVMGetUser
LLVMGetValueName
LLVMGetVectorSize
LLVMGetVisibility
LLVMHasMetadata
LLVMInitializeAnalysis
LLVMInitializeCodeGen
LLVMInitializeCore
LLVMInitializeFunctionPassManager
LLVMInitializeIPA
LLVMInitializeIPO
LLVMInitializeInstCombine
LLVMInitializeInstrumentation
LLVMInitializeScalarOpts
LLVMInitializeTarget
LLVMInitializeTransformUtils
LLVMInsertBasicBlock
LLVMInsertBasicBlockInContext
LLVMInsertIntoBuilder
LLVMInsertIntoBuilderWithName
LLVMInt16Type
LLVMInt16TypeInContext
LLVMInt1Type
LLVMInt1TypeInContext
LLVMInt32Type
LLVMInt32TypeInContext
LLVMInt64Type
LLVMInt64TypeInContext
LLVMInt8Type
LLVMInt8TypeInContext
LLVMIntPtrType
LLVMIntType
LLVMIntTypeInContext
LLVMInvalidateStructLayout
LLVMIsConstant
LLVMIsDeclaration
LLVMIsFunctionVarArg
LLVMIsGlobalConstant
LLVMIsNull
LLVMIsPackedStruct
LLVMIsSectionIteratorAtEnd
LLVMIsTailCall
LLVMIsThreadLocal
LLVMIsUndef
LLVMLabelType
LLVMLabelTypeInContext
LLVMLinkInInterpreter
LLVMLinkInJIT
LLVMMDNode
LLVMMDNodeInContext
LLVMMDString
LLVMMDStringInContext
LLVMModuleCreateWithName
LLVMModuleCreateWithNameInContext
LLVMMoveBasicBlockAfter
LLVMMoveBasicBlockBefore
LLVMMoveToNextSection
LLVMOffsetOfElement
LLVMOpaqueType
LLVMOpaqueTypeInContext
LLVMPPCFP128Type
LLVMPPCFP128TypeInContext
LLVMParseBitcode
LLVMParseBitcodeInContext
LLVMPointerSize
LLVMPointerType
LLVMPositionBuilder
LLVMPositionBuilderAtEnd
LLVMPositionBuilderBefore
LLVMPreferredAlignmentOfGlobal
LLVMPreferredAlignmentOfType
LLVMRecompileAndRelinkFunction
LLVMRefineType
LLVMRemoveAttribute
LLVMRemoveFunctionAttr
LLVMRemoveInstrAttribute
LLVMRemoveModule
LLVMRemoveModuleProvider
LLVMReplaceAllUsesWith
LLVMResolveTypeHandle
LLVMRunFunction
LLVMRunFunctionAsMain
LLVMRunFunctionPassManager
LLVMRunPassManager
LLVMRunStaticConstructors
LLVMRunStaticDestructors
LLVMSetAlignment
LLVMSetCurrentDebugLocation
LLVMSetDataLayout
LLVMSetFunctionCallConv
LLVMSetGC
LLVMSetGlobalConstant
LLVMSetInitializer
LLVMSetInstDebugLocation
LLVMSetInstrParamAlignment
LLVMSetInstructionCallConv
LLVMSetLinkage
LLVMSetMetadata
LLVMSetModuleInlineAsm
LLVMSetOperand
LLVMSetParamAlignment
LLVMSetSection
LLVMSetTailCall
LLVMSetTarget
LLVMSetThreadLocal
LLVMSetValueName
LLVMSetVisibility
LLVMSizeOf
LLVMSizeOfTypeInBits
LLVMStoreSizeOfType
LLVMStructType
LLVMStructTypeInContext
LLVMTypeOf
LLVMValueAsBasicBlock
LLVMValueIsBasicBlock
LLVMVectorType
LLVMVerifyFunction
LLVMVerifyModule
LLVMViewFunctionCFG
LLVMViewFunctionCFGOnly
LLVMVoidType
LLVMVoidTypeInContext
LLVMWriteBitcodeToFD
LLVMWriteBitcodeToFile
LLVMWriteBitcodeToFileHandle
LLVMX86FP80Type
LLVMX86FP80TypeInContext
LLVMX86MMXType
LLVMX86MMXTypeInContext

View file

@ -207,6 +207,29 @@ str_from_vec(rust_task *task, rust_vec *v)
return st;
}
extern "C" CDECL rust_str *
str_from_cstr(rust_task *task, char *sbuf)
{
size_t len = strlen(sbuf) + 1;
rust_str *st = vec_alloc_with_data(task, len, len, 1, sbuf);
if (!st) {
task->fail(2);
return NULL;
}
return st;
}
extern "C" CDECL rust_str *
str_from_buf(rust_task *task, char *buf, unsigned int len) {
rust_str *st = vec_alloc_with_data(task, len + 1, len, 1, buf);
if (!st) {
task->fail(2);
return NULL;
}
st->data[st->fill++] = '\0';
return st;
}
extern "C" CDECL void *
rand_new(rust_task *task)
{

View file

@ -40,7 +40,7 @@ fn sub(str t, int n) -> str {
b += ns;
}
else {
b += t.(i);
_str.push_byte(b, t.(i));
}
i += 1u;
}

View file

@ -39,7 +39,7 @@ fn sub(str t, int n) -> str {
b += ns;
}
else {
b += t.(i);
_str.push_byte(b, t.(i));
}
i += 1u;
}

View file

@ -28,7 +28,7 @@ fn make_cumulative(vec[aminoacids] aa) -> vec[aminoacids] {
let vec[aminoacids] ans = vec();
for (aminoacids a in aa) {
cp += a._1;
ans += tup(a._0, cp);
ans += vec(tup(a._0, cp));
}
ret ans;
}
@ -59,7 +59,7 @@ fn make_random_fasta(str id, str desc, vec[aminoacids] genelist, int n) {
auto rng = myrandom(std.rand.mk_rng().next());
let str op = "";
for each (uint i in _uint.range(0u, n as uint)) {
op += select_random(rng.next(100u32), genelist) as u8;
_str.push_byte(op, select_random(rng.next(100u32), genelist) as u8);
if (_str.byte_len(op) >= LINE_LENGTH()) {
log(op);
op = "";
@ -76,7 +76,7 @@ fn make_repeat_fasta(str id, str desc, str s, int n) {
let uint sl = _str.byte_len(s);
for each (uint i in _uint.range(0u, n as uint)) {
op += s.(i % sl);
_str.push_byte(op, s.(i % sl));
if (_str.byte_len(op) >= LINE_LENGTH()) {
log(op);
op = "";

View file

@ -1,15 +0,0 @@
fn main() {
auto v = vec(1,2,3);
v += 4;
v += 5;
check (v.(3) == 4);
check (v.(4) == 5);
auto s = "hello";
log s;
s += 'z' as u8;
s += 'y' as u8;
log s;
check (s.(5) == 'z' as u8);
check (s.(6) == 'y' as u8);
}

View file

@ -0,0 +1,14 @@
// -*- rust -*-
use std;
import std._str;
fn main() {
auto s = "hello";
auto sb = _str.rustrt.str_buf(s);
auto s_cstr = _str.rustrt.str_from_cstr(sb);
check (_str.eq(s_cstr, s));
auto s_buf = _str.rustrt.str_from_buf(sb, 5u);
check (_str.eq(s_buf, s));
}

View file

@ -0,0 +1,17 @@
// -*- rust -*-
fn len(vec[mutable? int] v) -> uint {
auto i = 0u;
for (int x in v) {
i += 1u;
}
ret i;
}
fn main() {
auto v0 = vec(1, 2, 3, 4, 5);
log len(v0);
auto v1 = vec(mutable 1, 2, 3, 4, 5);
log len(v1);
}