First pass on splitting stratum and opacity off of effects. WIP.
This commit is contained in:
@@ -667,11 +667,12 @@ The keywords are:
|
|||||||
@tab @code{export}
|
@tab @code{export}
|
||||||
@tab @code{let}
|
@tab @code{let}
|
||||||
@tab @code{auto}
|
@tab @code{auto}
|
||||||
@item @code{io}
|
@item @code{state}
|
||||||
@tab @code{state}
|
@tab @code{gc}
|
||||||
|
@tab @code{abs}
|
||||||
|
@item @code{auth}
|
||||||
|
@tab @code{impure}
|
||||||
@tab @code{unsafe}
|
@tab @code{unsafe}
|
||||||
@tab @code{auth}
|
|
||||||
@tab @code{with}
|
|
||||||
@item @code{bind}
|
@item @code{bind}
|
||||||
@tab @code{type}
|
@tab @code{type}
|
||||||
@tab @code{true}
|
@tab @code{true}
|
||||||
@@ -705,8 +706,8 @@ The keywords are:
|
|||||||
@item @code{task}
|
@item @code{task}
|
||||||
@tab @code{port}
|
@tab @code{port}
|
||||||
@tab @code{chan}
|
@tab @code{chan}
|
||||||
@tab @code{flush}
|
|
||||||
@tab @code{spawn}
|
@tab @code{spawn}
|
||||||
|
@tab @code{with}
|
||||||
@item @code{if}
|
@item @code{if}
|
||||||
@tab @code{else}
|
@tab @code{else}
|
||||||
@tab @code{alt}
|
@tab @code{alt}
|
||||||
@@ -1473,7 +1474,6 @@ operating-system processes.
|
|||||||
@cindex Message passing
|
@cindex Message passing
|
||||||
@cindex Send statement
|
@cindex Send statement
|
||||||
@cindex Receive statement
|
@cindex Receive statement
|
||||||
@cindex Flush statement
|
|
||||||
|
|
||||||
With the exception of @emph{unsafe} constructs, Rust tasks are isolated from
|
With the exception of @emph{unsafe} constructs, Rust tasks are isolated from
|
||||||
interfering with one another's memory directly. Instead of manipulating shared
|
interfering with one another's memory directly. Instead of manipulating shared
|
||||||
@@ -1515,11 +1515,7 @@ task. If too many messages are queued for transmission from a single sending
|
|||||||
task, without being received by a receiving task, the sending task may exceed
|
task, without being received by a receiving task, the sending task may exceed
|
||||||
its memory budget, which causes a run-time signal. To help control this
|
its memory budget, which causes a run-time signal. To help control this
|
||||||
possibility, a semi-synchronous send operation is possible, which blocks until
|
possibility, a semi-synchronous send operation is possible, which blocks until
|
||||||
there is room in the existing queue and then executes an asynchronous send. A
|
there is room in the existing queue and then executes an asynchronous send.
|
||||||
full @code{flush} operation is also available, which blocks until a channel's
|
|
||||||
queue is @emph{empty}. A @code{flush} does @emph{not} guarantee that a message
|
|
||||||
has been @emph{received} by any particular recipient when the sending task is
|
|
||||||
unblocked. @xref{Ref.Stmt.Flush}.
|
|
||||||
|
|
||||||
The asynchronous message-send operator is @code{<+}. The semi-synchronous
|
The asynchronous message-send operator is @code{<+}. The semi-synchronous
|
||||||
message-send operator is @code{<|}. @xref{Ref.Stmt.Send}. The message-receive
|
message-send operator is @code{<|}. @xref{Ref.Stmt.Send}. The message-receive
|
||||||
@@ -2550,7 +2546,6 @@ actions.
|
|||||||
* Ref.Stmt.Copy:: Statement for copying a value.
|
* Ref.Stmt.Copy:: Statement for copying a value.
|
||||||
* Ref.Stmt.Spawn:: Statements for creating new tasks.
|
* Ref.Stmt.Spawn:: Statements for creating new tasks.
|
||||||
* Ref.Stmt.Send:: Statements for sending a value into a channel.
|
* Ref.Stmt.Send:: Statements for sending a value into a channel.
|
||||||
* Ref.Stmt.Flush:: Statement for flushing a channel queue.
|
|
||||||
* Ref.Stmt.Recv:: Statement for receiving a value from a channel.
|
* Ref.Stmt.Recv:: Statement for receiving a value from a channel.
|
||||||
* Ref.Stmt.Call:: Statement for calling a function.
|
* Ref.Stmt.Call:: Statement for calling a function.
|
||||||
* Ref.Stmt.Bind:: Statement for binding arguments to functions.
|
* Ref.Stmt.Bind:: Statement for binding arguments to functions.
|
||||||
@@ -2933,24 +2928,6 @@ chan[str] c = @dots{};
|
|||||||
c <| "hello, world";
|
c <| "hello, world";
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@node Ref.Stmt.Flush
|
|
||||||
@subsection Ref.Stmt.Flush
|
|
||||||
@c * Ref.Stmt.Flush:: Statement for flushing a channel queue.
|
|
||||||
@cindex Flush statement
|
|
||||||
@cindex Communication
|
|
||||||
|
|
||||||
A @code{flush} statement takes a channel and blocks the flushing task until
|
|
||||||
the channel's queue has emptied. It can be used to implement a more precise
|
|
||||||
form of flow-control than with the send operators alone.
|
|
||||||
|
|
||||||
An example of the @code{flush} statement:
|
|
||||||
@example
|
|
||||||
chan[str] c = @dots{};
|
|
||||||
c <| "hello, world";
|
|
||||||
flush c;
|
|
||||||
@end example
|
|
||||||
|
|
||||||
|
|
||||||
@node Ref.Stmt.Recv
|
@node Ref.Stmt.Recv
|
||||||
@subsection Ref.Stmt.Recv
|
@subsection Ref.Stmt.Recv
|
||||||
@c * Ref.Stmt.Recv:: Statement for receiving a value from a channel.
|
@c * Ref.Stmt.Recv:: Statement for receiving a value from a channel.
|
||||||
@@ -3359,8 +3336,8 @@ statement following the @code{alt} when the case block completes.
|
|||||||
@cindex Multiplexing
|
@cindex Multiplexing
|
||||||
|
|
||||||
The simplest form of @code{alt} statement is the a @emph{communication}
|
The simplest form of @code{alt} statement is the a @emph{communication}
|
||||||
@code{alt}. The cases of a communication @code{alt}'s arms are send, receive
|
@code{alt}. The cases of a communication @code{alt}'s arms are send and
|
||||||
and flush statements. @xref{Ref.Task.Comm}.
|
receive statements. @xref{Ref.Task.Comm}.
|
||||||
|
|
||||||
To execute a communication @code{alt}, the runtime checks all of the ports and
|
To execute a communication @code{alt}, the runtime checks all of the ports and
|
||||||
channels involved in the arms of the statement to see if any @code{case} can
|
channels involved in the arms of the statement to see if any @code{case} can
|
||||||
@@ -3679,3 +3656,11 @@ to the task's domain; if the queue grows too big, the task will fail.
|
|||||||
@printindex cp
|
@printindex cp
|
||||||
|
|
||||||
@bye
|
@bye
|
||||||
|
|
||||||
|
@c Local Variables:
|
||||||
|
@c mode: texinfo
|
||||||
|
@c fill-column: 78;
|
||||||
|
@c indent-tabs-mode: nil
|
||||||
|
@c buffer-file-coding-system: utf-8-unix
|
||||||
|
@c compile-command: "make -k 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
||||||
|
@c End:
|
||||||
|
|||||||
@@ -29,10 +29,20 @@ type slot_key =
|
|||||||
*)
|
*)
|
||||||
|
|
||||||
type effect =
|
type effect =
|
||||||
PURE
|
EFF_pure
|
||||||
| IO
|
| EFF_impure
|
||||||
| STATE
|
| EFF_unsafe
|
||||||
| UNSAFE
|
;;
|
||||||
|
|
||||||
|
type stratum =
|
||||||
|
STRAT_value
|
||||||
|
| STRAT_state
|
||||||
|
| STRAT_gc
|
||||||
|
;;
|
||||||
|
|
||||||
|
type opacity =
|
||||||
|
OPA_transparent
|
||||||
|
| OPA_abstract
|
||||||
;;
|
;;
|
||||||
|
|
||||||
type mutability =
|
type mutability =
|
||||||
@@ -702,10 +712,48 @@ and fmt_effect
|
|||||||
(effect:effect)
|
(effect:effect)
|
||||||
: unit =
|
: unit =
|
||||||
match effect with
|
match effect with
|
||||||
PURE -> ()
|
EFF_pure -> ()
|
||||||
| IO -> fmt ff "io"
|
| EFF_impure -> fmt ff "impure"
|
||||||
| STATE -> fmt ff "state"
|
| EFF_unsafe -> fmt ff "unsafe"
|
||||||
| UNSAFE -> fmt ff "unsafe"
|
|
||||||
|
and fmt_effect_qual
|
||||||
|
(ff:Format.formatter)
|
||||||
|
(e:effect)
|
||||||
|
: unit =
|
||||||
|
fmt_effect ff e;
|
||||||
|
if e <> EFF_pure then fmt ff " ";
|
||||||
|
|
||||||
|
and fmt_stratum
|
||||||
|
(ff:Format.formatter)
|
||||||
|
(strat:stratum)
|
||||||
|
: unit =
|
||||||
|
match strat with
|
||||||
|
STRAT_value -> ()
|
||||||
|
| STRAT_state -> fmt ff "state"
|
||||||
|
| STRAT_gc -> fmt ff "gc"
|
||||||
|
|
||||||
|
and fmt_stratum_qual
|
||||||
|
(ff:Format.formatter)
|
||||||
|
(s:stratum)
|
||||||
|
: unit =
|
||||||
|
fmt_stratum ff s;
|
||||||
|
if s <> STRAT_value then fmt ff " ";
|
||||||
|
|
||||||
|
and fmt_opacity
|
||||||
|
(ff:Format.formatter)
|
||||||
|
(opa:opacity)
|
||||||
|
: unit =
|
||||||
|
match opa with
|
||||||
|
OPA_transparent -> ()
|
||||||
|
| OPA_abstract -> fmt ff "abs"
|
||||||
|
|
||||||
|
and fmt_opacity_qual
|
||||||
|
(ff:Format.formatter)
|
||||||
|
(op:opacity)
|
||||||
|
: unit =
|
||||||
|
fmt_opacity ff op;
|
||||||
|
if op <> OPA_transparent then fmt ff " ";
|
||||||
|
|
||||||
|
|
||||||
and fmt_ty_fn
|
and fmt_ty_fn
|
||||||
(ff:Format.formatter)
|
(ff:Format.formatter)
|
||||||
@@ -713,8 +761,7 @@ and fmt_ty_fn
|
|||||||
(tf:ty_fn)
|
(tf:ty_fn)
|
||||||
: unit =
|
: unit =
|
||||||
let (tsig, ta) = tf in
|
let (tsig, ta) = tf in
|
||||||
fmt_effect ff ta.fn_effect;
|
fmt_effect_qual ff ta.fn_effect;
|
||||||
if ta.fn_effect <> PURE then fmt ff " ";
|
|
||||||
fmt ff "%s" (if ta.fn_is_iter then "iter" else "fn");
|
fmt ff "%s" (if ta.fn_is_iter then "iter" else "fn");
|
||||||
begin
|
begin
|
||||||
match ident_and_params with
|
match ident_and_params with
|
||||||
@@ -763,8 +810,7 @@ and fmt_ty (ff:Format.formatter) (t:ty) : unit =
|
|||||||
fmt_ident_tys ff entries;
|
fmt_ident_tys ff entries;
|
||||||
fmt ff "@]"
|
fmt ff "@]"
|
||||||
|
|
||||||
| TY_param (i, e) -> (fmt_effect ff e;
|
| TY_param (i, e) -> (fmt_effect_qual ff e;
|
||||||
if e <> PURE then fmt ff " ";
|
|
||||||
fmt ff "<p#%d>" i)
|
fmt ff "<p#%d>" i)
|
||||||
| TY_native oid -> fmt ff "<native#%d>" (int_of_opaque oid)
|
| TY_native oid -> fmt ff "<native#%d>" (int_of_opaque oid)
|
||||||
| TY_named n -> fmt_name ff n
|
| TY_named n -> fmt_name ff n
|
||||||
@@ -789,8 +835,7 @@ and fmt_ty (ff:Format.formatter) (t:ty) : unit =
|
|||||||
|
|
||||||
| TY_obj (effect, fns) ->
|
| TY_obj (effect, fns) ->
|
||||||
fmt_obox ff;
|
fmt_obox ff;
|
||||||
fmt_effect ff effect;
|
fmt_effect_qual ff effect;
|
||||||
if effect <> PURE then fmt ff " ";
|
|
||||||
fmt ff "obj ";
|
fmt ff "obj ";
|
||||||
fmt_obr ff;
|
fmt_obr ff;
|
||||||
Hashtbl.iter
|
Hashtbl.iter
|
||||||
@@ -1584,8 +1629,7 @@ and fmt_slice (ff:Format.formatter) (slice:slice) : unit =
|
|||||||
|
|
||||||
and fmt_decl_param (ff:Format.formatter) (param:ty_param) : unit =
|
and fmt_decl_param (ff:Format.formatter) (param:ty_param) : unit =
|
||||||
let (ident, (i, e)) = param in
|
let (ident, (i, e)) = param in
|
||||||
fmt_effect ff e;
|
fmt_effect_qual ff e;
|
||||||
if e <> PURE then fmt ff " ";
|
|
||||||
fmt_ident ff ident;
|
fmt_ident ff ident;
|
||||||
fmt ff "=<p#%d>" i
|
fmt ff "=<p#%d>" i
|
||||||
|
|
||||||
@@ -1608,10 +1652,6 @@ and fmt_ident_and_params
|
|||||||
fmt_ident ff id;
|
fmt_ident ff id;
|
||||||
fmt_decl_params ff params
|
fmt_decl_params ff params
|
||||||
|
|
||||||
and fmt_effect_qual (ff:Format.formatter) (e:effect) : unit =
|
|
||||||
fmt_effect ff e;
|
|
||||||
if e <> PURE then fmt ff " ";
|
|
||||||
|
|
||||||
and fmt_fn
|
and fmt_fn
|
||||||
(ff:Format.formatter)
|
(ff:Format.formatter)
|
||||||
(id:ident)
|
(id:ident)
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ and parse_cexp (ps:pstate) : cexp =
|
|||||||
fun (ident, item) ->
|
fun (ident, item) ->
|
||||||
htab_put items ident item
|
htab_put items ident item
|
||||||
end
|
end
|
||||||
(Item.parse_mod_item_from_signature ps)
|
(Item.parse_native_mod_item_from_signature ps)
|
||||||
in
|
in
|
||||||
ignore (bracketed_zero_or_more
|
ignore (bracketed_zero_or_more
|
||||||
LBRACE RBRACE None get_item ps);
|
LBRACE RBRACE None get_item ps);
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ let rec generate_mod_item (mis:mod_items) (cx:ctxt) : unit =
|
|||||||
match Random.int 2 with
|
match Random.int 2 with
|
||||||
0 ->
|
0 ->
|
||||||
let ty = generate_ty cx in
|
let ty = generate_ty cx in
|
||||||
let eff = PURE in
|
let eff = Ast.EFF_pure in
|
||||||
decl (MOD_ITEM_type (eff, ty))
|
decl (MOD_ITEM_type (eff, ty))
|
||||||
| _ ->
|
| _ ->
|
||||||
let mis' = Hashtbl.create 0 in
|
let mis' = Hashtbl.create 0 in
|
||||||
|
|||||||
@@ -155,8 +155,6 @@ and parse_stmts (ps:pstate) : Ast.stmt array =
|
|||||||
raise (err "statement does nothing" ps);
|
raise (err "statement does nothing" ps);
|
||||||
arr
|
arr
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(*
|
(*
|
||||||
* We have no way to parse a single Ast.stmt; any incoming syntactic statement
|
* We have no way to parse a single Ast.stmt; any incoming syntactic statement
|
||||||
* may desugar to N>1 real Ast.stmts
|
* may desugar to N>1 real Ast.stmts
|
||||||
@@ -605,7 +603,11 @@ and parse_stmts_including_none (ps:pstate) : Ast.stmt array =
|
|||||||
expect ps SEMI;
|
expect ps SEMI;
|
||||||
spans ps stmts apos (Ast.STMT_join lval)
|
spans ps stmts apos (Ast.STMT_join lval)
|
||||||
|
|
||||||
| IO | STATE | UNSAFE | MOD | OBJ | TAG | TYPE | FN | USE | NATIVE ->
|
|
||||||
|
| STATE | GC
|
||||||
|
| IMPURE | UNSAFE
|
||||||
|
| ABS | NATIVE
|
||||||
|
| MOD | OBJ | TAG | TYPE | FN | USE ->
|
||||||
let items = ctxt "stmt: decl" parse_mod_item ps in
|
let items = ctxt "stmt: decl" parse_mod_item ps in
|
||||||
let bpos = lexpos ps in
|
let bpos = lexpos ps in
|
||||||
Array.map
|
Array.map
|
||||||
@@ -689,6 +691,8 @@ and parse_stmts_including_none (ps:pstate) : Ast.stmt array =
|
|||||||
|
|
||||||
and parse_ty_param (iref:int ref) (ps:pstate) : Ast.ty_param identified =
|
and parse_ty_param (iref:int ref) (ps:pstate) : Ast.ty_param identified =
|
||||||
let apos = lexpos ps in
|
let apos = lexpos ps in
|
||||||
|
let _ = Pexp.parse_opacity ps in
|
||||||
|
let _ = Pexp.parse_stratum ps in
|
||||||
let e = Pexp.parse_effect ps in
|
let e = Pexp.parse_effect ps in
|
||||||
let ident = Pexp.parse_ident ps in
|
let ident = Pexp.parse_ident ps in
|
||||||
let i = !iref in
|
let i = !iref in
|
||||||
@@ -851,7 +855,7 @@ and parse_obj_item
|
|||||||
do
|
do
|
||||||
let apos = lexpos ps in
|
let apos = lexpos ps in
|
||||||
match peek ps with
|
match peek ps with
|
||||||
IO | STATE | UNSAFE | FN | ITER ->
|
IMPURE | UNSAFE | FN | ITER ->
|
||||||
let effect = Pexp.parse_effect ps in
|
let effect = Pexp.parse_effect ps in
|
||||||
let is_iter = (peek ps) = ITER in
|
let is_iter = (peek ps) = ITER in
|
||||||
bump ps;
|
bump ps;
|
||||||
@@ -986,7 +990,10 @@ and parse_mod_item (ps:pstate)
|
|||||||
|
|
||||||
match peek ps with
|
match peek ps with
|
||||||
|
|
||||||
IO | STATE | UNSAFE | TYPE | OBJ | TAG | FN | ITER ->
|
STATE | GC | IMPURE | UNSAFE | ABS
|
||||||
|
| TYPE | OBJ | TAG | FN | ITER ->
|
||||||
|
let _ = Pexp.parse_opacity ps in
|
||||||
|
let _ = Pexp.parse_stratum ps in
|
||||||
let effect = Pexp.parse_effect ps in
|
let effect = Pexp.parse_effect ps in
|
||||||
begin
|
begin
|
||||||
match peek ps with
|
match peek ps with
|
||||||
@@ -1044,7 +1051,7 @@ and parse_mod_item (ps:pstate)
|
|||||||
expect ps MOD;
|
expect ps MOD;
|
||||||
let ident = Pexp.parse_ident ps in
|
let ident = Pexp.parse_ident ps in
|
||||||
let path = parse_lib_name ident in
|
let path = parse_lib_name ident in
|
||||||
let items = parse_mod_items_from_signature ps in
|
let items = parse_native_mod_items_from_signature ps in
|
||||||
let bpos = lexpos ps in
|
let bpos = lexpos ps in
|
||||||
let rlib = REQUIRED_LIB_c { required_libname = path;
|
let rlib = REQUIRED_LIB_c { required_libname = path;
|
||||||
required_prefix = ps.pstate_depth }
|
required_prefix = ps.pstate_depth }
|
||||||
@@ -1056,7 +1063,7 @@ and parse_mod_item (ps:pstate)
|
|||||||
end
|
end
|
||||||
| _ -> raise (unexpected ps)
|
| _ -> raise (unexpected ps)
|
||||||
|
|
||||||
and parse_mod_items_header_from_signature (ps:pstate) : Ast.mod_view =
|
and parse_native_mod_header_from_signature (ps:pstate) : Ast.mod_view =
|
||||||
let exports = Hashtbl.create 0 in
|
let exports = Hashtbl.create 0 in
|
||||||
while (peek ps = EXPORT)
|
while (peek ps = EXPORT)
|
||||||
do
|
do
|
||||||
@@ -1068,11 +1075,11 @@ and parse_mod_items_header_from_signature (ps:pstate) : Ast.mod_view =
|
|||||||
then htab_put exports Ast.EXPORT_all_decls ();
|
then htab_put exports Ast.EXPORT_all_decls ();
|
||||||
{empty_view with Ast.view_exports = exports}
|
{empty_view with Ast.view_exports = exports}
|
||||||
|
|
||||||
and parse_mod_items_from_signature
|
and parse_native_mod_items_from_signature
|
||||||
(ps:pstate)
|
(ps:pstate)
|
||||||
: (Ast.mod_view * Ast.mod_items) =
|
: (Ast.mod_view * Ast.mod_items) =
|
||||||
expect ps LBRACE;
|
expect ps LBRACE;
|
||||||
let view = parse_mod_items_header_from_signature ps in
|
let view = parse_native_mod_header_from_signature ps in
|
||||||
let items = Hashtbl.create 0 in
|
let items = Hashtbl.create 0 in
|
||||||
while not (peek ps = RBRACE)
|
while not (peek ps = RBRACE)
|
||||||
do
|
do
|
||||||
@@ -1080,24 +1087,24 @@ and parse_mod_items_from_signature
|
|||||||
(fun (ident, item) ->
|
(fun (ident, item) ->
|
||||||
htab_put items ident item)
|
htab_put items ident item)
|
||||||
(ctxt "mod items from sig: mod item"
|
(ctxt "mod items from sig: mod item"
|
||||||
parse_mod_item_from_signature ps)
|
parse_native_mod_item_from_signature ps)
|
||||||
done;
|
done;
|
||||||
expect ps RBRACE;
|
expect ps RBRACE;
|
||||||
(view,items)
|
(view,items)
|
||||||
|
|
||||||
and parse_mod_item_from_signature (ps:pstate)
|
and parse_native_mod_item_from_signature (ps:pstate)
|
||||||
: (Ast.ident * Ast.mod_item) array =
|
: (Ast.ident * Ast.mod_item) array =
|
||||||
let apos = lexpos ps in
|
let apos = lexpos ps in
|
||||||
match peek ps with
|
match peek ps with
|
||||||
MOD ->
|
MOD ->
|
||||||
bump ps;
|
bump ps;
|
||||||
let (ident, params) = parse_ident_and_params ps "mod signature" in
|
let (ident, params) = parse_ident_and_params ps "mod signature" in
|
||||||
let items = parse_mod_items_from_signature ps in
|
let items = parse_native_mod_items_from_signature ps in
|
||||||
let bpos = lexpos ps in
|
let bpos = lexpos ps in
|
||||||
[| (ident,
|
[| (ident,
|
||||||
span ps apos bpos (decl params (Ast.MOD_ITEM_mod items))) |]
|
span ps apos bpos (decl params (Ast.MOD_ITEM_mod items))) |]
|
||||||
|
|
||||||
| IO | STATE | UNSAFE | FN | ITER ->
|
| IMPURE | UNSAFE | FN | ITER ->
|
||||||
let effect = Pexp.parse_effect ps in
|
let effect = Pexp.parse_effect ps in
|
||||||
let is_iter = (peek ps) = ITER in
|
let is_iter = (peek ps) = ITER in
|
||||||
bump ps;
|
bump ps;
|
||||||
@@ -1142,7 +1149,7 @@ and parse_mod_item_from_signature (ps:pstate)
|
|||||||
expect ps SEMI;
|
expect ps SEMI;
|
||||||
let bpos = lexpos ps in
|
let bpos = lexpos ps in
|
||||||
[| (ident, span ps apos bpos
|
[| (ident, span ps apos bpos
|
||||||
(decl params (Ast.MOD_ITEM_type (Ast.UNSAFE, t)))) |]
|
(decl params (Ast.MOD_ITEM_type (Ast.EFF_unsafe, t)))) |]
|
||||||
|
|
||||||
| _ -> raise (unexpected ps)
|
| _ -> raise (unexpected ps)
|
||||||
|
|
||||||
|
|||||||
@@ -95,8 +95,12 @@
|
|||||||
("claim", CLAIM);
|
("claim", CLAIM);
|
||||||
("prove", PROVE);
|
("prove", PROVE);
|
||||||
|
|
||||||
("io", IO);
|
("abs", ABS);
|
||||||
|
|
||||||
("state", STATE);
|
("state", STATE);
|
||||||
|
("gc", GC);
|
||||||
|
|
||||||
|
("impure", IMPURE);
|
||||||
("unsafe", UNSAFE);
|
("unsafe", UNSAFE);
|
||||||
|
|
||||||
("native", NATIVE);
|
("native", NATIVE);
|
||||||
|
|||||||
@@ -140,12 +140,22 @@ and parse_optional_trailing_constrs (ps:pstate) : Ast.constrs =
|
|||||||
COLON -> (bump ps; parse_constrs ps)
|
COLON -> (bump ps; parse_constrs ps)
|
||||||
| _ -> [| |]
|
| _ -> [| |]
|
||||||
|
|
||||||
|
and parse_opacity (ps:pstate) : Ast.opacity =
|
||||||
|
match peek ps with
|
||||||
|
ABS -> bump ps; Ast.OPA_abstract
|
||||||
|
| _ -> Ast.OPA_transparent
|
||||||
|
|
||||||
|
and parse_stratum (ps:pstate) : Ast.stratum =
|
||||||
|
match peek ps with
|
||||||
|
STATE -> bump ps; Ast.STRAT_state
|
||||||
|
| GC -> bump ps; Ast.STRAT_gc
|
||||||
|
| _ -> Ast.STRAT_value
|
||||||
|
|
||||||
and parse_effect (ps:pstate) : Ast.effect =
|
and parse_effect (ps:pstate) : Ast.effect =
|
||||||
match peek ps with
|
match peek ps with
|
||||||
IO -> bump ps; Ast.IO
|
IMPURE -> bump ps; Ast.EFF_impure
|
||||||
| STATE -> bump ps; Ast.STATE
|
| UNSAFE -> bump ps; Ast.EFF_unsafe
|
||||||
| UNSAFE -> bump ps; Ast.UNSAFE
|
| _ -> Ast.EFF_pure
|
||||||
| _ -> Ast.PURE
|
|
||||||
|
|
||||||
and parse_mutability (ps:pstate) : Ast.mutability =
|
and parse_mutability (ps:pstate) : Ast.mutability =
|
||||||
match peek ps with
|
match peek ps with
|
||||||
@@ -263,7 +273,9 @@ and parse_atomic_ty (ps:pstate) : Ast.ty =
|
|||||||
bump ps;
|
bump ps;
|
||||||
Ast.TY_mach m
|
Ast.TY_mach m
|
||||||
|
|
||||||
| IO | STATE | UNSAFE | OBJ | FN | ITER ->
|
| ABS | STATE | GC | IMPURE | UNSAFE | OBJ | FN | ITER ->
|
||||||
|
let _ = parse_opacity ps in
|
||||||
|
let _ = parse_stratum ps in
|
||||||
let effect = parse_effect ps in
|
let effect = parse_effect ps in
|
||||||
begin
|
begin
|
||||||
match peek ps with
|
match peek ps with
|
||||||
|
|||||||
@@ -80,9 +80,15 @@ type token =
|
|||||||
| CLAIM
|
| CLAIM
|
||||||
| PROVE
|
| PROVE
|
||||||
|
|
||||||
(* Effect keywords *)
|
(* Opacity keywords *)
|
||||||
| IO
|
| ABS
|
||||||
|
|
||||||
|
(* Stratum keywords *)
|
||||||
| STATE
|
| STATE
|
||||||
|
| GC
|
||||||
|
|
||||||
|
(* Effect keywords *)
|
||||||
|
| IMPURE
|
||||||
| UNSAFE
|
| UNSAFE
|
||||||
|
|
||||||
(* Type qualifiers *)
|
(* Type qualifiers *)
|
||||||
@@ -237,9 +243,15 @@ let rec string_of_tok t =
|
|||||||
| CLAIM -> "claim"
|
| CLAIM -> "claim"
|
||||||
| PROVE -> "prove"
|
| PROVE -> "prove"
|
||||||
|
|
||||||
(* Effect keywords *)
|
(* Opacity keywords *)
|
||||||
| IO -> "io"
|
| ABS -> "abs"
|
||||||
|
|
||||||
|
(* Stratum keywords *)
|
||||||
| STATE -> "state"
|
| STATE -> "state"
|
||||||
|
| GC -> "gc"
|
||||||
|
|
||||||
|
(* Effect keywords *)
|
||||||
|
| IMPURE -> "impure"
|
||||||
| UNSAFE -> "unsafe"
|
| UNSAFE -> "unsafe"
|
||||||
|
|
||||||
(* Type qualifiers *)
|
(* Type qualifiers *)
|
||||||
|
|||||||
@@ -1527,10 +1527,9 @@ let dwarf_visitor
|
|||||||
(* Note: weird encoding: mutable+pure = unsafe. *)
|
(* Note: weird encoding: mutable+pure = unsafe. *)
|
||||||
let mut_byte, pure_byte =
|
let mut_byte, pure_byte =
|
||||||
match eff with
|
match eff with
|
||||||
Ast.UNSAFE -> (1,1)
|
Ast.EFF_unsafe -> (1,1)
|
||||||
| Ast.STATE -> (1,0)
|
| Ast.EFF_impure -> (0,0)
|
||||||
| Ast.IO -> (0,0)
|
| Ast.EFF_pure -> (0,1)
|
||||||
| Ast.PURE -> (0,1)
|
|
||||||
in
|
in
|
||||||
SEQ [|
|
SEQ [|
|
||||||
(* DW_AT_mutable: DW_FORM_flag *)
|
(* DW_AT_mutable: DW_FORM_flag *)
|
||||||
@@ -2888,10 +2887,10 @@ let rec extract_mod_items
|
|||||||
let get_effect die =
|
let get_effect die =
|
||||||
match (get_flag die DW_AT_mutable, get_flag die DW_AT_pure) with
|
match (get_flag die DW_AT_mutable, get_flag die DW_AT_pure) with
|
||||||
(* Note: weird encoding: mutable+pure = unsafe. *)
|
(* Note: weird encoding: mutable+pure = unsafe. *)
|
||||||
(true, true) -> Ast.UNSAFE
|
(true, true) -> Ast.EFF_unsafe
|
||||||
| (true, false) -> Ast.STATE
|
| (false, false) -> Ast.EFF_impure
|
||||||
| (false, false) -> Ast.IO
|
| (false, true) -> Ast.EFF_pure
|
||||||
| (false, true) -> Ast.PURE
|
| _ -> failwith "bad effect encoding"
|
||||||
in
|
in
|
||||||
|
|
||||||
let get_name die = get_str die DW_AT_name in
|
let get_name die = get_str die DW_AT_name in
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ let function_effect_propagation_visitor
|
|||||||
* This visitor calculates the effect of each function according to
|
* This visitor calculates the effect of each function according to
|
||||||
* its statements:
|
* its statements:
|
||||||
*
|
*
|
||||||
* - Communication lowers to 'io'
|
* - Communication statements lower to 'impure'
|
||||||
* - Native calls lower to 'unsafe'
|
* - Native calls lower to 'unsafe'
|
||||||
* - Calling a function with effect e lowers to e.
|
* - Calling a function with effect e lowers to e.
|
||||||
*)
|
*)
|
||||||
@@ -138,7 +138,7 @@ let function_effect_propagation_visitor
|
|||||||
let fn_id = Stack.top curr_fn in
|
let fn_id = Stack.top curr_fn in
|
||||||
let e =
|
let e =
|
||||||
match htab_search item_effect fn_id with
|
match htab_search item_effect fn_id with
|
||||||
None -> Ast.PURE
|
None -> Ast.EFF_pure
|
||||||
| Some e -> e
|
| Some e -> e
|
||||||
in
|
in
|
||||||
let ne = lower_effect_of ne e in
|
let ne = lower_effect_of ne e in
|
||||||
@@ -163,7 +163,7 @@ let function_effect_propagation_visitor
|
|||||||
begin
|
begin
|
||||||
match s.node with
|
match s.node with
|
||||||
Ast.STMT_send _
|
Ast.STMT_send _
|
||||||
| Ast.STMT_recv _ -> lower_to s Ast.IO
|
| Ast.STMT_recv _ -> lower_to s Ast.EFF_impure
|
||||||
|
|
||||||
| Ast.STMT_call (_, fn, _) ->
|
| Ast.STMT_call (_, fn, _) ->
|
||||||
let lower_to_callee_ty t =
|
let lower_to_callee_ty t =
|
||||||
@@ -183,7 +183,7 @@ let function_effect_propagation_visitor
|
|||||||
match htab_search cx.ctxt_required_items item.id with
|
match htab_search cx.ctxt_required_items item.id with
|
||||||
None -> ()
|
None -> ()
|
||||||
| Some (REQUIRED_LIB_rust _, _) -> ()
|
| Some (REQUIRED_LIB_rust _, _) -> ()
|
||||||
| Some _ -> lower_to s Ast.UNSAFE
|
| Some _ -> lower_to s Ast.EFF_unsafe
|
||||||
end
|
end
|
||||||
| _ -> ()
|
| _ -> ()
|
||||||
end;
|
end;
|
||||||
@@ -232,7 +232,7 @@ let effect_checking_visitor
|
|||||||
| Some e ->
|
| Some e ->
|
||||||
let curr =
|
let curr =
|
||||||
if Stack.is_empty auth_stack
|
if Stack.is_empty auth_stack
|
||||||
then Ast.PURE
|
then Ast.EFF_pure
|
||||||
else Stack.top auth_stack
|
else Stack.top auth_stack
|
||||||
in
|
in
|
||||||
let next = lower_effect_of e curr in
|
let next = lower_effect_of e curr in
|
||||||
@@ -253,7 +253,7 @@ let effect_checking_visitor
|
|||||||
Ast.MOD_ITEM_fn f ->
|
Ast.MOD_ITEM_fn f ->
|
||||||
let e =
|
let e =
|
||||||
match htab_search item_effect i.id with
|
match htab_search item_effect i.id with
|
||||||
None -> Ast.PURE
|
None -> Ast.EFF_pure
|
||||||
| Some e -> e
|
| Some e -> e
|
||||||
in
|
in
|
||||||
let fe = f.Ast.fn_aux.Ast.fn_effect in
|
let fe = f.Ast.fn_aux.Ast.fn_effect in
|
||||||
@@ -291,7 +291,7 @@ let effect_checking_visitor
|
|||||||
let curr = Stack.pop auth_stack in
|
let curr = Stack.pop auth_stack in
|
||||||
let next =
|
let next =
|
||||||
if Stack.is_empty auth_stack
|
if Stack.is_empty auth_stack
|
||||||
then Ast.PURE
|
then Ast.EFF_pure
|
||||||
else Stack.top auth_stack
|
else Stack.top auth_stack
|
||||||
in
|
in
|
||||||
iflog cx
|
iflog cx
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ type ctxt =
|
|||||||
|
|
||||||
ctxt_rty_cache: (Ast.ty,Il.referent_ty) Hashtbl.t;
|
ctxt_rty_cache: (Ast.ty,Il.referent_ty) Hashtbl.t;
|
||||||
|
|
||||||
ctxt_type_effect_cache: (Ast.ty,Ast.effect) Hashtbl.t;
|
ctxt_type_stratum_cache: (Ast.ty,Ast.stratum) Hashtbl.t;
|
||||||
ctxt_type_points_to_heap_cache: (Ast.ty,bool) Hashtbl.t;
|
ctxt_type_points_to_heap_cache: (Ast.ty,bool) Hashtbl.t;
|
||||||
ctxt_type_is_structured_cache: (Ast.ty,bool) Hashtbl.t;
|
ctxt_type_is_structured_cache: (Ast.ty,bool) Hashtbl.t;
|
||||||
ctxt_type_contains_chan_cache: (Ast.ty,bool) Hashtbl.t;
|
ctxt_type_contains_chan_cache: (Ast.ty,bool) Hashtbl.t;
|
||||||
@@ -296,7 +296,7 @@ let new_ctxt sess abi crate =
|
|||||||
ctxt_curr_path = Stack.create ();
|
ctxt_curr_path = Stack.create ();
|
||||||
|
|
||||||
ctxt_rty_cache = Hashtbl.create 0;
|
ctxt_rty_cache = Hashtbl.create 0;
|
||||||
ctxt_type_effect_cache = Hashtbl.create 0;
|
ctxt_type_stratum_cache = Hashtbl.create 0;
|
||||||
ctxt_type_points_to_heap_cache = Hashtbl.create 0;
|
ctxt_type_points_to_heap_cache = Hashtbl.create 0;
|
||||||
ctxt_type_is_structured_cache = Hashtbl.create 0;
|
ctxt_type_is_structured_cache = Hashtbl.create 0;
|
||||||
ctxt_type_contains_chan_cache = Hashtbl.create 0;
|
ctxt_type_contains_chan_cache = Hashtbl.create 0;
|
||||||
@@ -1227,16 +1227,15 @@ let type_points_to_heap (cx:ctxt) (t:Ast.ty) : bool =
|
|||||||
(fun _ -> fold_ty cx fold t)
|
(fun _ -> fold_ty cx fold t)
|
||||||
;;
|
;;
|
||||||
|
|
||||||
(* Effect analysis. *)
|
|
||||||
|
(* Type qualifier analysis. *)
|
||||||
|
|
||||||
let effect_le x y =
|
let effect_le x y =
|
||||||
match (x,y) with
|
match (x,y) with
|
||||||
(Ast.UNSAFE, _) -> true
|
(Ast.EFF_unsafe, _) -> true
|
||||||
| (Ast.STATE, Ast.PURE) -> true
|
| (Ast.EFF_impure, Ast.EFF_pure) -> true
|
||||||
| (Ast.STATE, Ast.IO) -> true
|
| (Ast.EFF_impure, Ast.EFF_impure) -> true
|
||||||
| (Ast.STATE, Ast.STATE) -> true
|
| (Ast.EFF_pure, Ast.EFF_pure) -> true
|
||||||
| (Ast.IO, Ast.PURE) -> true
|
|
||||||
| (Ast.IO, Ast.IO) -> true
|
|
||||||
| (Ast.PURE, Ast.PURE) -> true
|
|
||||||
| _ -> false
|
| _ -> false
|
||||||
;;
|
;;
|
||||||
|
|
||||||
@@ -1244,16 +1243,30 @@ let lower_effect_of x y =
|
|||||||
if effect_le x y then x else y
|
if effect_le x y then x else y
|
||||||
;;
|
;;
|
||||||
|
|
||||||
let type_effect (cx:ctxt) (t:Ast.ty) : Ast.effect =
|
let stratum_le x y =
|
||||||
let fold_mutable _ = Ast.STATE in
|
match (x,y) with
|
||||||
let fold = associative_binary_op_ty_fold Ast.PURE lower_effect_of in
|
(Ast.STRAT_gc, _) -> true
|
||||||
|
| (Ast.STRAT_state, Ast.STRAT_value) -> true
|
||||||
|
| (Ast.STRAT_state, Ast.STRAT_state) -> true
|
||||||
|
| (Ast.STRAT_value, Ast.STRAT_value) -> true
|
||||||
|
| _ -> false
|
||||||
|
;;
|
||||||
|
|
||||||
|
let lower_stratum_of x y =
|
||||||
|
if stratum_le x y then x else y
|
||||||
|
;;
|
||||||
|
|
||||||
|
let type_stratum (cx:ctxt) (t:Ast.ty) : Ast.stratum =
|
||||||
|
let fold_mutable _ = Ast.STRAT_state in
|
||||||
|
let fold = associative_binary_op_ty_fold Ast.STRAT_value lower_stratum_of in
|
||||||
let fold = { fold with ty_fold_mutable = fold_mutable } in
|
let fold = { fold with ty_fold_mutable = fold_mutable } in
|
||||||
htab_search_or_add cx.ctxt_type_effect_cache t
|
htab_search_or_add cx.ctxt_type_stratum_cache t
|
||||||
(fun _ -> fold_ty cx fold t)
|
(fun _ -> fold_ty cx fold t)
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
|
||||||
let type_has_state (cx:ctxt) (t:Ast.ty) : bool =
|
let type_has_state (cx:ctxt) (t:Ast.ty) : bool =
|
||||||
effect_le (type_effect cx t) Ast.STATE
|
stratum_le (type_stratum cx t) Ast.STRAT_state
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
|
||||||
@@ -1627,7 +1640,7 @@ let ty_of_mod_item (item:Ast.mod_item) : Ast.ty =
|
|||||||
| Ast.MOD_ITEM_mod _ -> bug () "Semant.ty_of_mod_item on mod"
|
| Ast.MOD_ITEM_mod _ -> bug () "Semant.ty_of_mod_item on mod"
|
||||||
| Ast.MOD_ITEM_const (ty, _) -> ty
|
| Ast.MOD_ITEM_const (ty, _) -> ty
|
||||||
| Ast.MOD_ITEM_obj ob ->
|
| Ast.MOD_ITEM_obj ob ->
|
||||||
let taux = { Ast.fn_effect = Ast.PURE;
|
let taux = { Ast.fn_effect = Ast.EFF_pure;
|
||||||
Ast.fn_is_iter = false }
|
Ast.fn_is_iter = false }
|
||||||
in
|
in
|
||||||
let tobj = Ast.TY_obj (ty_obj_of_obj ob) in
|
let tobj = Ast.TY_obj (ty_obj_of_obj ob) in
|
||||||
@@ -1650,7 +1663,7 @@ let ty_of_mod_item (item:Ast.mod_item) : Ast.ty =
|
|||||||
if Array.length hdr = 0
|
if Array.length hdr = 0
|
||||||
then Ast.TY_tag ttag
|
then Ast.TY_tag ttag
|
||||||
else
|
else
|
||||||
let taux = { Ast.fn_effect = Ast.PURE;
|
let taux = { Ast.fn_effect = Ast.EFF_pure;
|
||||||
Ast.fn_is_iter = false }
|
Ast.fn_is_iter = false }
|
||||||
in
|
in
|
||||||
let inputs = Array.map (fun (s, _) -> s.node) hdr in
|
let inputs = Array.map (fun (s, _) -> s.node) hdr in
|
||||||
@@ -2561,7 +2574,7 @@ let mk_ty_fn_or_iter
|
|||||||
(is_iter:bool)
|
(is_iter:bool)
|
||||||
: Ast.ty =
|
: Ast.ty =
|
||||||
(* In some cases we don't care what aux or constrs are. *)
|
(* In some cases we don't care what aux or constrs are. *)
|
||||||
let taux = { Ast.fn_effect = Ast.PURE;
|
let taux = { Ast.fn_effect = Ast.EFF_pure;
|
||||||
Ast.fn_is_iter = is_iter; }
|
Ast.fn_is_iter = is_iter; }
|
||||||
in
|
in
|
||||||
let tsig = { Ast.sig_input_slots = arg_slots;
|
let tsig = { Ast.sig_input_slots = arg_slots;
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ let determine_constr_key
|
|||||||
match Hashtbl.find cx.ctxt_all_item_types cid with
|
match Hashtbl.find cx.ctxt_all_item_types cid with
|
||||||
Ast.TY_fn (_, taux) ->
|
Ast.TY_fn (_, taux) ->
|
||||||
begin
|
begin
|
||||||
if taux.Ast.fn_effect = Ast.PURE
|
if taux.Ast.fn_effect = Ast.EFF_pure
|
||||||
then cid
|
then cid
|
||||||
else err (Some cid) "impure function used in constraint"
|
else err (Some cid) "impure function used in constraint"
|
||||||
end
|
end
|
||||||
@@ -989,6 +989,7 @@ let graph_special_block_structure_building_visitor
|
|||||||
Hashtbl.replace graph cond_id [then_id; else_id];
|
Hashtbl.replace graph cond_id [then_id; else_id];
|
||||||
Hashtbl.replace graph then_end_id succ;
|
Hashtbl.replace graph then_end_id succ;
|
||||||
Hashtbl.replace graph else_end_id succ;
|
Hashtbl.replace graph else_end_id succ;
|
||||||
|
|
||||||
(* Kill residual messed-up block wiring.*)
|
(* Kill residual messed-up block wiring.*)
|
||||||
remove_flow_edges graph then_end_id [then_id];
|
remove_flow_edges graph then_end_id [then_id];
|
||||||
remove_flow_edges graph else_id [then_id];
|
remove_flow_edges graph else_id [then_id];
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import std.util.none;
|
|||||||
import std._str;
|
import std._str;
|
||||||
import std._vec;
|
import std._vec;
|
||||||
|
|
||||||
io fn compile_input(session.session sess, str input, str output) {
|
impure fn compile_input(session.session sess, str input, str output) {
|
||||||
auto p = parser.new_parser(sess, 0, input);
|
auto p = parser.new_parser(sess, 0, input);
|
||||||
auto crate = parser.parse_crate(p);
|
auto crate = parser.parse_crate(p);
|
||||||
crate = resolve.resolve_crate(sess, crate);
|
crate = resolve.resolve_crate(sess, crate);
|
||||||
@@ -36,7 +36,7 @@ fn usage(session.session sess, str argv0) {
|
|||||||
log "";
|
log "";
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn main(vec[str] args) {
|
impure fn main(vec[str] args) {
|
||||||
|
|
||||||
auto sess = session.session();
|
auto sess = session.session();
|
||||||
let option[str] input_file = none[str];
|
let option[str] input_file = none[str];
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ state type reader = state obj {
|
|||||||
fn is_eof() -> bool;
|
fn is_eof() -> bool;
|
||||||
fn curr() -> char;
|
fn curr() -> char;
|
||||||
fn next() -> char;
|
fn next() -> char;
|
||||||
io fn bump();
|
impure fn bump();
|
||||||
fn mark();
|
fn mark();
|
||||||
fn get_filename() -> str;
|
fn get_filename() -> str;
|
||||||
fn get_mark_pos() -> common.pos;
|
fn get_mark_pos() -> common.pos;
|
||||||
@@ -55,7 +55,7 @@ fn new_reader(stdio_reader rdr, str filename) -> reader
|
|||||||
ret n;
|
ret n;
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn bump() {
|
impure fn bump() {
|
||||||
c = n;
|
c = n;
|
||||||
|
|
||||||
if (c == (-1) as char) {
|
if (c == (-1) as char) {
|
||||||
@@ -247,14 +247,14 @@ fn is_whitespace(char c) -> bool {
|
|||||||
ret c == ' ' || c == '\t' || c == '\r' || c == '\n';
|
ret c == ' ' || c == '\t' || c == '\r' || c == '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn consume_any_whitespace(reader rdr) {
|
impure fn consume_any_whitespace(reader rdr) {
|
||||||
while (is_whitespace(rdr.curr())) {
|
while (is_whitespace(rdr.curr())) {
|
||||||
rdr.bump();
|
rdr.bump();
|
||||||
}
|
}
|
||||||
be consume_any_line_comment(rdr);
|
be consume_any_line_comment(rdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn consume_any_line_comment(reader rdr) {
|
impure fn consume_any_line_comment(reader rdr) {
|
||||||
if (rdr.curr() == '/') {
|
if (rdr.curr() == '/') {
|
||||||
alt (rdr.next()) {
|
alt (rdr.next()) {
|
||||||
case ('/') {
|
case ('/') {
|
||||||
@@ -277,7 +277,7 @@ io fn consume_any_line_comment(reader rdr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
io fn consume_block_comment(reader rdr) {
|
impure fn consume_block_comment(reader rdr) {
|
||||||
let int level = 1;
|
let int level = 1;
|
||||||
while (level > 0) {
|
while (level > 0) {
|
||||||
if (rdr.curr() == '/' && rdr.next() == '*') {
|
if (rdr.curr() == '/' && rdr.next() == '*') {
|
||||||
@@ -298,7 +298,7 @@ io fn consume_block_comment(reader rdr) {
|
|||||||
be consume_any_whitespace(rdr);
|
be consume_any_whitespace(rdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn next_token(reader rdr) -> token.token {
|
impure fn next_token(reader rdr) -> token.token {
|
||||||
auto accum_str = "";
|
auto accum_str = "";
|
||||||
auto accum_int = 0;
|
auto accum_int = 0;
|
||||||
|
|
||||||
@@ -359,7 +359,7 @@ io fn next_token(reader rdr) -> token.token {
|
|||||||
ret token.LIT_INT(accum_int);
|
ret token.LIT_INT(accum_int);
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn binop(reader rdr, token.binop op) -> token.token {
|
impure fn binop(reader rdr, token.binop op) -> token.token {
|
||||||
rdr.bump();
|
rdr.bump();
|
||||||
if (rdr.next() == '=') {
|
if (rdr.next() == '=') {
|
||||||
rdr.bump();
|
rdr.bump();
|
||||||
|
|||||||
@@ -13,14 +13,14 @@ import util.common.new_str_hash;
|
|||||||
state type parser =
|
state type parser =
|
||||||
state obj {
|
state obj {
|
||||||
fn peek() -> token.token;
|
fn peek() -> token.token;
|
||||||
io fn bump();
|
impure fn bump();
|
||||||
io fn err(str s);
|
impure fn err(str s);
|
||||||
fn get_session() -> session.session;
|
fn get_session() -> session.session;
|
||||||
fn get_span() -> common.span;
|
fn get_span() -> common.span;
|
||||||
fn next_def_id() -> ast.def_id;
|
fn next_def_id() -> ast.def_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
io fn new_parser(session.session sess,
|
impure fn new_parser(session.session sess,
|
||||||
ast.crate_num crate, str path) -> parser {
|
ast.crate_num crate, str path) -> parser {
|
||||||
state obj stdio_parser(session.session sess,
|
state obj stdio_parser(session.session sess,
|
||||||
mutable token.token tok,
|
mutable token.token tok,
|
||||||
@@ -35,13 +35,13 @@ io fn new_parser(session.session sess,
|
|||||||
ret tok;
|
ret tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn bump() {
|
impure fn bump() {
|
||||||
tok = lexer.next_token(rdr);
|
tok = lexer.next_token(rdr);
|
||||||
lo = rdr.get_mark_pos();
|
lo = rdr.get_mark_pos();
|
||||||
hi = rdr.get_curr_pos();
|
hi = rdr.get_curr_pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn err(str m) {
|
impure fn err(str m) {
|
||||||
auto span = rec(filename = rdr.get_filename(),
|
auto span = rec(filename = rdr.get_filename(),
|
||||||
lo = lo, hi = hi);
|
lo = lo, hi = hi);
|
||||||
sess.span_err(span, m);
|
sess.span_err(span, m);
|
||||||
@@ -68,7 +68,7 @@ io fn new_parser(session.session sess,
|
|||||||
npos, npos, 0, crate, rdr);
|
npos, npos, 0, crate, rdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn expect(parser p, token.token t) {
|
impure fn expect(parser p, token.token t) {
|
||||||
if (p.peek() == t) {
|
if (p.peek() == t) {
|
||||||
p.bump();
|
p.bump();
|
||||||
} else {
|
} else {
|
||||||
@@ -86,7 +86,7 @@ fn spanned[T](&span lo, &span hi, &T node) -> ast.spanned[T] {
|
|||||||
hi=hi.hi));
|
hi=hi.hi));
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_ident(parser p) -> ast.ident {
|
impure fn parse_ident(parser p) -> ast.ident {
|
||||||
alt (p.peek()) {
|
alt (p.peek()) {
|
||||||
case (token.IDENT(?i)) { p.bump(); ret i; }
|
case (token.IDENT(?i)) { p.bump(); ret i; }
|
||||||
case (_) {
|
case (_) {
|
||||||
@@ -96,7 +96,7 @@ io fn parse_ident(parser p) -> ast.ident {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_possibly_mutable_ty(parser p) -> tup(bool, @ast.ty) {
|
impure fn parse_possibly_mutable_ty(parser p) -> tup(bool, @ast.ty) {
|
||||||
auto mut;
|
auto mut;
|
||||||
if (p.peek() == token.MUTABLE) {
|
if (p.peek() == token.MUTABLE) {
|
||||||
p.bump();
|
p.bump();
|
||||||
@@ -108,7 +108,7 @@ io fn parse_possibly_mutable_ty(parser p) -> tup(bool, @ast.ty) {
|
|||||||
ret tup(mut, parse_ty(p));
|
ret tup(mut, parse_ty(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_ty(parser p) -> @ast.ty {
|
impure fn parse_ty(parser p) -> @ast.ty {
|
||||||
auto lo = p.get_span();
|
auto lo = p.get_span();
|
||||||
let ast.ty_ t;
|
let ast.ty_ t;
|
||||||
alt (p.peek()) {
|
alt (p.peek()) {
|
||||||
@@ -144,7 +144,7 @@ io fn parse_ty(parser p) -> @ast.ty {
|
|||||||
ret @spanned(lo, lo, t);
|
ret @spanned(lo, lo, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_arg(parser p) -> ast.arg {
|
impure fn parse_arg(parser p) -> ast.arg {
|
||||||
let ast.mode m = ast.val;
|
let ast.mode m = ast.val;
|
||||||
if (p.peek() == token.BINOP(token.AND)) {
|
if (p.peek() == token.BINOP(token.AND)) {
|
||||||
m = ast.alias;
|
m = ast.alias;
|
||||||
@@ -155,10 +155,10 @@ io fn parse_arg(parser p) -> ast.arg {
|
|||||||
ret rec(mode=m, ty=t, ident=i, id=p.next_def_id());
|
ret rec(mode=m, ty=t, ident=i, id=p.next_def_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_seq[T](token.token bra,
|
impure fn parse_seq[T](token.token bra,
|
||||||
token.token ket,
|
token.token ket,
|
||||||
option[token.token] sep,
|
option[token.token] sep,
|
||||||
(io fn(parser) -> T) f,
|
(impure fn(parser) -> T) f,
|
||||||
parser p) -> util.common.spanned[vec[T]] {
|
parser p) -> util.common.spanned[vec[T]] {
|
||||||
let bool first = true;
|
let bool first = true;
|
||||||
auto lo = p.get_span();
|
auto lo = p.get_span();
|
||||||
@@ -185,7 +185,7 @@ io fn parse_seq[T](token.token bra,
|
|||||||
ret spanned(lo, hi, v);
|
ret spanned(lo, hi, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_lit(parser p) -> option[ast.lit] {
|
impure fn parse_lit(parser p) -> option[ast.lit] {
|
||||||
auto lo = p.get_span();
|
auto lo = p.get_span();
|
||||||
let ast.lit_ lit;
|
let ast.lit_ lit;
|
||||||
alt (p.peek()) {
|
alt (p.peek()) {
|
||||||
@@ -217,7 +217,7 @@ io fn parse_lit(parser p) -> option[ast.lit] {
|
|||||||
ret some(spanned(lo, lo, lit));
|
ret some(spanned(lo, lo, lit));
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_name(parser p, ast.ident id) -> ast.name {
|
impure fn parse_name(parser p, ast.ident id) -> ast.name {
|
||||||
|
|
||||||
auto lo = p.get_span();
|
auto lo = p.get_span();
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ io fn parse_name(parser p, ast.ident id) -> ast.name {
|
|||||||
ret spanned(lo, tys.span, rec(ident=id, types=tys.node));
|
ret spanned(lo, tys.span, rec(ident=id, types=tys.node));
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_possibly_mutable_expr(parser p) -> tup(bool, @ast.expr) {
|
impure fn parse_possibly_mutable_expr(parser p) -> tup(bool, @ast.expr) {
|
||||||
auto mut;
|
auto mut;
|
||||||
if (p.peek() == token.MUTABLE) {
|
if (p.peek() == token.MUTABLE) {
|
||||||
p.bump();
|
p.bump();
|
||||||
@@ -252,7 +252,7 @@ io fn parse_possibly_mutable_expr(parser p) -> tup(bool, @ast.expr) {
|
|||||||
ret tup(mut, parse_expr(p));
|
ret tup(mut, parse_expr(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_bottom_expr(parser p) -> @ast.expr {
|
impure fn parse_bottom_expr(parser p) -> @ast.expr {
|
||||||
|
|
||||||
auto lo = p.get_span();
|
auto lo = p.get_span();
|
||||||
auto hi = lo;
|
auto hi = lo;
|
||||||
@@ -315,7 +315,7 @@ io fn parse_bottom_expr(parser p) -> @ast.expr {
|
|||||||
|
|
||||||
case (token.REC) {
|
case (token.REC) {
|
||||||
p.bump();
|
p.bump();
|
||||||
io fn parse_entry(parser p) ->
|
impure fn parse_entry(parser p) ->
|
||||||
tup(ast.ident, @ast.expr) {
|
tup(ast.ident, @ast.expr) {
|
||||||
auto i = parse_ident(p);
|
auto i = parse_ident(p);
|
||||||
expect(p, token.EQ);
|
expect(p, token.EQ);
|
||||||
@@ -348,7 +348,7 @@ io fn parse_bottom_expr(parser p) -> @ast.expr {
|
|||||||
ret @spanned(lo, hi, ex);
|
ret @spanned(lo, hi, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_path_expr(parser p) -> @ast.expr {
|
impure fn parse_path_expr(parser p) -> @ast.expr {
|
||||||
auto lo = p.get_span();
|
auto lo = p.get_span();
|
||||||
auto e = parse_bottom_expr(p);
|
auto e = parse_bottom_expr(p);
|
||||||
auto hi = e.span;
|
auto hi = e.span;
|
||||||
@@ -381,7 +381,7 @@ io fn parse_path_expr(parser p) -> @ast.expr {
|
|||||||
ret e;
|
ret e;
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_prefix_expr(parser p) -> @ast.expr {
|
impure fn parse_prefix_expr(parser p) -> @ast.expr {
|
||||||
|
|
||||||
auto lo = p.get_span();
|
auto lo = p.get_span();
|
||||||
auto hi = lo;
|
auto hi = lo;
|
||||||
@@ -443,8 +443,8 @@ io fn parse_prefix_expr(parser p) -> @ast.expr {
|
|||||||
ret @spanned(lo, hi, ex);
|
ret @spanned(lo, hi, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_binops(parser p,
|
impure fn parse_binops(parser p,
|
||||||
(io fn(parser) -> @ast.expr) sub,
|
(impure fn(parser) -> @ast.expr) sub,
|
||||||
vec[tup(token.binop, ast.binop)] ops)
|
vec[tup(token.binop, ast.binop)] ops)
|
||||||
-> @ast.expr {
|
-> @ast.expr {
|
||||||
auto lo = p.get_span();
|
auto lo = p.get_span();
|
||||||
@@ -472,8 +472,8 @@ io fn parse_binops(parser p,
|
|||||||
ret e;
|
ret e;
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_binary_exprs(parser p,
|
impure fn parse_binary_exprs(parser p,
|
||||||
(io fn(parser) -> @ast.expr) sub,
|
(impure fn(parser) -> @ast.expr) sub,
|
||||||
vec[tup(token.token, ast.binop)] ops)
|
vec[tup(token.token, ast.binop)] ops)
|
||||||
-> @ast.expr {
|
-> @ast.expr {
|
||||||
auto lo = p.get_span();
|
auto lo = p.get_span();
|
||||||
@@ -496,42 +496,42 @@ io fn parse_binary_exprs(parser p,
|
|||||||
ret e;
|
ret e;
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_factor_expr(parser p) -> @ast.expr {
|
impure fn parse_factor_expr(parser p) -> @ast.expr {
|
||||||
auto sub = parse_prefix_expr;
|
auto sub = parse_prefix_expr;
|
||||||
ret parse_binops(p, sub, vec(tup(token.STAR, ast.mul),
|
ret parse_binops(p, sub, vec(tup(token.STAR, ast.mul),
|
||||||
tup(token.SLASH, ast.div),
|
tup(token.SLASH, ast.div),
|
||||||
tup(token.PERCENT, ast.rem)));
|
tup(token.PERCENT, ast.rem)));
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_term_expr(parser p) -> @ast.expr {
|
impure fn parse_term_expr(parser p) -> @ast.expr {
|
||||||
auto sub = parse_factor_expr;
|
auto sub = parse_factor_expr;
|
||||||
ret parse_binops(p, sub, vec(tup(token.PLUS, ast.add),
|
ret parse_binops(p, sub, vec(tup(token.PLUS, ast.add),
|
||||||
tup(token.MINUS, ast.sub)));
|
tup(token.MINUS, ast.sub)));
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_shift_expr(parser p) -> @ast.expr {
|
impure fn parse_shift_expr(parser p) -> @ast.expr {
|
||||||
auto sub = parse_term_expr;
|
auto sub = parse_term_expr;
|
||||||
ret parse_binops(p, sub, vec(tup(token.LSL, ast.lsl),
|
ret parse_binops(p, sub, vec(tup(token.LSL, ast.lsl),
|
||||||
tup(token.LSR, ast.lsr),
|
tup(token.LSR, ast.lsr),
|
||||||
tup(token.ASR, ast.asr)));
|
tup(token.ASR, ast.asr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_bitand_expr(parser p) -> @ast.expr {
|
impure fn parse_bitand_expr(parser p) -> @ast.expr {
|
||||||
auto sub = parse_shift_expr;
|
auto sub = parse_shift_expr;
|
||||||
ret parse_binops(p, sub, vec(tup(token.AND, ast.bitand)));
|
ret parse_binops(p, sub, vec(tup(token.AND, ast.bitand)));
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_bitxor_expr(parser p) -> @ast.expr {
|
impure fn parse_bitxor_expr(parser p) -> @ast.expr {
|
||||||
auto sub = parse_bitand_expr;
|
auto sub = parse_bitand_expr;
|
||||||
ret parse_binops(p, sub, vec(tup(token.CARET, ast.bitxor)));
|
ret parse_binops(p, sub, vec(tup(token.CARET, ast.bitxor)));
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_bitor_expr(parser p) -> @ast.expr {
|
impure fn parse_bitor_expr(parser p) -> @ast.expr {
|
||||||
auto sub = parse_bitxor_expr;
|
auto sub = parse_bitxor_expr;
|
||||||
ret parse_binops(p, sub, vec(tup(token.OR, ast.bitor)));
|
ret parse_binops(p, sub, vec(tup(token.OR, ast.bitor)));
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_cast_expr(parser p) -> @ast.expr {
|
impure fn parse_cast_expr(parser p) -> @ast.expr {
|
||||||
auto lo = p.get_span();
|
auto lo = p.get_span();
|
||||||
auto e = parse_bitor_expr(p);
|
auto e = parse_bitor_expr(p);
|
||||||
auto hi = e.span;
|
auto hi = e.span;
|
||||||
@@ -552,7 +552,7 @@ io fn parse_cast_expr(parser p) -> @ast.expr {
|
|||||||
ret e;
|
ret e;
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_relational_expr(parser p) -> @ast.expr {
|
impure fn parse_relational_expr(parser p) -> @ast.expr {
|
||||||
auto sub = parse_cast_expr;
|
auto sub = parse_cast_expr;
|
||||||
ret parse_binary_exprs(p, sub, vec(tup(token.LT, ast.lt),
|
ret parse_binary_exprs(p, sub, vec(tup(token.LT, ast.lt),
|
||||||
tup(token.LE, ast.le),
|
tup(token.LE, ast.le),
|
||||||
@@ -561,23 +561,23 @@ io fn parse_relational_expr(parser p) -> @ast.expr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
io fn parse_equality_expr(parser p) -> @ast.expr {
|
impure fn parse_equality_expr(parser p) -> @ast.expr {
|
||||||
auto sub = parse_relational_expr;
|
auto sub = parse_relational_expr;
|
||||||
ret parse_binary_exprs(p, sub, vec(tup(token.EQEQ, ast.eq),
|
ret parse_binary_exprs(p, sub, vec(tup(token.EQEQ, ast.eq),
|
||||||
tup(token.NE, ast.ne)));
|
tup(token.NE, ast.ne)));
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_and_expr(parser p) -> @ast.expr {
|
impure fn parse_and_expr(parser p) -> @ast.expr {
|
||||||
auto sub = parse_equality_expr;
|
auto sub = parse_equality_expr;
|
||||||
ret parse_binary_exprs(p, sub, vec(tup(token.ANDAND, ast.and)));
|
ret parse_binary_exprs(p, sub, vec(tup(token.ANDAND, ast.and)));
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_or_expr(parser p) -> @ast.expr {
|
impure fn parse_or_expr(parser p) -> @ast.expr {
|
||||||
auto sub = parse_and_expr;
|
auto sub = parse_and_expr;
|
||||||
ret parse_binary_exprs(p, sub, vec(tup(token.OROR, ast.or)));
|
ret parse_binary_exprs(p, sub, vec(tup(token.OROR, ast.or)));
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_assign_expr(parser p) -> @ast.expr {
|
impure fn parse_assign_expr(parser p) -> @ast.expr {
|
||||||
auto lo = p.get_span();
|
auto lo = p.get_span();
|
||||||
auto lhs = parse_or_expr(p);
|
auto lhs = parse_or_expr(p);
|
||||||
alt (p.peek()) {
|
alt (p.peek()) {
|
||||||
@@ -591,7 +591,7 @@ io fn parse_assign_expr(parser p) -> @ast.expr {
|
|||||||
ret lhs;
|
ret lhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_if_expr(parser p) -> @ast.expr {
|
impure fn parse_if_expr(parser p) -> @ast.expr {
|
||||||
auto lo = p.get_span();
|
auto lo = p.get_span();
|
||||||
auto hi = lo;
|
auto hi = lo;
|
||||||
|
|
||||||
@@ -613,7 +613,7 @@ io fn parse_if_expr(parser p) -> @ast.expr {
|
|||||||
ret @spanned(lo, hi, ast.expr_if(cond, thn, els, none[@ast.ty]));
|
ret @spanned(lo, hi, ast.expr_if(cond, thn, els, none[@ast.ty]));
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_expr(parser p) -> @ast.expr {
|
impure fn parse_expr(parser p) -> @ast.expr {
|
||||||
alt (p.peek()) {
|
alt (p.peek()) {
|
||||||
case (token.LBRACE) {
|
case (token.LBRACE) {
|
||||||
auto blk = parse_block(p);
|
auto blk = parse_block(p);
|
||||||
@@ -630,7 +630,7 @@ io fn parse_expr(parser p) -> @ast.expr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_initializer(parser p) -> option[@ast.expr] {
|
impure fn parse_initializer(parser p) -> option[@ast.expr] {
|
||||||
if (p.peek() == token.EQ) {
|
if (p.peek() == token.EQ) {
|
||||||
p.bump();
|
p.bump();
|
||||||
ret some(parse_expr(p));
|
ret some(parse_expr(p));
|
||||||
@@ -639,7 +639,7 @@ io fn parse_initializer(parser p) -> option[@ast.expr] {
|
|||||||
ret none[@ast.expr];
|
ret none[@ast.expr];
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_let(parser p) -> @ast.decl {
|
impure fn parse_let(parser p) -> @ast.decl {
|
||||||
auto lo = p.get_span();
|
auto lo = p.get_span();
|
||||||
|
|
||||||
expect(p, token.LET);
|
expect(p, token.LET);
|
||||||
@@ -659,7 +659,7 @@ io fn parse_let(parser p) -> @ast.decl {
|
|||||||
ret @spanned(lo, hi, ast.decl_local(@local));
|
ret @spanned(lo, hi, ast.decl_local(@local));
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_auto(parser p) -> @ast.decl {
|
impure fn parse_auto(parser p) -> @ast.decl {
|
||||||
auto lo = p.get_span();
|
auto lo = p.get_span();
|
||||||
|
|
||||||
expect(p, token.AUTO);
|
expect(p, token.AUTO);
|
||||||
@@ -678,7 +678,7 @@ io fn parse_auto(parser p) -> @ast.decl {
|
|||||||
ret @spanned(lo, hi, ast.decl_local(@local));
|
ret @spanned(lo, hi, ast.decl_local(@local));
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_stmt(parser p) -> @ast.stmt {
|
impure fn parse_stmt(parser p) -> @ast.stmt {
|
||||||
auto lo = p.get_span();
|
auto lo = p.get_span();
|
||||||
alt (p.peek()) {
|
alt (p.peek()) {
|
||||||
|
|
||||||
@@ -760,7 +760,7 @@ io fn parse_stmt(parser p) -> @ast.stmt {
|
|||||||
fail;
|
fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_block(parser p) -> ast.block {
|
impure fn parse_block(parser p) -> ast.block {
|
||||||
auto f = parse_stmt;
|
auto f = parse_stmt;
|
||||||
// FIXME: passing parse_stmt as an lval doesn't work at the moment.
|
// FIXME: passing parse_stmt as an lval doesn't work at the moment.
|
||||||
auto stmts = parse_seq[@ast.stmt](token.LBRACE,
|
auto stmts = parse_seq[@ast.stmt](token.LBRACE,
|
||||||
@@ -800,7 +800,7 @@ io fn parse_block(parser p) -> ast.block {
|
|||||||
ret spanned(stmts.span, stmts.span, b);
|
ret spanned(stmts.span, stmts.span, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_fn(parser p) -> tup(ast.ident, @ast.item) {
|
impure fn parse_fn(parser p) -> tup(ast.ident, @ast.item) {
|
||||||
auto lo = p.get_span();
|
auto lo = p.get_span();
|
||||||
expect(p, token.FN);
|
expect(p, token.FN);
|
||||||
auto id = parse_ident(p);
|
auto id = parse_ident(p);
|
||||||
@@ -832,7 +832,7 @@ io fn parse_fn(parser p) -> tup(ast.ident, @ast.item) {
|
|||||||
ret tup(id, @spanned(lo, body.span, item));
|
ret tup(id, @spanned(lo, body.span, item));
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_mod_items(parser p, token.token term) -> ast._mod {
|
impure fn parse_mod_items(parser p, token.token term) -> ast._mod {
|
||||||
let vec[@ast.item] items = vec();
|
let vec[@ast.item] items = vec();
|
||||||
let hashmap[ast.ident,uint] index = new_str_hash[uint]();
|
let hashmap[ast.ident,uint] index = new_str_hash[uint]();
|
||||||
let uint u = 0u;
|
let uint u = 0u;
|
||||||
@@ -845,7 +845,7 @@ io fn parse_mod_items(parser p, token.token term) -> ast._mod {
|
|||||||
ret rec(items=items, index=index);
|
ret rec(items=items, index=index);
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_mod(parser p) -> tup(ast.ident, @ast.item) {
|
impure fn parse_mod(parser p) -> tup(ast.ident, @ast.item) {
|
||||||
auto lo = p.get_span();
|
auto lo = p.get_span();
|
||||||
expect(p, token.MOD);
|
expect(p, token.MOD);
|
||||||
auto id = parse_ident(p);
|
auto id = parse_ident(p);
|
||||||
@@ -857,7 +857,7 @@ io fn parse_mod(parser p) -> tup(ast.ident, @ast.item) {
|
|||||||
ret tup(id, @spanned(lo, hi, item));
|
ret tup(id, @spanned(lo, hi, item));
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_item(parser p) -> tup(ast.ident, @ast.item) {
|
impure fn parse_item(parser p) -> tup(ast.ident, @ast.item) {
|
||||||
alt (p.peek()) {
|
alt (p.peek()) {
|
||||||
case (token.FN) {
|
case (token.FN) {
|
||||||
ret parse_fn(p);
|
ret parse_fn(p);
|
||||||
@@ -870,7 +870,7 @@ io fn parse_item(parser p) -> tup(ast.ident, @ast.item) {
|
|||||||
fail;
|
fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn parse_crate(parser p) -> @ast.crate {
|
impure fn parse_crate(parser p) -> @ast.crate {
|
||||||
auto lo = p.get_span();
|
auto lo = p.get_span();
|
||||||
auto hi = lo;
|
auto hi = lo;
|
||||||
auto m = parse_mod_items(p, token.EOF);
|
auto m = parse_mod_items(p, token.EOF);
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ mod util {
|
|||||||
mod common;
|
mod common;
|
||||||
}
|
}
|
||||||
|
|
||||||
auth driver.rustc.main = state;
|
auth driver.rustc.main = impure;
|
||||||
auth middle.trans = unsafe;
|
auth middle.trans = unsafe;
|
||||||
auth lib.llvm = unsafe;
|
auth lib.llvm = unsafe;
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import std._vec;
|
|||||||
type hashfn[K] = fn(&K) -> uint;
|
type hashfn[K] = fn(&K) -> uint;
|
||||||
type eqfn[K] = fn(&K, &K) -> bool;
|
type eqfn[K] = fn(&K, &K) -> bool;
|
||||||
|
|
||||||
state type hashmap[K, V] = state obj {
|
abs state type hashmap[K, V] = state obj {
|
||||||
fn size() -> uint;
|
fn size() -> uint;
|
||||||
fn insert(&K key, &V val) -> bool;
|
fn insert(&K key, &V val) -> bool;
|
||||||
fn contains_key(&K key) -> bool;
|
fn contains_key(&K key) -> bool;
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ native "rust" mod rustrt {
|
|||||||
export size_of;
|
export size_of;
|
||||||
export align_of;
|
export align_of;
|
||||||
export refcount;
|
export refcount;
|
||||||
export gc;
|
export do_gc;
|
||||||
|
|
||||||
fn last_os_error() -> str;
|
fn last_os_error() -> str;
|
||||||
fn size_of[T]() -> uint;
|
fn size_of[T]() -> uint;
|
||||||
fn align_of[T]() -> uint;
|
fn align_of[T]() -> uint;
|
||||||
fn refcount[T](@T t) -> uint;
|
fn refcount[T](@T t) -> uint;
|
||||||
fn gc();
|
fn do_gc();
|
||||||
fn unsupervise();
|
fn unsupervise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ refcount(rust_task *task, type_desc *t, size_t *v) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" CDECL void
|
extern "C" CDECL void
|
||||||
gc(rust_task *task) {
|
do_gc(rust_task *task) {
|
||||||
task->gc(1);
|
task->gc(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// error-pattern: calculated effect is 'io'
|
// error-pattern: calculated effect is 'impure'
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let chan[int] c = chan();
|
let chan[int] c = chan();
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
fn f(int a, int b) : lt(a,b) {
|
fn f(int a, int b) : lt(a,b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn lt(int a, int b) -> bool {
|
impure fn lt(int a, int b) -> bool {
|
||||||
let port[int] p = port();
|
let port[int] p = port();
|
||||||
let chan[int] c = chan(p);
|
let chan[int] c = chan(p);
|
||||||
c <| 10;
|
c <| 10;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// error-pattern: calculated effect is 'io'
|
// error-pattern: calculated effect is 'impure'
|
||||||
|
|
||||||
io fn foo() {
|
impure fn foo() {
|
||||||
let chan[int] c = chan();
|
let chan[int] c = chan();
|
||||||
c <| 10;
|
c <| 10;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// error-pattern: calculated effect is ''
|
// error-pattern: calculated effect is ''
|
||||||
io fn main() {
|
impure fn main() {
|
||||||
log "hi";
|
log "hi";
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,7 @@ fn child() {
|
|||||||
check (1 == 2);
|
check (1 == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn main() {
|
impure fn main() {
|
||||||
let port[int] p = port();
|
let port[int] p = port();
|
||||||
spawn child();
|
spawn child();
|
||||||
let int x;
|
let int x;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// -*- rust -*-
|
// -*- rust -*-
|
||||||
|
|
||||||
io fn f(chan[int] c)
|
impure fn f(chan[int] c)
|
||||||
{
|
{
|
||||||
type t = tup(int,int,int);
|
type t = tup(int,int,int);
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ io fn f(chan[int] c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
io fn main() {
|
impure fn main() {
|
||||||
let port[int] p = port();
|
let port[int] p = port();
|
||||||
spawn f(chan(p));
|
spawn f(chan(p));
|
||||||
let int i;
|
let int i;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
// -*- rust -*-
|
// -*- rust -*-
|
||||||
|
|
||||||
io fn a(chan[int] c) {
|
impure fn a(chan[int] c) {
|
||||||
c <| 10;
|
c <| 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn main() {
|
impure fn main() {
|
||||||
let port[int] p = port();
|
let port[int] p = port();
|
||||||
spawn a(chan(p));
|
spawn a(chan(p));
|
||||||
spawn b(chan(p));
|
spawn b(chan(p));
|
||||||
@@ -14,7 +14,7 @@ io fn main() {
|
|||||||
// log "Finished.";
|
// log "Finished.";
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn b(chan[int] c) {
|
impure fn b(chan[int] c) {
|
||||||
// log "task b0";
|
// log "task b0";
|
||||||
// log "task b1";
|
// log "task b1";
|
||||||
// log "task b2";
|
// log "task b2";
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
// -*- rust -*-
|
// -*- rust -*-
|
||||||
|
|
||||||
io fn a(chan[int] c) {
|
impure fn a(chan[int] c) {
|
||||||
log "task a0";
|
log "task a0";
|
||||||
log "task a1";
|
log "task a1";
|
||||||
c <| 10;
|
c <| 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn main() {
|
impure fn main() {
|
||||||
let port[int] p = port();
|
let port[int] p = port();
|
||||||
spawn a(chan(p));
|
spawn a(chan(p));
|
||||||
spawn b(chan(p));
|
spawn b(chan(p));
|
||||||
@@ -16,7 +16,7 @@ io fn main() {
|
|||||||
log "Finished.";
|
log "Finished.";
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn b(chan[int] c) {
|
impure fn b(chan[int] c) {
|
||||||
log "task b0";
|
log "task b0";
|
||||||
log "task b1";
|
log "task b1";
|
||||||
log "task b2";
|
log "task b2";
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// -*- rust -*-
|
// -*- rust -*-
|
||||||
|
|
||||||
io fn a(chan[int] c) {
|
impure fn a(chan[int] c) {
|
||||||
if (true) {
|
if (true) {
|
||||||
log "task a";
|
log "task a";
|
||||||
log "task a";
|
log "task a";
|
||||||
@@ -22,7 +22,7 @@ fn g(int x, str y) -> int {
|
|||||||
ret z;
|
ret z;
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn main() {
|
impure fn main() {
|
||||||
let int n = 2 + 3 * 7;
|
let int n = 2 + 3 * 7;
|
||||||
let str s = "hello there";
|
let str s = "hello there";
|
||||||
let port[int] p = port();
|
let port[int] p = port();
|
||||||
@@ -37,7 +37,7 @@ io fn main() {
|
|||||||
log "children finished, root finishing";
|
log "children finished, root finishing";
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn b(chan[int] c) {
|
impure fn b(chan[int] c) {
|
||||||
if (true) {
|
if (true) {
|
||||||
log "task b";
|
log "task b";
|
||||||
log "task b";
|
log "task b";
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// -*- rust -*-
|
// -*- rust -*-
|
||||||
|
|
||||||
io fn main() {
|
impure fn main() {
|
||||||
let port[int] p = port();
|
let port[int] p = port();
|
||||||
spawn child(chan(p));
|
spawn child(chan(p));
|
||||||
let int y;
|
let int y;
|
||||||
@@ -10,7 +10,7 @@ io fn main() {
|
|||||||
check (y == 10);
|
check (y == 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn child(chan[int] c) {
|
impure fn child(chan[int] c) {
|
||||||
c <| 10;
|
c <| 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// -*- rust -*-
|
// -*- rust -*-
|
||||||
|
|
||||||
io fn main() {
|
impure fn main() {
|
||||||
let port[int] p = port();
|
let port[int] p = port();
|
||||||
auto c = chan(p);
|
auto c = chan(p);
|
||||||
let int y;
|
let int y;
|
||||||
@@ -18,6 +18,6 @@ io fn main() {
|
|||||||
check (y == 10);
|
check (y == 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn child(chan[int] c) {
|
impure fn child(chan[int] c) {
|
||||||
c <| 10;
|
c <| 10;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -347,5 +347,5 @@ fn main() {
|
|||||||
test_growth();
|
test_growth();
|
||||||
test_removal();
|
test_removal();
|
||||||
|
|
||||||
std.sys.rustrt.gc();
|
std.sys.rustrt.do_gc();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ obj worker(chan[int] c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn do_work(chan[int] c) {
|
impure fn do_work(chan[int] c) {
|
||||||
log "in child task";
|
log "in child task";
|
||||||
{
|
{
|
||||||
let worker w = worker(c);
|
let worker w = worker(c);
|
||||||
@@ -20,7 +20,7 @@ io fn do_work(chan[int] c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn main() {
|
impure fn main() {
|
||||||
let port[int] p = port();
|
let port[int] p = port();
|
||||||
log "spawning worker";
|
log "spawning worker";
|
||||||
auto w = spawn do_work(chan(p));
|
auto w = spawn do_work(chan(p));
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// This checks that preemption works.
|
// This checks that preemption works.
|
||||||
|
|
||||||
io fn starve_main(chan[int] alive) {
|
impure fn starve_main(chan[int] alive) {
|
||||||
log "signalling main";
|
log "signalling main";
|
||||||
alive <| 1;
|
alive <| 1;
|
||||||
log "starving main";
|
log "starving main";
|
||||||
@@ -10,7 +10,7 @@ io fn starve_main(chan[int] alive) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn main() {
|
impure fn main() {
|
||||||
let port[int] alive = port();
|
let port[int] alive = port();
|
||||||
log "main started";
|
log "main started";
|
||||||
let task s = spawn starve_main(chan(alive));
|
let task s = spawn starve_main(chan(alive));
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
io fn main() -> () {
|
impure fn main() -> () {
|
||||||
test05();
|
test05();
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn test05_start(chan[int] ch) {
|
impure fn test05_start(chan[int] ch) {
|
||||||
ch <| 10;
|
ch <| 10;
|
||||||
ch <| 20;
|
ch <| 20;
|
||||||
ch <| 30;
|
ch <| 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn test05() {
|
impure fn test05() {
|
||||||
let port[int] po = port();
|
let port[int] po = port();
|
||||||
let chan[int] ch = chan(po);
|
let chan[int] ch = chan(po);
|
||||||
spawn test05_start(chan(po));
|
spawn test05_start(chan(po));
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
io fn start(chan[chan[str]] c) {
|
impure fn start(chan[chan[str]] c) {
|
||||||
let port[str] p = port();
|
let port[str] p = port();
|
||||||
c <| chan(p);
|
c <| chan(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn main() {
|
impure fn main() {
|
||||||
let port[chan[str]] p = port();
|
let port[chan[str]] p = port();
|
||||||
auto child = spawn "child" start(chan(p));
|
auto child = spawn "child" start(chan(p));
|
||||||
auto c <- p;
|
auto c <- p;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std;
|
use std;
|
||||||
import std._task;
|
import std._task;
|
||||||
|
|
||||||
io fn start(chan[int] c, int start, int number_of_messages) {
|
impure fn start(chan[int] c, int start, int number_of_messages) {
|
||||||
let int i = 0;
|
let int i = 0;
|
||||||
while (i < number_of_messages) {
|
while (i < number_of_messages) {
|
||||||
c <| start + i;
|
c <| start + i;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std;
|
use std;
|
||||||
import std._task;
|
import std._task;
|
||||||
|
|
||||||
io fn start(chan[int] c, int start, int number_of_messages) {
|
impure fn start(chan[int] c, int start, int number_of_messages) {
|
||||||
let int i = 0;
|
let int i = 0;
|
||||||
while (i < number_of_messages) {
|
while (i < number_of_messages) {
|
||||||
c <| start + i;
|
c <| start + i;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
io fn main() -> () {
|
impure fn main() -> () {
|
||||||
test00();
|
test00();
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn test00() {
|
impure fn test00() {
|
||||||
let int r = 0;
|
let int r = 0;
|
||||||
let int sum = 0;
|
let int sum = 0;
|
||||||
let port[int] p = port();
|
let port[int] p = port();
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
io fn main() -> () {
|
impure fn main() -> () {
|
||||||
test00();
|
test00();
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn test00() {
|
impure fn test00() {
|
||||||
let int r = 0;
|
let int r = 0;
|
||||||
let int sum = 0;
|
let int sum = 0;
|
||||||
let port[int] p = port();
|
let port[int] p = port();
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
io fn main() -> () {
|
impure fn main() -> () {
|
||||||
test00();
|
test00();
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn test00() {
|
impure fn test00() {
|
||||||
let int r = 0;
|
let int r = 0;
|
||||||
let int sum = 0;
|
let int sum = 0;
|
||||||
let port[int] p = port();
|
let port[int] p = port();
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
io fn main() -> () {
|
impure fn main() -> () {
|
||||||
test00();
|
test00();
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn test00_start(chan[int] c, int start, int number_of_messages) {
|
impure fn test00_start(chan[int] c, int start, int number_of_messages) {
|
||||||
let int i = 0;
|
let int i = 0;
|
||||||
while (i < number_of_messages) {
|
while (i < number_of_messages) {
|
||||||
c <| start + i;
|
c <| start + i;
|
||||||
@@ -10,7 +10,7 @@ io fn test00_start(chan[int] c, int start, int number_of_messages) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
io fn test00() {
|
impure fn test00() {
|
||||||
let int r = 0;
|
let int r = 0;
|
||||||
let int sum = 0;
|
let int sum = 0;
|
||||||
let port[int] p = port();
|
let port[int] p = port();
|
||||||
|
|||||||
Reference in New Issue
Block a user