Merge branch 'master' into recursive-elseif
Conflicts: src/comp/middle/typeck.rs
This commit is contained in:
commit
bbb6836da0
44 changed files with 1856 additions and 961 deletions
90
src/Makefile
90
src/Makefile
|
|
@ -34,6 +34,7 @@ DSYMUTIL := true
|
|||
|
||||
ifeq ($(CFG_OSTYPE), FreeBSD)
|
||||
CFG_RUNTIME := librustrt.so
|
||||
CFG_SUPPORT := librustllvm.so
|
||||
CFG_STDLIB := libstd.so
|
||||
CFG_GCC_CFLAGS += -fPIC -march=i686 -I/usr/local/include
|
||||
CFG_GCC_LINK_FLAGS += -shared -fPIC -lpthread -lrt
|
||||
|
|
@ -47,6 +48,7 @@ endif
|
|||
|
||||
ifeq ($(CFG_OSTYPE), Linux)
|
||||
CFG_RUNTIME := librustrt.so
|
||||
CFG_SUPPORT := librustllvm.so
|
||||
CFG_STDLIB := libstd.so
|
||||
CFG_GCC_CFLAGS += -fPIC -march=i686
|
||||
CFG_GCC_LINK_FLAGS += -shared -fPIC -ldl -lpthread -lrt
|
||||
|
|
@ -60,6 +62,7 @@ endif
|
|||
|
||||
ifeq ($(CFG_OSTYPE), Darwin)
|
||||
CFG_RUNTIME := librustrt.dylib
|
||||
CFG_SUPPORT := librustllvm.dylib
|
||||
CFG_STDLIB := libstd.dylib
|
||||
CFG_UNIXY := 1
|
||||
CFG_GCC_LINK_FLAGS += -dynamiclib -lpthread
|
||||
|
|
@ -85,8 +88,8 @@ ifdef CFG_WINDOWSY
|
|||
CFG_NATIVE := 1
|
||||
endif
|
||||
CFG_RUNTIME := rustrt.dll
|
||||
CFG_SUPPORT := rustllvm.dll
|
||||
CFG_STDLIB := std.dll
|
||||
CFG_OBJ_SUFFIX := .o
|
||||
CFG_EXE_SUFFIX := .exe
|
||||
CFG_BOOT := ./rustboot.exe
|
||||
CFG_RUSTC := ./rustc.exe
|
||||
|
|
@ -101,7 +104,6 @@ ifdef CFG_UNIXY
|
|||
CFG_INFO := $(info cfg: unix-y environment)
|
||||
CFG_BOOT := ./rustboot
|
||||
CFG_RUSTC := ./rustc
|
||||
CFG_OBJ_SUFFIX := .o
|
||||
CFG_RUN_TARG = LD_LIBRARY_PATH=. $(CFG_VALGRIND) $(1)
|
||||
CFG_GCC := 1
|
||||
ifdef MINGW_CROSS
|
||||
|
|
@ -109,12 +111,12 @@ ifdef CFG_UNIXY
|
|||
CFG_GCC_CROSS := i586-mingw32msvc-
|
||||
CFG_BOOT_FLAGS += -t win32-x86-pe
|
||||
CFG_RUNTIME := rustrt.dll
|
||||
CFG_SUPPORT := rustllvm.dll
|
||||
CFG_STDLIB := std.dll
|
||||
CFG_RUSTC := ./rustc.exe
|
||||
ifdef CFG_VALGRIND
|
||||
CFG_VALGRIND += wine
|
||||
endif
|
||||
CFG_OBJ_SUFFIX := .o
|
||||
CFG_EXE_SUFFIX := .exe
|
||||
CFG_GCC_CFLAGS := -march=i686
|
||||
CFG_GCC_LINK_FLAGS := -shared
|
||||
|
|
@ -182,7 +184,7 @@ endif
|
|||
ifneq ($(CFG_LLVM_CONFIG),)
|
||||
CFG_LLVM_VERSION := $(shell $(CFG_LLVM_CONFIG) --version)
|
||||
$(info cfg: found llvm-config at $(CFG_LLVM_CONFIG))
|
||||
CFG_LLVM_ALLOWED_VERSIONS := 2.8svn 2.8 2.9svn
|
||||
CFG_LLVM_ALLOWED_VERSIONS := 2.8svn 2.8 2.9svn 3.0svn
|
||||
ifneq ($(findstring $(CFG_LLVM_VERSION),$(CFG_LLVM_ALLOWED_VERSIONS)),)
|
||||
$(info cfg: using LLVM version $(CFG_LLVM_VERSION))
|
||||
else
|
||||
|
|
@ -196,6 +198,10 @@ ifdef CFG_LLVM_CONFIG
|
|||
LLC := "$(shell $(CFG_LLVM_CONFIG) --bindir)/llc"
|
||||
CFG_LLC_CFLAGS := -march=x86
|
||||
LLVM-DIS := "$(shell $(CFG_LLVM_CONFIG) --bindir)/llvm-dis"
|
||||
CFG_LLVM_INCDIR := $(shell $(CFG_LLVM_CONFIG) --includedir)
|
||||
CFG_LLVM_CXXFLAGS := $(shell $(CFG_LLVM_CONFIG) --cxxflags)
|
||||
CFG_LLVM_LDFLAGS := $(shell $(CFG_LLVM_CONFIG) --ldflags)
|
||||
CFG_LLVM_LIBS := $(shell $(CFG_LLVM_CONFIG) --libs)
|
||||
endif
|
||||
|
||||
MKFILES := Makefile
|
||||
|
|
@ -302,15 +308,22 @@ RUNTIME_HDR := rt/globals.h \
|
|||
rt/test/rust_test_util.h
|
||||
|
||||
RUNTIME_INCS := -Irt/isaac -Irt/uthash
|
||||
RUNTIME_OBJS := $(RUNTIME_CS:.cpp=$(CFG_OBJ_SUFFIX))
|
||||
RUNTIME_LIBS := $(CFG_RUNTIME_LIBS)
|
||||
RUNTIME_OBJS := $(RUNTIME_CS:.cpp=.o)
|
||||
|
||||
SUPPORT_CS := llvmext/Object.cpp
|
||||
|
||||
SUPPORT_HDR := llvmext/include/llvm-c/Object.h
|
||||
|
||||
SUPPORT_INCS := -iquote $(CFG_LLVM_INCDIR) -iquote llvmext/include
|
||||
SUPPORT_OBJS := $(SUPPORT_CS:.cpp=.o)
|
||||
SUPPORT_LIBS := $(CFG_LLVM_LDFLAGS) $(CFG_LLVM_LIBS)
|
||||
|
||||
STDLIB_CRATE := lib/std.rc
|
||||
STDLIB_INPUTS := $(wildcard lib/*.rc lib/*.rs lib/*/*.rs)
|
||||
COMPILER_CRATE := comp/rustc.rc
|
||||
COMPILER_INPUTS := $(wildcard comp/*.rc comp/*.rs comp/*/*.rs)
|
||||
COMPILER_INPUTS := $(wildcard comp/rustc.rc comp/*.rs comp/*/*.rs)
|
||||
|
||||
GENERATED := boot/fe/lexer.ml boot/util/version.ml
|
||||
GENERATED := boot/fe/lexer.ml boot/util/version.ml glue.o
|
||||
|
||||
all: $(CFG_RUSTC) $(MKFILES) $(GENERATED)
|
||||
|
||||
|
|
@ -325,14 +338,24 @@ $(CFG_RUNTIME): $(RUNTIME_OBJS) $(MKFILES) $(RUNTIME_HDR)
|
|||
@$(call CFG_ECHO, compile: $<)
|
||||
$(CFG_QUIET)$(call CFG_LINK_C, $@) $(RUNTIME_OBJS)
|
||||
|
||||
$(CFG_SUPPORT): $(SUPPORT_OBJS) $(MKFILES) $(SUPPORT_HDR)
|
||||
@$(call CFG_ECHO, compile: $<)
|
||||
$(CFG_QUIET)$(call CFG_LINK_C, $@ $(CFG_LLVM_LDFLAGS) $(CFG_LLVM_LIBS)) \
|
||||
$(SUPPORT_OBJS)
|
||||
|
||||
$(CFG_STDLIB): $(STDLIB_CRATE) $(CFG_BOOT) $(MKFILES)
|
||||
@$(call CFG_ECHO, compile: $<)
|
||||
$(BOOT) -shared -o $@ $(STDLIB_CRATE)
|
||||
|
||||
%$(CFG_OBJ_SUFFIX): %.cpp $(MKFILES)
|
||||
rt/%.o: rt/%.cpp $(MKFILES)
|
||||
@$(call CFG_ECHO, compile: $<)
|
||||
$(CFG_QUIET)$(call CFG_COMPILE_C, $@, $(RUNTIME_INCS)) $<
|
||||
|
||||
llvmext/%.o: llvmext/%.cpp $(MKFILES)
|
||||
@$(call CFG_ECHO, compile: $<)
|
||||
$(CFG_QUIET)$(call CFG_COMPILE_C, $@, $(CFG_LLVM_CXXFLAGS) \
|
||||
$(SUPPORT_INCS)) $<
|
||||
|
||||
ifdef CFG_NATIVE
|
||||
$(CFG_BOOT): $(BOOT_CMXS) $(MKFILES)
|
||||
@$(call CFG_ECHO, compile: $<)
|
||||
|
|
@ -363,13 +386,18 @@ endif
|
|||
# Main compiler targets and rules
|
||||
######################################################################
|
||||
|
||||
$(CFG_RUSTC): $(COMPILER_INPUTS) $(CFG_BOOT) $(CFG_RUNTIME) $(CFG_STDLIB)
|
||||
$(CFG_RUSTC): $(COMPILER_INPUTS) $(CFG_BOOT) $(CFG_RUNTIME) $(CFG_STDLIB) \
|
||||
$(CFG_SUPPORT)
|
||||
@$(call CFG_ECHO, compile: $<)
|
||||
$(BOOT) -minimal -o $@ $<
|
||||
$(CFG_QUIET)chmod 0755 $@
|
||||
|
||||
glue.bc: $(CFG_RUSTC) $(CFG_RUNTIME) $(CFG_STDLIB)
|
||||
@$(call CFG_ECHO, generate: $@)
|
||||
$(RUSTC) -o $@ -glue
|
||||
|
||||
self: $(CFG_RUSTC)
|
||||
@$(call CFG_ECHO, compile: $<)
|
||||
@$(call CFG_ECHO, compile: $(COMPILER_CRATE))
|
||||
$(RUSTC) $(COMPILER_CRATE)
|
||||
|
||||
|
||||
|
|
@ -402,6 +430,7 @@ TEST_XFAILS_BOOT := $(TASK_XFAILS) \
|
|||
$(NOMINAL_TAG_XFAILS) \
|
||||
$(CONST_TAG_XFAILS) \
|
||||
test/run-pass/arith-unsigned.rs \
|
||||
test/run-pass/box-compare.rs \
|
||||
test/run-pass/child-outlives-parent.rs \
|
||||
test/run-pass/clone-with-exterior.rs \
|
||||
test/run-pass/constrained-type.rs \
|
||||
|
|
@ -409,12 +438,15 @@ TEST_XFAILS_BOOT := $(TASK_XFAILS) \
|
|||
test/run-pass/obj-as.rs \
|
||||
test/run-pass/vec-slice.rs \
|
||||
test/run-pass/fn-lval.rs \
|
||||
test/run-pass/generic-bind-2.rs \
|
||||
test/run-pass/generic-fn-box.rs \
|
||||
test/run-pass/generic-tup.rs \
|
||||
test/run-pass/iter-ret.rs \
|
||||
test/run-pass/leak-tag-copy.rs \
|
||||
test/run-pass/lib-io.rs \
|
||||
test/run-pass/mlist-cycle.rs \
|
||||
test/run-pass/obj-as.rs \
|
||||
test/run-pass/seq-compare.rs \
|
||||
test/run-pass/task-comm.rs \
|
||||
test/run-pass/task-comm-3.rs \
|
||||
test/run-pass/vec-slice.rs \
|
||||
|
|
@ -439,24 +471,11 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \
|
|||
basic-1.rs \
|
||||
basic-2.rs \
|
||||
basic.rs \
|
||||
bind-obj-ctor.rs \
|
||||
child-outlives-parent.rs \
|
||||
clone-with-exterior.rs \
|
||||
comm.rs \
|
||||
constrained-type.rs \
|
||||
destructor-ordering.rs \
|
||||
drop-parametric-closure-with-bound-box.rs \
|
||||
export-non-interference.rs \
|
||||
foreach-nested-2.rs \
|
||||
foreach-nested.rs \
|
||||
foreach-put-structured.rs \
|
||||
foreach-simple-outer-slot.rs \
|
||||
generic-fn-twice.rs \
|
||||
generic-iter-frame.rs \
|
||||
generic-recursive-tag.rs \
|
||||
generic-tag-alt.rs \
|
||||
generic-tag-values.rs \
|
||||
iter-range.rs \
|
||||
iter-ret.rs \
|
||||
lazychan.rs \
|
||||
lib-bitv.rs \
|
||||
|
|
@ -478,7 +497,6 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \
|
|||
mutable-alias-vec.rs \
|
||||
obj-as.rs \
|
||||
obj-dtor.rs \
|
||||
obj-return-polytypes.rs \
|
||||
pred.rs \
|
||||
preempt.rs \
|
||||
rt-circular-buffer.rs \
|
||||
|
|
@ -511,13 +529,11 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \
|
|||
threads.rs \
|
||||
type-sizes.rs \
|
||||
typestate-cfg-nesting.rs \
|
||||
use-import-export.rs \
|
||||
user.rs \
|
||||
utf8.rs \
|
||||
vec-alloc-append.rs \
|
||||
vec-append.rs \
|
||||
vec-slice.rs \
|
||||
while-prelude-drop.rs \
|
||||
while-with-break.rs \
|
||||
yield.rs \
|
||||
yield2.rs \
|
||||
|
|
@ -764,9 +780,9 @@ test/bench/shootout/%.boot$(CFG_EXE_SUFFIX): \
|
|||
@$(call CFG_ECHO, assemble [llvm]: $<)
|
||||
$(CFG_QUIET)gcc $(CFG_GCC_CFLAGS) -o $@ -c $<
|
||||
|
||||
%.rustc$(CFG_EXE_SUFFIX): %.o $(CFG_RUNTIME)
|
||||
%.rustc$(CFG_EXE_SUFFIX): %.o $(CFG_RUNTIME) glue.o
|
||||
@$(call CFG_ECHO, link [llvm]: $<)
|
||||
$(CFG_QUIET)gcc $(CFG_GCC_CFLAGS) -o $@ $< -L. -lrustrt
|
||||
$(CFG_QUIET)gcc $(CFG_GCC_CFLAGS) glue.o -o $@ $< -L. -lrustrt
|
||||
@# dsymutil sometimes fails or prints a warning, but the
|
||||
@# program still runs. Since it simplifies debugging other
|
||||
@# programs, I\'ll live with the noise.
|
||||
|
|
@ -803,7 +819,7 @@ C_DEPFILES := $(RUNTIME_CS:%.cpp=%.d)
|
|||
%.d: %.cpp $(MKFILES)
|
||||
@$(call CFG_ECHO, dep: $<)
|
||||
$(CFG_QUIET)$(call CFG_DEPEND_C, $@ \
|
||||
$(patsubst %.cpp, %$(CFG_OBJ_SUFFIX), $<), \
|
||||
$(patsubst %.cpp, %.o, $<), \
|
||||
$(RUNTIME_INCS)) $< $(CFG_PATH_MUNGE) >$@.tmp \
|
||||
&& mv $@.tmp $@
|
||||
|
||||
|
|
@ -826,9 +842,15 @@ RUSTBOOT_PROBE := $(wildcard $(CFG_BOOT))
|
|||
ifneq ($(RUSTBOOT_PROBE),)
|
||||
CFG_INFO := $(info cfg: using built $(CFG_BOOT) for rust deps)
|
||||
STDLIB_DEPFILE := $(CFG_STDLIB).d
|
||||
RUSTC_DEPFILE := $(CFG_RUSTC).d
|
||||
CRATE_DEPFILES := $(ALL_TEST_CRATES:%.rc=%.d) $(STDLIB_DEPFILE)
|
||||
|
||||
$(STDLIB_DEPFILE): $(STDLIB_CRATE) $(MKFILES) $(CFG_BOOT)
|
||||
$(STDLIB_DEPFILE): $(STDLIB_CRATE) $(MKFILES) $(CFG_BOOT) $(STDLIB_INPUTS)
|
||||
@$(call CFG_ECHO, dep: $<)
|
||||
$(BOOT) -shared -rdeps $< $(CFG_PATH_MUNGE) >$@.tmp \
|
||||
&& mv $@.tmp $@
|
||||
|
||||
$(RUSTC_DEPFILE): $(STDLIB_CRATE) $(MKFILES) $(CFG_BOOT) $(COMPILER_INPUTS)
|
||||
@$(call CFG_ECHO, dep: $<)
|
||||
$(BOOT) -shared -rdeps $< $(CFG_PATH_MUNGE) >$@.tmp \
|
||||
&& mv $@.tmp $@
|
||||
|
|
@ -920,12 +942,12 @@ clean:
|
|||
$(CFG_QUIET)rm -f $(ML_DEPFILES:%.d=%.d.tmp)
|
||||
$(CFG_QUIET)rm -f $(C_DEPFILES:%.d=%.d.tmp)
|
||||
$(CFG_QUIET)rm -f $(CRATE_DEPFILES:%.d=%.d.tmp)
|
||||
$(CFG_QUIET)rm -f $(GENERATED)
|
||||
$(CFG_QUIET)rm -f $(GENERATED) glue.bc glue.s
|
||||
$(CFG_QUIET)rm -f $(CFG_BOOT) $(CFG_RUNTIME) $(CFG_STDLIB)
|
||||
$(CFG_QUIET)rm -Rf $(PKG_NAME)-*.tar.gz dist
|
||||
$(CFG_QUIET)rm -f $(foreach ext,cmx cmi cmo cma o a d exe,\
|
||||
$(CFG_QUIET)rm -f $(foreach ext,cmx cmi cmo cma bc o a d exe,\
|
||||
$(wildcard boot/*/*.$(ext) boot/*/*/*.$(ext)))
|
||||
$(CFG_QUIET)rm -Rf $(foreach ext,out llvm x86 boot rustc o s exe dSYM,\
|
||||
$(CFG_QUIET)rm -Rf $(foreach ext,out llvm x86 boot rustc bc o s exe dSYM,\
|
||||
$(wildcard test/*/*.$(ext)))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ let general_code_alignment = 16;;
|
|||
let tydesc_field_first_param = 0;;
|
||||
let tydesc_field_size = 1;;
|
||||
let tydesc_field_align = 2;;
|
||||
let tydesc_field_copy_glue = 3;;
|
||||
let tydesc_field_take_glue = 3;;
|
||||
let tydesc_field_drop_glue = 4;;
|
||||
let tydesc_field_free_glue = 5;;
|
||||
let tydesc_field_sever_glue = 6;;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,6 @@
|
|||
|
||||
open Common;;
|
||||
|
||||
let _ =
|
||||
Gc.set { (Gc.get()) with
|
||||
Gc.space_overhead = 400; }
|
||||
;;
|
||||
|
||||
let (targ:Common.target) =
|
||||
match Sys.os_type with
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ type glue =
|
|||
| GLUE_yield
|
||||
| GLUE_exit_main_task
|
||||
| GLUE_exit_task
|
||||
| GLUE_copy of Ast.ty (* One-level copy. *)
|
||||
| GLUE_take of Ast.ty (* One-level refcounts++. *)
|
||||
| GLUE_drop of Ast.ty (* De-initialize local memory. *)
|
||||
| GLUE_free of Ast.ty (* Drop body + free() box ptr. *)
|
||||
| GLUE_sever of Ast.ty (* Null all box state slots. *)
|
||||
|
|
@ -2776,7 +2776,7 @@ let glue_str (cx:ctxt) (g:glue) : string =
|
|||
| GLUE_yield -> "glue$yield"
|
||||
| GLUE_exit_main_task -> "glue$exit_main_task"
|
||||
| GLUE_exit_task -> "glue$exit_task"
|
||||
| GLUE_copy ty -> "glue$copy$" ^ (ty_str cx ty)
|
||||
| GLUE_take ty -> "glue$take$" ^ (ty_str cx ty)
|
||||
| GLUE_drop ty -> "glue$drop$" ^ (ty_str cx ty)
|
||||
| GLUE_free ty -> "glue$free$" ^ (ty_str cx ty)
|
||||
| GLUE_sever ty -> "glue$sever$" ^ (ty_str cx ty)
|
||||
|
|
|
|||
|
|
@ -1355,7 +1355,7 @@ let trans_visitor
|
|||
Asm.WORD (word_ty_mach, Asm.IMM 0L);
|
||||
Asm.WORD (word_ty_mach, Asm.IMM sz);
|
||||
Asm.WORD (word_ty_mach, Asm.IMM align);
|
||||
fix (get_copy_glue t);
|
||||
fix (get_take_glue t);
|
||||
fix (get_drop_glue t);
|
||||
begin
|
||||
match ty_mem_ctrl cx t with
|
||||
|
|
@ -2022,34 +2022,18 @@ let trans_visitor
|
|||
get_typed_mem_glue g fty inner
|
||||
|
||||
|
||||
and get_copy_glue
|
||||
and get_take_glue
|
||||
(ty:Ast.ty)
|
||||
: fixup =
|
||||
let ty = get_genericized_ty ty in
|
||||
let arg_ty_params_alias = 0 in
|
||||
let arg_src_alias = 1 in
|
||||
let arg_initflag = 2 in
|
||||
|
||||
let g = GLUE_copy ty in
|
||||
let inner (out_ptr:Il.cell) (args:Il.cell) =
|
||||
let dst = deref out_ptr in
|
||||
let g = GLUE_take ty in
|
||||
let inner (_:Il.cell) (args:Il.cell) =
|
||||
let ty_params = deref (get_element_ptr args arg_ty_params_alias) in
|
||||
let src = deref (get_element_ptr args arg_src_alias) in
|
||||
|
||||
(* Translate copy code for the dst-initializing and
|
||||
* dst-non-initializing cases and branch accordingly. *)
|
||||
let initflag = get_element_ptr args arg_initflag in
|
||||
let jmps = trans_compare_simple Il.JNE (Il.Cell initflag) one in
|
||||
|
||||
trans_copy_ty_full true ty_params true dst ty src ty;
|
||||
|
||||
let skip_noninit_jmp = mark() in
|
||||
emit (Il.jmp Il.JMP Il.CodeNone);
|
||||
List.iter patch jmps;
|
||||
|
||||
trans_copy_ty_full true ty_params false dst ty src ty;
|
||||
|
||||
patch skip_noninit_jmp;
|
||||
trans_take_ty true ty_params src ty;
|
||||
in
|
||||
let ty_params_ptr = ty_params_covering ty in
|
||||
let fty =
|
||||
|
|
@ -2186,17 +2170,23 @@ let trans_visitor
|
|||
get_tydesc_params ty_params_cell elt_td_ptr_cell
|
||||
in
|
||||
|
||||
let initflag = Il.Reg (force_to_reg one) in
|
||||
|
||||
(* Take all *)
|
||||
copy_loop dst_buf src_buf (Il.Cell fill) (Il.Cell elt_sz)
|
||||
begin
|
||||
fun dptr sptr ->
|
||||
fun _ sptr ->
|
||||
trans_call_dynamic_glue
|
||||
elt_td_ptr_cell
|
||||
Abi.tydesc_field_copy_glue
|
||||
(Some (deref dptr))
|
||||
[| ty_params_ptr; sptr; initflag |]
|
||||
Abi.tydesc_field_take_glue
|
||||
None
|
||||
[| ty_params_ptr; sptr |]
|
||||
None;
|
||||
end;
|
||||
|
||||
(* Memcpy all *)
|
||||
copy_loop dst_buf src_buf (Il.Cell fill) one
|
||||
begin
|
||||
fun dptr sptr ->
|
||||
mov (deref dptr) (Il.Cell (deref sptr))
|
||||
end;
|
||||
|
||||
(* Set the new vec's fill to the original vec's fill *)
|
||||
|
|
@ -3734,17 +3724,58 @@ let trans_visitor
|
|||
end
|
||||
tys
|
||||
|
||||
and trans_copy_ty
|
||||
(ty_params:Il.cell)
|
||||
(initializing:bool)
|
||||
(dst:Il.cell) (dst_ty:Ast.ty)
|
||||
(src:Il.cell) (src_ty:Ast.ty)
|
||||
: unit =
|
||||
trans_copy_ty_full
|
||||
false ty_params initializing dst dst_ty src src_ty
|
||||
|
||||
and trans_copy_ty_full
|
||||
and trans_take_ty
|
||||
(force_inline:bool)
|
||||
(ty_params:Il.cell)
|
||||
(v:Il.cell)
|
||||
(ty:Ast.ty)
|
||||
: unit =
|
||||
let ty = strip_mutable_or_constrained_ty ty in
|
||||
match ty_mem_ctrl cx ty with
|
||||
MEM_rc_opaque | MEM_gc | MEM_rc_struct -> incr_refcount v
|
||||
| _ ->
|
||||
begin
|
||||
match ty with
|
||||
Ast.TY_fn _
|
||||
| Ast.TY_obj _ ->
|
||||
let binding =
|
||||
get_element_ptr v Abi.binding_field_bound_data
|
||||
in
|
||||
let null_jmp = null_check binding in
|
||||
incr_refcount binding;
|
||||
patch null_jmp
|
||||
|
||||
| Ast.TY_param (i, _) ->
|
||||
aliasing false v
|
||||
begin
|
||||
fun v ->
|
||||
let td = get_ty_param ty_params i in
|
||||
let ty_params_ptr = get_tydesc_params ty_params td in
|
||||
trans_call_dynamic_glue
|
||||
td Abi.tydesc_field_take_glue
|
||||
None
|
||||
[| ty_params_ptr; v; |]
|
||||
None
|
||||
end
|
||||
|
||||
| Ast.TY_rec _
|
||||
| Ast.TY_tag _
|
||||
| Ast.TY_tup _ ->
|
||||
if force_inline
|
||||
then
|
||||
iter_ty_parts ty_params v ty
|
||||
(trans_take_ty force_inline ty_params)
|
||||
else
|
||||
trans_call_static_glue
|
||||
(code_fixup_to_ptr_operand (get_take_glue ty))
|
||||
None
|
||||
[| alias ty_params; alias v; |]
|
||||
None
|
||||
|
||||
| _ -> ()
|
||||
end
|
||||
|
||||
and trans_copy_ty
|
||||
(ty_params:Il.cell)
|
||||
(initializing:bool)
|
||||
(dst:Il.cell) (dst_ty:Ast.ty)
|
||||
|
|
@ -3789,7 +3820,7 @@ let trans_visitor
|
|||
| _ ->
|
||||
(* Heavyweight copy: duplicate 1 level of the referent. *)
|
||||
anno "heavy";
|
||||
trans_copy_ty_heavy force_inline ty_params initializing
|
||||
trans_copy_ty_heavy ty_params initializing
|
||||
dst dst_ty src src_ty
|
||||
end
|
||||
|
||||
|
|
@ -3821,7 +3852,6 @@ let trans_visitor
|
|||
*)
|
||||
|
||||
and trans_copy_ty_heavy
|
||||
(force_inline:bool)
|
||||
(ty_params:Il.cell)
|
||||
(initializing:bool)
|
||||
(dst:Il.cell) (dst_ty:Ast.ty)
|
||||
|
|
@ -3863,68 +3893,14 @@ let trans_visitor
|
|||
(ty_sz cx ty)));
|
||||
mov dst (Il.Cell src)
|
||||
|
||||
| Ast.TY_param (i, _) ->
|
||||
iflog
|
||||
(fun _ -> annotate
|
||||
(Printf.sprintf "copy_ty: parametric copy %#d" i));
|
||||
let initflag = Il.Reg (force_to_reg one) in
|
||||
aliasing false src
|
||||
begin
|
||||
fun src ->
|
||||
let td = get_ty_param ty_params i in
|
||||
let ty_params_ptr = get_tydesc_params ty_params td in
|
||||
trans_call_dynamic_glue
|
||||
td Abi.tydesc_field_copy_glue
|
||||
(Some dst)
|
||||
[| ty_params_ptr; src; initflag |]
|
||||
None
|
||||
end
|
||||
|
||||
| Ast.TY_fn _
|
||||
| Ast.TY_obj _ ->
|
||||
begin
|
||||
let src_item =
|
||||
get_element_ptr src Abi.binding_field_dispatch
|
||||
in
|
||||
let dst_item =
|
||||
get_element_ptr dst Abi.binding_field_dispatch
|
||||
in
|
||||
let src_binding =
|
||||
get_element_ptr src Abi.binding_field_bound_data
|
||||
in
|
||||
let dst_binding =
|
||||
get_element_ptr dst Abi.binding_field_bound_data
|
||||
in
|
||||
mov dst_item (Il.Cell src_item);
|
||||
mov dst_binding zero;
|
||||
let null_jmp = null_check src_binding in
|
||||
(* Copy if we have a src binding. *)
|
||||
(* FIXME (issue #58): this is completely wrong, call
|
||||
* through to the binding's self-copy fptr. For now
|
||||
* this only works by accident.
|
||||
*)
|
||||
trans_copy_ty ty_params true
|
||||
dst_binding (Ast.TY_box Ast.TY_int)
|
||||
src_binding (Ast.TY_box Ast.TY_int);
|
||||
patch null_jmp
|
||||
end
|
||||
|
||||
| _ ->
|
||||
if force_inline || should_inline_structure_helpers ty
|
||||
then
|
||||
iter_ty_parts_full ty_params dst src ty
|
||||
(fun dst src ty ->
|
||||
trans_copy_ty ty_params true
|
||||
dst ty src ty)
|
||||
else
|
||||
let initflag = Il.Reg (force_to_reg one) in
|
||||
trans_call_static_glue
|
||||
(code_fixup_to_ptr_operand (get_copy_glue ty))
|
||||
(Some dst)
|
||||
[| alias ty_params;
|
||||
alias src;
|
||||
initflag |]
|
||||
None
|
||||
trans_take_ty false ty_params src ty;
|
||||
if not initializing
|
||||
then drop_ty ty_params dst ty;
|
||||
let sz = ty_sz_with_ty_params ty_params ty in
|
||||
copy_loop dst src sz (imm 1L)
|
||||
(fun dptr sptr ->
|
||||
mov (deref dptr) (Il.Cell (deref sptr)))
|
||||
|
||||
|
||||
and trans_copy
|
||||
|
|
|
|||
|
|
@ -25,22 +25,39 @@ fn restore_callee_saves() -> vec[str] {
|
|||
"popl %ebp");
|
||||
}
|
||||
|
||||
fn load_esp_from_rust_sp() -> vec[str] {
|
||||
fn load_esp_from_rust_sp_first_arg() -> vec[str] {
|
||||
ret vec("movl " + wstr(abi.task_field_rust_sp) + "(%ecx), %esp");
|
||||
}
|
||||
|
||||
fn load_esp_from_runtime_sp() -> vec[str] {
|
||||
fn load_esp_from_runtime_sp_first_arg() -> vec[str] {
|
||||
ret vec("movl " + wstr(abi.task_field_runtime_sp) + "(%ecx), %esp");
|
||||
}
|
||||
|
||||
fn store_esp_to_rust_sp() -> vec[str] {
|
||||
fn store_esp_to_rust_sp_first_arg() -> vec[str] {
|
||||
ret vec("movl %esp, " + wstr(abi.task_field_rust_sp) + "(%ecx)");
|
||||
}
|
||||
|
||||
fn store_esp_to_runtime_sp() -> vec[str] {
|
||||
fn store_esp_to_runtime_sp_first_arg() -> vec[str] {
|
||||
ret vec("movl %esp, " + wstr(abi.task_field_runtime_sp) + "(%ecx)");
|
||||
}
|
||||
|
||||
fn load_esp_from_rust_sp_second_arg() -> vec[str] {
|
||||
ret vec("movl " + wstr(abi.task_field_rust_sp) + "(%edx), %esp");
|
||||
}
|
||||
|
||||
fn load_esp_from_runtime_sp_second_arg() -> vec[str] {
|
||||
ret vec("movl " + wstr(abi.task_field_runtime_sp) + "(%edx), %esp");
|
||||
}
|
||||
|
||||
fn store_esp_to_rust_sp_second_arg() -> vec[str] {
|
||||
ret vec("movl %esp, " + wstr(abi.task_field_rust_sp) + "(%edx)");
|
||||
}
|
||||
|
||||
fn store_esp_to_runtime_sp_second_arg() -> vec[str] {
|
||||
ret vec("movl %esp, " + wstr(abi.task_field_runtime_sp) + "(%edx)");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is a bit of glue-code. It should be emitted once per
|
||||
* compilation unit.
|
||||
|
|
@ -61,8 +78,8 @@ fn store_esp_to_runtime_sp() -> vec[str] {
|
|||
fn rust_activate_glue() -> vec[str] {
|
||||
ret vec("movl 4(%esp), %ecx # ecx = rust_task")
|
||||
+ save_callee_saves()
|
||||
+ store_esp_to_runtime_sp()
|
||||
+ load_esp_from_rust_sp()
|
||||
+ store_esp_to_runtime_sp_first_arg()
|
||||
+ load_esp_from_rust_sp_first_arg()
|
||||
|
||||
/*
|
||||
* There are two paths we can arrive at this code from:
|
||||
|
|
@ -154,10 +171,10 @@ fn rust_activate_glue() -> vec[str] {
|
|||
|
||||
fn rust_yield_glue() -> vec[str] {
|
||||
ret vec("movl 0(%esp), %ecx # ecx = rust_task")
|
||||
+ load_esp_from_rust_sp()
|
||||
+ load_esp_from_rust_sp_first_arg()
|
||||
+ save_callee_saves()
|
||||
+ store_esp_to_rust_sp()
|
||||
+ load_esp_from_runtime_sp()
|
||||
+ store_esp_to_rust_sp_first_arg()
|
||||
+ load_esp_from_runtime_sp_first_arg()
|
||||
+ restore_callee_saves()
|
||||
+ vec("ret");
|
||||
}
|
||||
|
|
@ -175,8 +192,11 @@ fn upcall_glue(int n_args) -> vec[str] {
|
|||
*/
|
||||
|
||||
fn copy_arg(uint i) -> str {
|
||||
auto src_off = wstr(5 + (i as int));
|
||||
auto dst_off = wstr(1 + (i as int));
|
||||
if (i == 0u) {
|
||||
ret "movl %edx, (%esp)";
|
||||
}
|
||||
auto src_off = wstr(4 + (i as int));
|
||||
auto dst_off = wstr(0 + (i as int));
|
||||
auto m = vec("movl " + src_off + "(%ebp),%eax",
|
||||
"movl %eax," + dst_off + "(%esp)");
|
||||
ret _str.connect(m, "\n\t");
|
||||
|
|
@ -189,20 +209,19 @@ fn upcall_glue(int n_args) -> vec[str] {
|
|||
|
||||
+ vec("movl %esp, %ebp # ebp = rust_sp")
|
||||
|
||||
+ store_esp_to_rust_sp()
|
||||
+ load_esp_from_runtime_sp()
|
||||
+ store_esp_to_rust_sp_second_arg()
|
||||
+ load_esp_from_runtime_sp_second_arg()
|
||||
|
||||
+ vec("subl $" + wstr(n_args + 1) + ", %esp # esp -= args",
|
||||
"andl $~0xf, %esp # align esp down",
|
||||
"movl %ecx, (%esp) # arg[0] = rust_task ")
|
||||
"andl $~0xf, %esp # align esp down")
|
||||
|
||||
+ _vec.init_fn[str](carg, n_args as uint)
|
||||
+ _vec.init_fn[str](carg, (n_args + 1) as uint)
|
||||
|
||||
+ vec("movl %ecx, %edi # save task from ecx to edi",
|
||||
"call *%edx # call *%edx",
|
||||
"movl %edi, %ecx # restore edi-saved task to ecx")
|
||||
+ vec("movl %edx, %edi # save task from edx to edi",
|
||||
"call *%ecx # call *%ecx",
|
||||
"movl %edi, %edx # restore edi-saved task to edx")
|
||||
|
||||
+ load_esp_from_rust_sp()
|
||||
+ load_esp_from_rust_sp_second_arg()
|
||||
+ restore_callee_saves()
|
||||
+ vec("ret");
|
||||
|
||||
|
|
@ -254,6 +273,16 @@ fn get_module_asm() -> str {
|
|||
ret _str.connect(glues, "\n\n");
|
||||
}
|
||||
|
||||
fn get_meta_sect_name() -> str {
|
||||
if (_str.eq(target_os(), "macos")) {
|
||||
ret "__DATA,__note.rustc";
|
||||
}
|
||||
if (_str.eq(target_os(), "win32")) {
|
||||
ret ".note.rustc";
|
||||
}
|
||||
ret ".note.rustc";
|
||||
}
|
||||
|
||||
fn get_data_layout() -> str {
|
||||
if (_str.eq(target_os(), "macos")) {
|
||||
ret "e-p:32:32-f64:32:64-i64:32:64-f80:128:128-n8:16:32";
|
||||
|
|
|
|||
|
|
@ -54,7 +54,8 @@ impure fn compile_input(session.session sess,
|
|||
eval.env env,
|
||||
str input, str output,
|
||||
bool shared) {
|
||||
auto p = parser.new_parser(sess, env, 0, input);
|
||||
auto def = tup(0, 0);
|
||||
auto p = parser.new_parser(sess, env, def, input);
|
||||
auto crate = parse_input(sess, p, input);
|
||||
crate = resolve.resolve_crate(sess, crate);
|
||||
crate = typeck.check_crate(sess, crate);
|
||||
|
|
@ -64,9 +65,10 @@ impure fn compile_input(session.session sess,
|
|||
impure fn pretty_print_input(session.session sess,
|
||||
eval.env env,
|
||||
str input) {
|
||||
auto p = front.parser.new_parser(sess, env, 0, input);
|
||||
auto def = tup(0, 0);
|
||||
auto p = front.parser.new_parser(sess, env, def, input);
|
||||
auto crate = front.parser.parse_crate_from_source_file(p);
|
||||
pretty.pprust.print_ast(crate.node.module);
|
||||
pretty.pprust.print_ast(crate.node.module, std.io.stdout_writer());
|
||||
}
|
||||
|
||||
fn warn_wrong_compiler() {
|
||||
|
|
@ -82,6 +84,7 @@ fn usage(session.session sess, str argv0) {
|
|||
log "";
|
||||
log " -o <filename> write output to <filename>";
|
||||
log " -nowarn suppress wrong-compiler warning";
|
||||
log " -glue generate glue.bc file";
|
||||
log " -shared compile a shared-library crate";
|
||||
log " -pp pretty-print the input instead of compiling";
|
||||
log " -h display this message";
|
||||
|
|
@ -111,6 +114,7 @@ impure fn main(vec[str] args) {
|
|||
let bool do_warn = true;
|
||||
let bool shared = false;
|
||||
let bool pretty = false;
|
||||
let bool glue = false;
|
||||
|
||||
auto i = 1u;
|
||||
auto len = _vec.len[str](args);
|
||||
|
|
@ -121,6 +125,8 @@ impure fn main(vec[str] args) {
|
|||
if (_str.byte_len(arg) > 0u && arg.(0) == '-' as u8) {
|
||||
if (_str.eq(arg, "-nowarn")) {
|
||||
do_warn = false;
|
||||
} else if (_str.eq(arg, "-glue")) {
|
||||
glue = true;
|
||||
} else if (_str.eq(arg, "-shared")) {
|
||||
shared = true;
|
||||
} else if (_str.eq(arg, "-pp")) {
|
||||
|
|
@ -157,6 +163,18 @@ impure fn main(vec[str] args) {
|
|||
warn_wrong_compiler();
|
||||
}
|
||||
|
||||
if (glue) {
|
||||
alt (output_file) {
|
||||
case (none[str]) {
|
||||
middle.trans.make_common_glue("glue.bc");
|
||||
}
|
||||
case (some[str](?s)) {
|
||||
middle.trans.make_common_glue(s);
|
||||
}
|
||||
}
|
||||
ret;
|
||||
}
|
||||
|
||||
alt (input_file) {
|
||||
case (none[str]) {
|
||||
usage(sess, args.(0));
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ type ty_param = rec(ident ident, def_id id);
|
|||
// Annotations added during successive passes.
|
||||
tag ann {
|
||||
ann_none;
|
||||
ann_type(@middle.ty.t);
|
||||
ann_type(@middle.ty.t, option.t[vec[@middle.ty.t]] /* ty param substs */);
|
||||
}
|
||||
|
||||
tag def {
|
||||
|
|
@ -29,9 +29,11 @@ tag def {
|
|||
def_obj(def_id);
|
||||
def_obj_field(def_id);
|
||||
def_mod(def_id);
|
||||
def_native_mod(def_id);
|
||||
def_const(def_id);
|
||||
def_arg(def_id);
|
||||
def_local(def_id);
|
||||
def_upvar(def_id);
|
||||
def_variant(def_id /* tag */, def_id /* variant */);
|
||||
def_ty(def_id);
|
||||
def_ty_arg(def_id);
|
||||
|
|
@ -42,7 +44,8 @@ tag def {
|
|||
}
|
||||
|
||||
type crate = spanned[crate_];
|
||||
type crate_ = rec(_mod module);
|
||||
type crate_ = rec(vec[@crate_directive] directives,
|
||||
_mod module);
|
||||
|
||||
tag crate_directive_ {
|
||||
cdir_expr(@expr);
|
||||
|
|
@ -64,9 +67,15 @@ type meta_item = spanned[meta_item_];
|
|||
type meta_item_ = rec(ident name, str value);
|
||||
|
||||
type block = spanned[block_];
|
||||
type block_index = hashmap[ident, block_index_entry];
|
||||
tag block_index_entry {
|
||||
bie_item(@item);
|
||||
bie_local(@local);
|
||||
bie_tag_variant(@item /* tag item */, uint /* variant index */);
|
||||
}
|
||||
type block_ = rec(vec[@stmt] stmts,
|
||||
option.t[@expr] expr,
|
||||
hashmap[ident,uint] index);
|
||||
hashmap[ident,block_index_entry] index);
|
||||
|
||||
type variant_def = tup(def_id /* tag */, def_id /* variant */);
|
||||
|
||||
|
|
@ -427,6 +436,44 @@ fn index_native_view_item(native_mod_index index, @view_item it) {
|
|||
}
|
||||
}
|
||||
|
||||
fn index_stmt(block_index index, @stmt s) {
|
||||
alt (s.node) {
|
||||
case (ast.stmt_decl(?d)) {
|
||||
alt (d.node) {
|
||||
case (ast.decl_local(?loc)) {
|
||||
index.insert(loc.ident, ast.bie_local(loc));
|
||||
}
|
||||
case (ast.decl_item(?it)) {
|
||||
alt (it.node) {
|
||||
case (ast.item_fn(?i, _, _, _, _)) {
|
||||
index.insert(i, ast.bie_item(it));
|
||||
}
|
||||
case (ast.item_mod(?i, _, _)) {
|
||||
index.insert(i, ast.bie_item(it));
|
||||
}
|
||||
case (ast.item_ty(?i, _, _, _, _)) {
|
||||
index.insert(i, ast.bie_item(it));
|
||||
}
|
||||
case (ast.item_tag(?i, ?variants, _, _)) {
|
||||
index.insert(i, ast.bie_item(it));
|
||||
let uint vid = 0u;
|
||||
for (ast.variant v in variants) {
|
||||
auto t = ast.bie_tag_variant(it, vid);
|
||||
index.insert(v.name, t);
|
||||
vid += 1u;
|
||||
}
|
||||
}
|
||||
case (ast.item_obj(?i, _, _, _, _)) {
|
||||
index.insert(i, ast.bie_item(it));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case (_) { /* fall through */ }
|
||||
}
|
||||
}
|
||||
|
||||
fn is_call_expr(@expr e) -> bool {
|
||||
alt (e.node) {
|
||||
case (expr_call(_, _, _)) {
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ fn val_is_bool(val v) -> bool {
|
|||
|
||||
fn val_is_int(val v) -> bool {
|
||||
alt (v) {
|
||||
case (val_bool(_)) { ret true; }
|
||||
case (val_int(_)) { ret true; }
|
||||
case (_) { }
|
||||
}
|
||||
ret false;
|
||||
|
|
@ -386,9 +386,12 @@ impure fn eval_crate_directive(parser p,
|
|||
|
||||
auto full_path = prefix + std.os.path_sep() + file_path;
|
||||
|
||||
auto p0 = new_parser(p.get_session(), e, 0, full_path);
|
||||
auto start_id = p.next_def_id();
|
||||
auto p0 = new_parser(p.get_session(), e, start_id, full_path);
|
||||
auto m0 = parse_mod_items(p0, token.EOF);
|
||||
auto im = ast.item_mod(id, m0, p.next_def_id());
|
||||
auto next_id = p0.next_def_id();
|
||||
p.set_def(next_id._1);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -35,12 +35,13 @@ state type parser =
|
|||
fn get_session() -> session.session;
|
||||
fn get_span() -> common.span;
|
||||
fn next_def_id() -> ast.def_id;
|
||||
fn set_def(ast.def_num);
|
||||
fn get_prec_table() -> vec[op_spec];
|
||||
};
|
||||
|
||||
impure fn new_parser(session.session sess,
|
||||
eval.env env,
|
||||
ast.crate_num crate,
|
||||
ast.def_id initial_def,
|
||||
str path) -> parser {
|
||||
state obj stdio_parser(session.session sess,
|
||||
eval.env env,
|
||||
|
|
@ -94,6 +95,10 @@ impure fn new_parser(session.session sess,
|
|||
ret tup(crate, def);
|
||||
}
|
||||
|
||||
fn set_def(ast.def_num d) {
|
||||
def = d;
|
||||
}
|
||||
|
||||
fn get_file_type() -> file_type {
|
||||
ret ftype;
|
||||
}
|
||||
|
|
@ -114,8 +119,8 @@ impure fn new_parser(session.session sess,
|
|||
auto rdr = lexer.new_reader(srdr, path);
|
||||
auto npos = rdr.get_curr_pos();
|
||||
ret stdio_parser(sess, env, ftype, lexer.next_token(rdr),
|
||||
npos, npos, 0, UNRESTRICTED, crate, rdr,
|
||||
prec_table());
|
||||
npos, npos, initial_def._1, UNRESTRICTED, initial_def._0,
|
||||
rdr, prec_table());
|
||||
}
|
||||
|
||||
impure fn unexpected(parser p, token.token t) {
|
||||
|
|
@ -1465,39 +1470,9 @@ impure fn parse_source_stmt(parser p) -> @ast.stmt {
|
|||
}
|
||||
|
||||
fn index_block(vec[@ast.stmt] stmts, option.t[@ast.expr] expr) -> ast.block_ {
|
||||
auto index = new_str_hash[uint]();
|
||||
auto u = 0u;
|
||||
auto index = new_str_hash[ast.block_index_entry]();
|
||||
for (@ast.stmt s in stmts) {
|
||||
alt (s.node) {
|
||||
case (ast.stmt_decl(?d)) {
|
||||
alt (d.node) {
|
||||
case (ast.decl_local(?loc)) {
|
||||
index.insert(loc.ident, u);
|
||||
}
|
||||
case (ast.decl_item(?it)) {
|
||||
alt (it.node) {
|
||||
case (ast.item_fn(?i, _, _, _, _)) {
|
||||
index.insert(i, u);
|
||||
}
|
||||
case (ast.item_mod(?i, _, _)) {
|
||||
index.insert(i, u);
|
||||
}
|
||||
case (ast.item_ty(?i, _, _, _, _)) {
|
||||
index.insert(i, u);
|
||||
}
|
||||
case (ast.item_tag(?i, _, _, _)) {
|
||||
index.insert(i, u);
|
||||
}
|
||||
case (ast.item_obj(?i, _, _, _, _)) {
|
||||
index.insert(i, u);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case (_) { /* fall through */ }
|
||||
}
|
||||
u += 1u;
|
||||
ast.index_stmt(index, s);
|
||||
}
|
||||
ret rec(stmts=stmts, expr=expr, index=index);
|
||||
}
|
||||
|
|
@ -2261,7 +2236,9 @@ impure fn parse_crate_from_source_file(parser p) -> @ast.crate {
|
|||
auto lo = p.get_span();
|
||||
auto hi = lo;
|
||||
auto m = parse_mod_items(p, token.EOF);
|
||||
ret @spanned(lo, hi, rec(module=m));
|
||||
let vec[@ast.crate_directive] cdirs = vec();
|
||||
ret @spanned(lo, hi, rec(directives=cdirs,
|
||||
module=m));
|
||||
}
|
||||
|
||||
// Logic for parsing crate files (.rc)
|
||||
|
|
@ -2276,8 +2253,6 @@ impure fn parse_crate_directive(parser p) -> ast.crate_directive
|
|||
auto hi = lo;
|
||||
alt (p.peek()) {
|
||||
case (token.AUTH) {
|
||||
// FIXME: currently dropping auth clauses on the floor,
|
||||
// as there is no effect-checking pass.
|
||||
p.bump();
|
||||
auto n = parse_path(p, GREEDY);
|
||||
expect(p, token.EQ);
|
||||
|
|
@ -2288,8 +2263,6 @@ impure fn parse_crate_directive(parser p) -> ast.crate_directive
|
|||
}
|
||||
|
||||
case (token.META) {
|
||||
// FIXME: currently dropping meta clauses on the floor,
|
||||
// as there is no crate metadata system
|
||||
p.bump();
|
||||
auto mis = parse_meta(p);
|
||||
hi = p.get_span();
|
||||
|
|
@ -2398,7 +2371,8 @@ impure fn parse_crate_from_crate_file(parser p) -> @ast.crate {
|
|||
cdirs, prefix);
|
||||
hi = p.get_span();
|
||||
expect(p, token.EOF);
|
||||
ret @spanned(lo, hi, rec(module=m));
|
||||
ret @spanned(lo, hi, rec(directives=cdirs,
|
||||
module=m));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,87 +0,0 @@
|
|||
import std._int;
|
||||
import std._str;
|
||||
import std._uint;
|
||||
import std._vec;
|
||||
|
||||
export print_expr;
|
||||
|
||||
// FIXME this is superseded by ../pretty/pprust.rs. can it be dropped?
|
||||
|
||||
fn unknown() -> str {
|
||||
ret "<unknown ast node>";
|
||||
}
|
||||
|
||||
fn print_expr(@ast.expr expr) -> str {
|
||||
alt (expr.node) {
|
||||
case (ast.expr_lit(?lit, _)) {
|
||||
ret print_lit(lit);
|
||||
}
|
||||
case (ast.expr_binary(?op, ?lhs, ?rhs, _)) {
|
||||
ret print_expr_binary(op, lhs, rhs);
|
||||
}
|
||||
case (ast.expr_call(?path, ?args, _)) {
|
||||
ret print_expr_call(path, args);
|
||||
}
|
||||
case (ast.expr_path(?path, _, _)) {
|
||||
ret print_path(path);
|
||||
}
|
||||
case (_) {
|
||||
ret unknown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn print_lit(@ast.lit lit) -> str {
|
||||
alt (lit.node) {
|
||||
case (ast.lit_str(?s)) {
|
||||
ret "\"" + s + "\"";
|
||||
}
|
||||
case (ast.lit_int(?i)) {
|
||||
ret _int.to_str(i, 10u);
|
||||
}
|
||||
case (ast.lit_uint(?u)) {
|
||||
ret _uint.to_str(u, 10u);
|
||||
}
|
||||
case (_) {
|
||||
ret unknown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn print_expr_binary(ast.binop op, @ast.expr lhs, @ast.expr rhs) -> str {
|
||||
alt (op) {
|
||||
case (ast.add) {
|
||||
auto l = print_expr(lhs);
|
||||
auto r = print_expr(rhs);
|
||||
ret l + " + " + r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn print_expr_call(@ast.expr path_expr, vec[@ast.expr] args) -> str {
|
||||
auto s = print_expr(path_expr);
|
||||
|
||||
s += "(";
|
||||
fn print_expr_ref(&@ast.expr e) -> str { ret print_expr(e); }
|
||||
auto mapfn = print_expr_ref;
|
||||
auto argstrs = _vec.map[@ast.expr, str](mapfn, args);
|
||||
s += _str.connect(argstrs, ", ");
|
||||
s += ")";
|
||||
|
||||
ret s;
|
||||
}
|
||||
|
||||
fn print_path(ast.path path) -> str {
|
||||
ret _str.connect(path.node.idents, ".");
|
||||
}
|
||||
|
||||
//
|
||||
// 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:
|
||||
//
|
||||
|
|
@ -253,6 +253,8 @@ type ast_fold[ENV] =
|
|||
(fn(&ENV e, &span sp, ident i, vec[ident] idents,
|
||||
def_id id, option.t[def]) -> @view_item) fold_view_item_import,
|
||||
|
||||
(fn(&ENV e, &span sp, ident i) -> @view_item) fold_view_item_export,
|
||||
|
||||
// Additional nodes.
|
||||
(fn(&ENV e, &span sp,
|
||||
&ast.block_) -> block) fold_block,
|
||||
|
|
@ -270,6 +272,7 @@ type ast_fold[ENV] =
|
|||
(fn(&ENV e, &ast.native_mod m) -> ast.native_mod) fold_native_mod,
|
||||
|
||||
(fn(&ENV e, &span sp,
|
||||
vec[@ast.crate_directive] cdirs,
|
||||
&ast._mod m) -> @ast.crate) fold_crate,
|
||||
|
||||
(fn(&ENV e,
|
||||
|
|
@ -451,11 +454,14 @@ fn fold_pat[ENV](&ENV env, ast_fold[ENV] fld, @ast.pat p) -> @ast.pat {
|
|||
ret fld.fold_pat_bind(env_, p.span, id, did, t);
|
||||
}
|
||||
case (ast.pat_tag(?path, ?pats, ?d, ?t)) {
|
||||
auto ppath = fold_path(env, fld, path);
|
||||
|
||||
let vec[@ast.pat] ppats = vec();
|
||||
for (@ast.pat pat in pats) {
|
||||
ppats += vec(fold_pat(env_, fld, pat));
|
||||
}
|
||||
ret fld.fold_pat_tag(env_, p.span, path, ppats, d, t);
|
||||
|
||||
ret fld.fold_pat_tag(env_, p.span, ppath, ppats, d, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -718,6 +724,7 @@ fn fold_stmt[ENV](&ENV env, ast_fold[ENV] fld, &@stmt s) -> @stmt {
|
|||
|
||||
fn fold_block[ENV](&ENV env, ast_fold[ENV] fld, &block blk) -> block {
|
||||
|
||||
auto index = new_str_hash[ast.block_index_entry]();
|
||||
let ENV env_ = fld.update_env_for_block(env, blk);
|
||||
|
||||
if (!fld.keep_going(env_)) {
|
||||
|
|
@ -726,7 +733,9 @@ 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) {
|
||||
append[@ast.stmt](stmts, fold_stmt[ENV](env_, fld, s));
|
||||
auto new_stmt = fold_stmt[ENV](env_, fld, s);
|
||||
append[@ast.stmt](stmts, new_stmt);
|
||||
ast.index_stmt(index, new_stmt);
|
||||
}
|
||||
|
||||
auto expr = none[@ast.expr];
|
||||
|
|
@ -739,8 +748,7 @@ fn fold_block[ENV](&ENV env, ast_fold[ENV] fld, &block blk) -> block {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME: should we reindex?
|
||||
ret respan(blk.span, rec(stmts=stmts, expr=expr, index=blk.node.index));
|
||||
ret respan(blk.span, rec(stmts=stmts, expr=expr, index=index));
|
||||
}
|
||||
|
||||
fn fold_arm[ENV](&ENV env, ast_fold[ENV] fld, &arm a) -> arm {
|
||||
|
|
@ -838,6 +846,10 @@ fn fold_view_item[ENV](&ENV env, ast_fold[ENV] fld, @view_item vi)
|
|||
ret fld.fold_view_item_import(env_, vi.span, def_ident, idents,
|
||||
def_id, target_def);
|
||||
}
|
||||
|
||||
case (ast.view_item_export(?def_ident)) {
|
||||
ret fld.fold_view_item_export(env_, vi.span, def_ident);
|
||||
}
|
||||
}
|
||||
|
||||
fail;
|
||||
|
|
@ -969,9 +981,12 @@ fn fold_native_mod[ENV](&ENV e, ast_fold[ENV] fld,
|
|||
}
|
||||
|
||||
fn fold_crate[ENV](&ENV env, ast_fold[ENV] fld, @ast.crate c) -> @ast.crate {
|
||||
// FIXME: possibly fold the directives so you process any expressions
|
||||
// within them? Not clear. After front/eval.rs, nothing else should look
|
||||
// at crate directives.
|
||||
let ENV env_ = fld.update_env_for_crate(env, c);
|
||||
let ast._mod m = fold_mod[ENV](env_, fld, c.node.module);
|
||||
ret fld.fold_crate(env_, c.span, m);
|
||||
ret fld.fold_crate(env_, c.span, c.node.directives, m);
|
||||
}
|
||||
|
||||
//// Identity folds.
|
||||
|
|
@ -1324,6 +1339,11 @@ fn identity_fold_view_item_import[ENV](&ENV e, &span sp, ident i,
|
|||
ret @respan(sp, ast.view_item_import(i, is, id, target_def));
|
||||
}
|
||||
|
||||
fn identity_fold_view_item_export[ENV](&ENV e, &span sp, ident i)
|
||||
-> @view_item {
|
||||
ret @respan(sp, ast.view_item_export(i));
|
||||
}
|
||||
|
||||
// Additional identities.
|
||||
|
||||
fn identity_fold_block[ENV](&ENV e, &span sp, &ast.block_ blk) -> block {
|
||||
|
|
@ -1353,8 +1373,10 @@ fn identity_fold_native_mod[ENV](&ENV e,
|
|||
ret m;
|
||||
}
|
||||
|
||||
fn identity_fold_crate[ENV](&ENV e, &span sp, &ast._mod m) -> @ast.crate {
|
||||
ret @respan(sp, rec(module=m));
|
||||
fn identity_fold_crate[ENV](&ENV e, &span sp,
|
||||
vec[@ast.crate_directive] cdirs,
|
||||
&ast._mod m) -> @ast.crate {
|
||||
ret @respan(sp, rec(directives=cdirs, module=m));
|
||||
}
|
||||
|
||||
fn identity_fold_obj[ENV](&ENV e,
|
||||
|
|
@ -1501,13 +1523,15 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
|
|||
bind identity_fold_view_item_use[ENV](_,_,_,_,_),
|
||||
fold_view_item_import =
|
||||
bind identity_fold_view_item_import[ENV](_,_,_,_,_,_),
|
||||
fold_view_item_export =
|
||||
bind identity_fold_view_item_export[ENV](_,_,_),
|
||||
|
||||
fold_block = bind identity_fold_block[ENV](_,_,_),
|
||||
fold_fn = bind identity_fold_fn[ENV](_,_,_,_),
|
||||
fold_fn_decl = bind identity_fold_fn_decl[ENV](_,_,_,_),
|
||||
fold_mod = bind identity_fold_mod[ENV](_,_),
|
||||
fold_native_mod = bind identity_fold_native_mod[ENV](_,_),
|
||||
fold_crate = bind identity_fold_crate[ENV](_,_,_),
|
||||
fold_crate = bind identity_fold_crate[ENV](_,_,_,_),
|
||||
fold_obj = bind identity_fold_obj[ENV](_,_,_,_),
|
||||
|
||||
update_env_for_crate = bind identity_update_env_for_crate[ENV](_,_),
|
||||
|
|
|
|||
29
src/comp/middle/metadata.rs
Normal file
29
src/comp/middle/metadata.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import std._str;
|
||||
import front.ast;
|
||||
import middle.trans;
|
||||
import back.x86;
|
||||
|
||||
import lib.llvm.llvm;
|
||||
import lib.llvm.llvm.ValueRef;
|
||||
import lib.llvm.False;
|
||||
|
||||
// Returns a Plain Old LLVM String.
|
||||
fn C_postr(str s) -> ValueRef {
|
||||
ret llvm.LLVMConstString(_str.buf(s), _str.byte_len(s), False);
|
||||
}
|
||||
|
||||
fn collect_meta_directives(@trans.crate_ctxt cx, @ast.crate crate)
|
||||
-> ValueRef {
|
||||
ret C_postr("Hello world!"); // TODO
|
||||
}
|
||||
|
||||
fn write_metadata(@trans.crate_ctxt cx, @ast.crate crate) {
|
||||
auto llmeta = collect_meta_directives(cx, crate);
|
||||
|
||||
auto llconst = trans.C_struct(vec(llmeta));
|
||||
auto llglobal = llvm.LLVMAddGlobal(cx.llmod, trans.val_ty(llconst),
|
||||
_str.buf("rust_metadata"));
|
||||
llvm.LLVMSetInitializer(llglobal, llconst);
|
||||
llvm.LLVMSetSection(llglobal, _str.buf(x86.get_meta_sect_name()));
|
||||
}
|
||||
|
||||
|
|
@ -71,6 +71,13 @@ fn unwrap_def(def_wrap d) -> def {
|
|||
}
|
||||
}
|
||||
}
|
||||
case (def_wrap_native_mod(?m)) {
|
||||
alt (m.node) {
|
||||
case (ast.item_native_mod(_, _, ?id)) {
|
||||
ret ast.def_native_mod(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
case (def_wrap_other(?d)) {
|
||||
ret d;
|
||||
}
|
||||
|
|
@ -335,6 +342,40 @@ fn lookup_name_wrapped(&env e, ast.ident i) -> option.t[tup(@env, def_wrap)] {
|
|||
ret none[def_wrap];
|
||||
}
|
||||
|
||||
fn found_tag(@ast.item item, uint variant_idx) -> def_wrap {
|
||||
alt (item.node) {
|
||||
case (ast.item_tag(_, ?variants, _, ?tid)) {
|
||||
auto vid = variants.(variant_idx).id;
|
||||
auto t = ast.def_variant(tid, vid);
|
||||
ret def_wrap_other(t);
|
||||
}
|
||||
case (_) {
|
||||
log "tag item not actually a tag";
|
||||
fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_block(ast.ident i, &ast.block_ b) -> option.t[def_wrap] {
|
||||
alt (b.index.find(i)) {
|
||||
case (some[ast.block_index_entry](?ix)) {
|
||||
alt(ix) {
|
||||
case (ast.bie_item(?it)) {
|
||||
ret some(found_def_item(it));
|
||||
}
|
||||
case (ast.bie_local(?l)) {
|
||||
auto t = ast.def_local(l.id);
|
||||
ret some(def_wrap_other(t));
|
||||
}
|
||||
case (ast.bie_tag_variant(?item, ?variant_idx)) {
|
||||
ret some(found_tag(item, variant_idx));
|
||||
}
|
||||
}
|
||||
}
|
||||
case (_) { ret none[def_wrap]; }
|
||||
}
|
||||
}
|
||||
|
||||
fn in_scope(ast.ident i, &scope s) -> option.t[def_wrap] {
|
||||
alt (s) {
|
||||
|
||||
|
|
@ -361,7 +402,7 @@ fn lookup_name_wrapped(&env e, ast.ident i) -> option.t[tup(@env, def_wrap)] {
|
|||
}
|
||||
}
|
||||
}
|
||||
case (ast.item_tag(_, _, ?ty_params, _)) {
|
||||
case (ast.item_tag(_, ?variants, ?ty_params, ?tag_id)) {
|
||||
for (ast.ty_param tp in ty_params) {
|
||||
if (_str.eq(tp.ident, i)) {
|
||||
auto t = ast.def_ty_arg(tp.id);
|
||||
|
|
@ -407,13 +448,7 @@ fn lookup_name_wrapped(&env e, ast.ident i) -> option.t[tup(@env, def_wrap)] {
|
|||
}
|
||||
|
||||
case (scope_block(?b)) {
|
||||
alt (b.node.index.find(i)) {
|
||||
case (some[uint](?ix)) {
|
||||
auto x = found_decl_stmt(b.node.stmts.(ix));
|
||||
ret some(x);
|
||||
}
|
||||
case (_) { /* fall through */ }
|
||||
}
|
||||
ret check_block(i, b.node);
|
||||
}
|
||||
|
||||
case (scope_arm(?a)) {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -81,87 +81,10 @@ tag unify_result {
|
|||
|
||||
// Stringification
|
||||
|
||||
fn ast_ty_to_str(&@ast.ty ty) -> str {
|
||||
|
||||
fn ast_fn_input_to_str(&rec(ast.mode mode, @ast.ty ty) input) -> str {
|
||||
auto s;
|
||||
if (mode_is_alias(input.mode)) {
|
||||
s = "&";
|
||||
} else {
|
||||
s = "";
|
||||
}
|
||||
|
||||
ret s + ast_ty_to_str(input.ty);
|
||||
}
|
||||
|
||||
fn ast_ty_field_to_str(&ast.ty_field f) -> str {
|
||||
ret ast_ty_to_str(f.ty) + " " + f.ident;
|
||||
}
|
||||
|
||||
auto s;
|
||||
alt (ty.node) {
|
||||
case (ast.ty_nil) { s = "()"; }
|
||||
case (ast.ty_bool) { s = "bool"; }
|
||||
case (ast.ty_int) { s = "int"; }
|
||||
case (ast.ty_uint) { s = "uint"; }
|
||||
case (ast.ty_machine(?tm)) { s = common.ty_mach_to_str(tm); }
|
||||
case (ast.ty_char) { s = "char"; }
|
||||
case (ast.ty_str) { s = "str"; }
|
||||
case (ast.ty_box(?t)) { s = "@" + ast_ty_to_str(t); }
|
||||
case (ast.ty_vec(?t)) { s = "vec[" + ast_ty_to_str(t) + "]"; }
|
||||
case (ast.ty_type) { s = "type"; }
|
||||
|
||||
case (ast.ty_tup(?elts)) {
|
||||
auto f = ast_ty_to_str;
|
||||
s = "tup(";
|
||||
s += _str.connect(_vec.map[@ast.ty,str](f, elts), ",");
|
||||
s += ")";
|
||||
}
|
||||
|
||||
case (ast.ty_rec(?fields)) {
|
||||
auto f = ast_ty_field_to_str;
|
||||
s = "rec(";
|
||||
s += _str.connect(_vec.map[ast.ty_field,str](f, fields), ",");
|
||||
s += ")";
|
||||
}
|
||||
|
||||
case (ast.ty_fn(?proto, ?inputs, ?output)) {
|
||||
auto f = ast_fn_input_to_str;
|
||||
if (proto == ast.proto_fn) {
|
||||
s = "fn(";
|
||||
} else {
|
||||
s = "iter(";
|
||||
}
|
||||
auto is = _vec.map[rec(ast.mode mode, @ast.ty ty),str](f, inputs);
|
||||
s += _str.connect(is, ", ");
|
||||
s += ")";
|
||||
|
||||
if (output.node != ast.ty_nil) {
|
||||
s += " -> " + ast_ty_to_str(output);
|
||||
}
|
||||
}
|
||||
|
||||
case (ast.ty_path(?path, _)) {
|
||||
s = path_to_str(path);
|
||||
}
|
||||
|
||||
case (ast.ty_mutable(?t)) {
|
||||
s = "mutable " + ast_ty_to_str(t);
|
||||
}
|
||||
|
||||
|
||||
case (_) {
|
||||
fail; // FIXME: typestate bug
|
||||
}
|
||||
}
|
||||
|
||||
ret s;
|
||||
}
|
||||
|
||||
fn path_to_str(&ast.path pth) -> str {
|
||||
auto result = _str.connect(pth.node.idents, ".");
|
||||
if (_vec.len[@ast.ty](pth.node.types) > 0u) {
|
||||
auto f = ast_ty_to_str;
|
||||
auto f = pretty.pprust.ty_to_str;
|
||||
result += "[";
|
||||
result += _str.connect(_vec.map[@ast.ty,str](f, pth.node.types), ",");
|
||||
result += "]";
|
||||
|
|
@ -169,8 +92,6 @@ fn path_to_str(&ast.path pth) -> str {
|
|||
ret result;
|
||||
}
|
||||
|
||||
// FIXME use the pretty-printer for this once it has a concept of an
|
||||
// abstract stream
|
||||
fn ty_to_str(&@t typ) -> str {
|
||||
|
||||
fn fn_input_to_str(&rec(ast.mode mode, @t ty) input) -> str {
|
||||
|
|
@ -452,6 +373,14 @@ fn get_element_type(@t ty, uint i) -> @t {
|
|||
fail;
|
||||
}
|
||||
|
||||
fn type_is_box(@t ty) -> bool {
|
||||
alt (ty.struct) {
|
||||
case (ty_box(_)) { ret true; }
|
||||
case (_) { ret false; }
|
||||
}
|
||||
fail;
|
||||
}
|
||||
|
||||
fn type_is_boxed(@t ty) -> bool {
|
||||
alt (ty.struct) {
|
||||
case (ty_str) { ret true; }
|
||||
|
|
@ -596,10 +525,10 @@ fn eq_ty(&@t a, &@t b) -> bool {
|
|||
fn ann_to_type(&ast.ann ann) -> @t {
|
||||
alt (ann) {
|
||||
case (ast.ann_none) {
|
||||
// shouldn't happen, but can until the typechecker is complete
|
||||
ret plain_ty(ty_var(-1)); // FIXME: broken, broken, broken
|
||||
log "ann_to_type() called on node with no type";
|
||||
fail;
|
||||
}
|
||||
case (ast.ann_type(?ty)) {
|
||||
case (ast.ann_type(?ty, _)) {
|
||||
ret ty;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -17,17 +17,19 @@ type context = rec(contexttype tp, uint indent);
|
|||
|
||||
type ps = @rec(mutable vec[context] context,
|
||||
uint width,
|
||||
io.writer out,
|
||||
mutable vec[token] buffered,
|
||||
mutable uint scandepth,
|
||||
mutable uint bufferedcol,
|
||||
mutable uint col,
|
||||
mutable bool start_of_line);
|
||||
|
||||
fn mkstate(uint width) -> ps {
|
||||
fn mkstate(io.writer out, uint width) -> ps {
|
||||
let vec[context] stack = vec(rec(tp=cx_v, indent=0u));
|
||||
let vec[token] buff = vec();
|
||||
ret @rec(mutable context=stack,
|
||||
width=width,
|
||||
out=out,
|
||||
mutable buffered=buff,
|
||||
mutable scandepth=0u,
|
||||
mutable bufferedcol=0u,
|
||||
|
|
@ -46,10 +48,22 @@ impure fn pop_context(ps p) {
|
|||
}
|
||||
|
||||
impure fn add_token(ps p, token tok) {
|
||||
if (p.scandepth == 0u) {do_token(p, tok);}
|
||||
if (p.width == 0u) {direct_token(p, tok);}
|
||||
else if (p.scandepth == 0u) {do_token(p, tok);}
|
||||
else {buffer_token(p, tok);}
|
||||
}
|
||||
|
||||
impure fn direct_token(ps p, token tok) {
|
||||
alt (tok) {
|
||||
case (brk(?sz)) {
|
||||
while (sz > 0u) {p.out.write_str(" "); sz -= 1u;}
|
||||
}
|
||||
case (word(?w)) {p.out.write_str(w);}
|
||||
case (cword(?w)) {p.out.write_str(w);}
|
||||
case (_) {}
|
||||
}
|
||||
}
|
||||
|
||||
impure fn buffer_token(ps p, token tok) {
|
||||
p.buffered += vec(tok);
|
||||
p.bufferedcol += token_size(tok);
|
||||
|
|
@ -101,14 +115,13 @@ impure fn finish_block_scan(ps p, contexttype tp) {
|
|||
|
||||
impure fn finish_break_scan(ps p) {
|
||||
if (p.bufferedcol > p.width) {
|
||||
write_str("\n");
|
||||
p.col = 0u;
|
||||
line_break(p);
|
||||
}
|
||||
else {
|
||||
auto width;
|
||||
alt (p.buffered.(0)) {case(brk(?w)) {width = w;}}
|
||||
auto i = 0u;
|
||||
while (i < width) {write_str(" "); i+=1u;}
|
||||
while (i < width) {p.out.write_str(" "); i+=1u;}
|
||||
p.col += width;
|
||||
}
|
||||
p.scandepth = 0u;
|
||||
|
|
@ -142,20 +155,18 @@ impure fn do_token(ps p, token tok) {
|
|||
start_scan(p, tok);
|
||||
}
|
||||
case (cx_v) {
|
||||
write_str("\n");
|
||||
p.col = 0u;
|
||||
p.start_of_line = true;
|
||||
line_break(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
case (word(?w)) {
|
||||
before_print(p, false);
|
||||
write_str(w);
|
||||
p.out.write_str(w);
|
||||
p.col += _str.byte_len(w); // TODO char_len
|
||||
}
|
||||
case (cword(?w)) {
|
||||
before_print(p, true);
|
||||
write_str(w);
|
||||
p.out.write_str(w);
|
||||
p.col += _str.byte_len(w); // TODO char_len
|
||||
}
|
||||
case (open(?tp, ?indent)) {
|
||||
|
|
@ -170,6 +181,12 @@ impure fn do_token(ps p, token tok) {
|
|||
}
|
||||
}
|
||||
|
||||
impure fn line_break(ps p) {
|
||||
p.out.write_str("\n");
|
||||
p.col = 0u;
|
||||
p.start_of_line = true;
|
||||
}
|
||||
|
||||
impure fn before_print(ps p, bool closing) {
|
||||
if (p.start_of_line) {
|
||||
p.start_of_line = false;
|
||||
|
|
@ -177,14 +194,10 @@ impure fn before_print(ps p, bool closing) {
|
|||
if (closing) {ind = base_indent(p);}
|
||||
else {ind = cur_context(p).indent;}
|
||||
p.col = ind;
|
||||
while (ind > 0u) {write_str(" "); ind -= 1u;}
|
||||
while (ind > 0u) {p.out.write_str(" "); ind -= 1u;}
|
||||
}
|
||||
}
|
||||
|
||||
fn write_str(str s) {
|
||||
io.writefd(1, _str.bytes(s));
|
||||
}
|
||||
|
||||
fn token_size(token tok) -> uint {
|
||||
alt (tok) {
|
||||
case (brk(?sz)) {ret sz;}
|
||||
|
|
|
|||
|
|
@ -11,13 +11,19 @@ import foo = std.io;
|
|||
const uint indent_unit = 2u;
|
||||
const int as_prec = 5;
|
||||
|
||||
impure fn print_ast(ast._mod _mod) {
|
||||
auto s = pp.mkstate(80u);
|
||||
impure fn print_ast(ast._mod _mod, std.io.writer out) {
|
||||
auto s = pp.mkstate(out, 80u);
|
||||
for (@ast.view_item vitem in _mod.view_items) {print_view_item(s, vitem);}
|
||||
line(s);
|
||||
for (@ast.item item in _mod.items) {print_item(s, item);}
|
||||
}
|
||||
|
||||
fn ty_to_str(&@ast.ty ty) -> str {
|
||||
auto writer = std.io.string_writer();
|
||||
print_type(pp.mkstate(writer.get_writer(), 0u), ty);
|
||||
ret writer.get_str();
|
||||
}
|
||||
|
||||
impure fn hbox(ps s) {
|
||||
pp.hbox(s, indent_unit);
|
||||
}
|
||||
|
|
@ -85,24 +91,21 @@ impure fn print_type(ps s, @ast.ty ty) {
|
|||
commasep[ast.ty_field](s, fields, f);
|
||||
pclose(s);
|
||||
}
|
||||
case (ast.ty_fn(?proto,?inputs,?output)) {
|
||||
if (proto == ast.proto_fn) {wrd(s, "fn");}
|
||||
else {wrd(s, "iter");}
|
||||
popen(s);
|
||||
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);
|
||||
}
|
||||
auto f = print_arg;
|
||||
commasep[ast.ty_arg](s, inputs, f);
|
||||
pclose(s);
|
||||
if (output.node != ast.ty_nil) {
|
||||
space(s);
|
||||
case (ast.ty_obj(?methods)) {
|
||||
wrd1(s, "obj");
|
||||
bopen(s);
|
||||
for (ast.ty_method m in methods) {
|
||||
hbox(s);
|
||||
wrd1(s, "->");
|
||||
print_type(s, output);
|
||||
print_ty_fn(s, m.proto, option.some[str](m.ident),
|
||||
m.inputs, m.output);
|
||||
wrd(s, ";");
|
||||
end(s);
|
||||
line(s);
|
||||
}
|
||||
bclose(s);
|
||||
}
|
||||
case (ast.ty_fn(?proto,?inputs,?output)) {
|
||||
print_ty_fn(s, proto, option.none[str], inputs, output);
|
||||
}
|
||||
case (ast.ty_path(?path,_)) {
|
||||
print_path(s, path);
|
||||
|
|
@ -376,6 +379,7 @@ impure fn print_expr(ps s, @ast.expr expr) {
|
|||
wrd1(s, "else");
|
||||
print_expr(s, _else);
|
||||
}
|
||||
case (_) { /* fall through */ }
|
||||
}
|
||||
}
|
||||
case (ast.expr_while(?test,?block,_)) {
|
||||
|
|
@ -503,8 +507,16 @@ impure fn print_expr(ps s, @ast.expr expr) {
|
|||
wrd1(s, "check");
|
||||
print_expr(s, expr);
|
||||
}
|
||||
case (_) {wrd(s, "X");}
|
||||
// TODO expr_ext(path, vec[@expr], option.t[@expr], @expr, ann);
|
||||
case (ast.expr_ext(?path, ?args, ?body, _, _)) {
|
||||
wrd(s, "#");
|
||||
print_path(s, path);
|
||||
if (_vec.len[@ast.expr](args) > 0u) {
|
||||
popen(s);
|
||||
commasep[@ast.expr](s, args, pe);
|
||||
pclose(s);
|
||||
}
|
||||
// TODO: extension 'body'
|
||||
}
|
||||
}
|
||||
end(s);
|
||||
}
|
||||
|
|
@ -706,3 +718,28 @@ fn escape_str(str st, char to_escape) -> str {
|
|||
impure fn print_string(ps s, str st) {
|
||||
wrd(s, "\""); wrd(s, escape_str(st, '"')); wrd(s, "\"");
|
||||
}
|
||||
|
||||
impure fn print_ty_fn(ps s, ast.proto proto, option.t[str] id,
|
||||
vec[ast.ty_arg] inputs, @ast.ty output) {
|
||||
if (proto == ast.proto_fn) {wrd(s, "fn");}
|
||||
else {wrd(s, "iter");}
|
||||
alt (id) {
|
||||
case (option.some[str](?id)) {space(s); wrd(s, id);}
|
||||
case (_) {}
|
||||
}
|
||||
popen(s);
|
||||
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);
|
||||
}
|
||||
auto f = print_arg;
|
||||
commasep[ast.ty_arg](s, inputs, f);
|
||||
pclose(s);
|
||||
if (output.node != ast.ty_nil) {
|
||||
space(s);
|
||||
hbox(s);
|
||||
wrd1(s, "->");
|
||||
print_type(s, output);
|
||||
end(s);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@ mod front {
|
|||
mod extfmt;
|
||||
mod lexer;
|
||||
mod parser;
|
||||
mod pretty;
|
||||
mod token;
|
||||
mod eval;
|
||||
}
|
||||
|
||||
mod middle {
|
||||
mod fold;
|
||||
mod metadata;
|
||||
mod resolve;
|
||||
mod trans;
|
||||
mod ty;
|
||||
|
|
@ -41,10 +41,12 @@ mod util {
|
|||
}
|
||||
|
||||
auth driver.rustc.main = impure;
|
||||
auth middle.metadata = unsafe;
|
||||
auth middle.trans = unsafe;
|
||||
auth middle.trans.copy_args_to_allocas = impure;
|
||||
auth middle.trans.trans_block = impure;
|
||||
auth lib.llvm = unsafe;
|
||||
auth pretty.pprust = impure;
|
||||
|
||||
mod lib {
|
||||
alt (target_os) {
|
||||
|
|
|
|||
|
|
@ -46,6 +46,10 @@ fn new_str_hash[V]() -> std.map.hashmap[str,V] {
|
|||
ret std.map.mk_hashmap[str,V](hasher, eqer);
|
||||
}
|
||||
|
||||
fn def_eq(&ast.def_id a, &ast.def_id b) -> bool {
|
||||
ret a._0 == b._0 && a._1 == b._1;
|
||||
}
|
||||
|
||||
fn new_def_hash[V]() -> std.map.hashmap[ast.def_id,V] {
|
||||
|
||||
fn hash(&ast.def_id d) -> uint {
|
||||
|
|
@ -55,12 +59,8 @@ fn new_def_hash[V]() -> std.map.hashmap[ast.def_id,V] {
|
|||
ret u;
|
||||
}
|
||||
|
||||
fn eq(&ast.def_id a, &ast.def_id b) -> bool {
|
||||
ret a._0 == b._0 && a._1 == b._1;
|
||||
}
|
||||
|
||||
let std.map.hashfn[ast.def_id] hasher = hash;
|
||||
let std.map.eqfn[ast.def_id] eqer = eq;
|
||||
let std.map.eqfn[ast.def_id] eqer = def_eq;
|
||||
ret std.map.mk_hashmap[ast.def_id,V](hasher, eqer);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import std.sys;
|
||||
|
||||
fn add(int x, int y) -> int { ret x + y; }
|
||||
fn sub(int x, int y) -> int { ret x - y; }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import rustrt.sbuf;
|
||||
|
||||
import std._vec.rustrt.vbuf;
|
||||
import _vec.rustrt.vbuf;
|
||||
|
||||
native "rust" mod rustrt {
|
||||
type sbuf;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import std.sys;
|
||||
|
||||
fn add(uint x, uint y) -> uint { ret x + y; }
|
||||
fn sub(uint x, uint y) -> uint { ret x - y; }
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import vbuf = rustrt.vbuf;
|
||||
import std.option;
|
||||
|
||||
type operator2[T,U,V] = fn(&T, &U) -> V;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,3 @@
|
|||
import std._uint;
|
||||
import std._int;
|
||||
import std._vec;
|
||||
|
||||
// FIXME: With recursive object types, we could implement binary methods like
|
||||
// union, intersection, and difference. At that point, we could write
|
||||
// an optimizing version of this module that produces a different obj
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@
|
|||
* logging.
|
||||
*/
|
||||
|
||||
import std._vec;
|
||||
|
||||
// FIXME: handle 64-bit case.
|
||||
const uint const_refcount = 0x7bad_face_u;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,6 @@
|
|||
* A deque, for fun. Untested as of yet. Likely buggy.
|
||||
*/
|
||||
|
||||
import std.option;
|
||||
import std._vec;
|
||||
import std._int;
|
||||
|
||||
type t[T] = obj {
|
||||
fn size() -> uint;
|
||||
|
||||
|
|
|
|||
107
src/lib/io.rs
107
src/lib/io.rs
|
|
@ -1,7 +1,4 @@
|
|||
import std.os.libc;
|
||||
import std._str;
|
||||
import std._vec;
|
||||
|
||||
import os.libc;
|
||||
|
||||
type stdio_reader = state obj {
|
||||
fn getc() -> int;
|
||||
|
|
@ -91,35 +88,29 @@ tag fileflag {
|
|||
truncate;
|
||||
}
|
||||
|
||||
fn writefd(int fd, vec[u8] v) {
|
||||
auto len = _vec.len[u8](v);
|
||||
auto count = 0u;
|
||||
auto vbuf;
|
||||
while (count < len) {
|
||||
vbuf = _vec.buf_off[u8](v, count);
|
||||
auto nout = os.libc.write(fd, vbuf, len);
|
||||
if (nout < 0) {
|
||||
log "error dumping buffer";
|
||||
log sys.rustrt.last_os_error();
|
||||
fail;
|
||||
state obj fd_buf_writer(int fd, bool must_close) {
|
||||
fn write(vec[u8] v) {
|
||||
auto len = _vec.len[u8](v);
|
||||
auto count = 0u;
|
||||
auto vbuf;
|
||||
while (count < len) {
|
||||
vbuf = _vec.buf_off[u8](v, count);
|
||||
auto nout = os.libc.write(fd, vbuf, len);
|
||||
if (nout < 0) {
|
||||
log "error dumping buffer";
|
||||
log sys.rustrt.last_os_error();
|
||||
fail;
|
||||
}
|
||||
count += nout as uint;
|
||||
}
|
||||
count += nout as uint;
|
||||
}
|
||||
|
||||
drop {
|
||||
if (must_close) {os.libc.close(fd);}
|
||||
}
|
||||
}
|
||||
|
||||
fn new_buf_writer(str path, vec[fileflag] flags) -> buf_writer {
|
||||
|
||||
state obj fd_buf_writer(int fd) {
|
||||
|
||||
fn write(vec[u8] v) {
|
||||
writefd(fd, v);
|
||||
}
|
||||
|
||||
drop {
|
||||
os.libc.close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
fn file_buf_writer(str path, vec[fileflag] flags) -> buf_writer {
|
||||
let int fflags =
|
||||
os.libc_constants.O_WRONLY() |
|
||||
os.libc_constants.O_BINARY();
|
||||
|
|
@ -142,26 +133,58 @@ fn new_buf_writer(str path, vec[fileflag] flags) -> buf_writer {
|
|||
log sys.rustrt.last_os_error();
|
||||
fail;
|
||||
}
|
||||
ret fd_buf_writer(fd);
|
||||
ret fd_buf_writer(fd, true);
|
||||
}
|
||||
|
||||
type writer =
|
||||
state obj {
|
||||
fn write_str(str s);
|
||||
fn write_int(int n);
|
||||
fn write_uint(uint n);
|
||||
impure fn write_str(str s);
|
||||
impure fn write_int(int n);
|
||||
impure fn write_uint(uint n);
|
||||
};
|
||||
|
||||
fn file_writer(str path,
|
||||
vec[fileflag] flags)
|
||||
-> writer
|
||||
{
|
||||
state obj fw(buf_writer out) {
|
||||
fn write_str(str s) { out.write(_str.bytes(s)); }
|
||||
fn write_int(int n) { out.write(_str.bytes(_int.to_str(n, 10u))); }
|
||||
fn write_uint(uint n) { out.write(_str.bytes(_uint.to_str(n, 10u))); }
|
||||
state obj new_writer(buf_writer out) {
|
||||
impure fn write_str(str s) {
|
||||
out.write(_str.bytes(s));
|
||||
}
|
||||
ret fw(new_buf_writer(path, flags));
|
||||
impure fn write_int(int n) {
|
||||
out.write(_str.bytes(_int.to_str(n, 10u)));
|
||||
}
|
||||
impure fn write_uint(uint n) {
|
||||
out.write(_str.bytes(_uint.to_str(n, 10u)));
|
||||
}
|
||||
}
|
||||
|
||||
fn file_writer(str path, vec[fileflag] flags) -> writer {
|
||||
ret new_writer(file_buf_writer(path, flags));
|
||||
}
|
||||
|
||||
// FIXME it would be great if this could be a const named stdout
|
||||
fn stdout_writer() -> writer {
|
||||
ret new_writer(fd_buf_writer(1, false));
|
||||
}
|
||||
|
||||
type str_writer =
|
||||
state obj {
|
||||
fn get_writer() -> writer;
|
||||
fn get_str() -> str;
|
||||
};
|
||||
|
||||
type str_buf = @rec(mutable str buf);
|
||||
|
||||
// TODO awkward! it's not possible to implement a writer with an extra method
|
||||
fn string_writer() -> str_writer {
|
||||
auto buf = @rec(mutable buf = "");
|
||||
state obj str_writer_writer(str_buf buf) {
|
||||
impure fn write_str(str s) { buf.buf += s; }
|
||||
impure fn write_int(int n) { buf.buf += _int.to_str(n, 10u); }
|
||||
impure fn write_uint(uint n) { buf.buf += _uint.to_str(n, 10u); }
|
||||
}
|
||||
state obj str_writer_wrap(writer wr, str_buf buf) {
|
||||
fn get_writer() -> writer {ret wr;}
|
||||
fn get_str() -> str {ret buf.buf;}
|
||||
}
|
||||
ret str_writer_wrap(str_writer_writer(buf), buf);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
import std.option;
|
||||
import option.some;
|
||||
import option.none;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,6 @@
|
|||
* use, but useful as a stress test for rustboot.
|
||||
*/
|
||||
|
||||
import std._int;
|
||||
import std.sys;
|
||||
import std.option;
|
||||
import std._vec;
|
||||
|
||||
|
||||
type hashfn[K] = fn(&K) -> uint;
|
||||
type eqfn[K] = fn(&K, &K) -> bool;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,6 @@
|
|||
* point this will want to be rewritten.
|
||||
*/
|
||||
|
||||
import std._vec;
|
||||
import std._str;
|
||||
|
||||
export sha1;
|
||||
export mk_sha1;
|
||||
|
||||
|
|
|
|||
55
src/llvmext/Object.cpp
Normal file
55
src/llvmext/Object.cpp
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
//===- Object.cpp - C bindings to the object file library--------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the C bindings to the file-format-independent object
|
||||
// library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm-c/Object.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace object;
|
||||
|
||||
LLVMObjectFileRef LLVMCreateObjectFile(const char *ObjectPath) {
|
||||
StringRef SR(ObjectPath);
|
||||
return wrap(ObjectFile::createObjectFile(SR));
|
||||
}
|
||||
|
||||
void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) {
|
||||
delete unwrap(ObjectFile);
|
||||
}
|
||||
|
||||
LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef ObjectFile) {
|
||||
ObjectFile::section_iterator SI = unwrap(ObjectFile)->begin_sections();
|
||||
return wrap(new ObjectFile::section_iterator(SI));
|
||||
}
|
||||
|
||||
void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) {
|
||||
delete unwrap(SI);
|
||||
}
|
||||
|
||||
void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) {
|
||||
ObjectFile::section_iterator UnwrappedSI = *unwrap(SI);
|
||||
++UnwrappedSI;
|
||||
}
|
||||
|
||||
const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) {
|
||||
return (*unwrap(SI))->getName().data();
|
||||
}
|
||||
|
||||
uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) {
|
||||
return (*unwrap(SI))->getSize();
|
||||
}
|
||||
|
||||
const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) {
|
||||
return (*unwrap(SI))->getContents().data();
|
||||
}
|
||||
|
||||
3
src/llvmext/README
Normal file
3
src/llvmext/README
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
This directory currently contains some LLVM support code. This will generally
|
||||
be sent upstream to LLVM in time; for now it lives here.
|
||||
|
||||
75
src/llvmext/include/llvm-c/Object.h
Normal file
75
src/llvmext/include/llvm-c/Object.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/*===-- llvm-c/Object.h - Object Lib C Iface --------------------*- C++ -*-===*/
|
||||
/* */
|
||||
/* The LLVM Compiler Infrastructure */
|
||||
/* */
|
||||
/* This file is distributed under the University of Illinois Open Source */
|
||||
/* License. See LICENSE.TXT for details. */
|
||||
/* */
|
||||
/*===----------------------------------------------------------------------===*/
|
||||
/* */
|
||||
/* This header declares the C interface to libLLVMObject.a, which */
|
||||
/* implements object file reading and writing. */
|
||||
/* */
|
||||
/* Many exotic languages can interoperate with C code but have a harder time */
|
||||
/* with C++ due to name mangling. So in addition to C, this interface enables */
|
||||
/* tools written in such languages. */
|
||||
/* */
|
||||
/*===----------------------------------------------------------------------===*/
|
||||
|
||||
#ifndef LLVM_C_OBJECT_H
|
||||
#define LLVM_C_OBJECT_H
|
||||
|
||||
#include "llvm-c/Core.h"
|
||||
#include "llvm/Config/llvm-config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct LLVMOpaqueObjectFile *LLVMObjectFileRef;
|
||||
|
||||
typedef struct LLVMOpaqueSectionIterator *LLVMSectionIteratorRef;
|
||||
|
||||
LLVMObjectFileRef LLVMCreateObjectFile(const char *ObjectPath);
|
||||
void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile);
|
||||
|
||||
LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef ObjectFile);
|
||||
void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI);
|
||||
void LLVMMoveToNextSection(LLVMSectionIteratorRef SI);
|
||||
const char *LLVMGetSectionName(LLVMSectionIteratorRef SI);
|
||||
uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI);
|
||||
const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
namespace object {
|
||||
inline ObjectFile *unwrap(LLVMObjectFileRef OF) {
|
||||
return reinterpret_cast<ObjectFile*>(OF);
|
||||
}
|
||||
|
||||
inline LLVMObjectFileRef wrap(const ObjectFile *OF) {
|
||||
return reinterpret_cast<LLVMObjectFileRef>(const_cast<ObjectFile*>(OF));
|
||||
}
|
||||
|
||||
inline ObjectFile::section_iterator *unwrap(LLVMSectionIteratorRef SI) {
|
||||
return reinterpret_cast<ObjectFile::section_iterator*>(SI);
|
||||
}
|
||||
|
||||
inline LLVMSectionIteratorRef
|
||||
wrap(const ObjectFile::section_iterator *SI) {
|
||||
return reinterpret_cast<LLVMSectionIteratorRef>
|
||||
(const_cast<ObjectFile::section_iterator*>(SI));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
#endif
|
||||
|
||||
5
src/test/run-pass/box-compare.rs
Normal file
5
src/test/run-pass/box-compare.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
fn main() {
|
||||
check (@1 < @3);
|
||||
check (@@"hello " > @@"hello");
|
||||
check (@@@"hello" != @@@"there");
|
||||
}
|
||||
10
src/test/run-pass/generic-bind-2.rs
Normal file
10
src/test/run-pass/generic-bind-2.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
fn id[T](&T t) -> T {
|
||||
ret t;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
auto t = tup(1,2,3,4,5,6,7);
|
||||
check (t._5 == 6);
|
||||
auto f0 = bind id[tup(int,int,int,int,int,int,int)](t);
|
||||
check (f0()._5 == 6);
|
||||
}
|
||||
|
|
@ -3,6 +3,8 @@ fn id[T](&T t) -> T {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
auto f = bind id[int](_);
|
||||
check (f(10) == 10);
|
||||
auto t = tup(1,2,3,4,5,6,7);
|
||||
check (t._5 == 6);
|
||||
auto f1 = bind id[tup(int,int,int,int,int,int,int)](_);
|
||||
check (f1(t)._5 == 6);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ tag foo[T] {
|
|||
arm(T);
|
||||
}
|
||||
|
||||
fn altfoo[T](foo[T] f) {
|
||||
fn altfoo[T](&foo[T] f) {
|
||||
auto hit = false;
|
||||
alt (f) {
|
||||
case (arm[T](?x)) {
|
||||
|
|
|
|||
8
src/test/run-pass/generic-tag-local.rs
Normal file
8
src/test/run-pass/generic-tag-local.rs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
tag clam[T] {
|
||||
a(T);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
auto c = a(3);
|
||||
}
|
||||
|
||||
9
src/test/run-pass/leak-tag-copy.rs
Normal file
9
src/test/run-pass/leak-tag-copy.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
tag t {
|
||||
a;
|
||||
b(@int);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
auto x = b(@10);
|
||||
x = a;
|
||||
}
|
||||
15
src/test/run-pass/seq-compare.rs
Normal file
15
src/test/run-pass/seq-compare.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
fn main() {
|
||||
check ("hello" < "hellr");
|
||||
check ("hello " > "hello");
|
||||
check ("hello" != "there");
|
||||
|
||||
check (vec(1,2,3,4) > vec(1,2,3));
|
||||
check (vec(1,2,3) < vec(1,2,3,4));
|
||||
check (vec(1,2,4,4) > vec(1,2,3,4));
|
||||
check (vec(1,2,3,4) < vec(1,2,4,4));
|
||||
check (vec(1,2,3) <= vec(1,2,3));
|
||||
check (vec(1,2,3) <= vec(1,2,3,3));
|
||||
check (vec(1,2,3,4) > vec(1,2,3));
|
||||
check (vec(1,2,3) == vec(1,2,3));
|
||||
check (vec(1,2,3) != vec(1,1,3));
|
||||
}
|
||||
11
src/test/run-pass/simple-generic-alt.rs
Normal file
11
src/test/run-pass/simple-generic-alt.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
tag clam[T] {
|
||||
a(T);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
auto c = a(2);
|
||||
alt (c) {
|
||||
case (a[int](_)) {}
|
||||
}
|
||||
}
|
||||
|
||||
7
src/test/run-pass/simple-generic-tag.rs
Normal file
7
src/test/run-pass/simple-generic-tag.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
tag clam[T] {
|
||||
a(T);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue