Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 9 additions & 13 deletions design/Syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ Productions marked * probably deferred to later versions.
```
<typ> ::= type expressions
<id> <typ-args>? constructor
actor? { <typ-field>;* } object
(shared|actor)? { <typ-field>;* } object
[ var? <typ> ] array
<typ> ? option
<class>? <typ-params>? <typ> -> <typ> function
(shared|class)? <typ-params>? <typ> -> <typ> function
async <typ> future
like <typ> structural expansion
( ((<id> :)? <typ>),* ) tuple
Expand Down Expand Up @@ -43,10 +43,6 @@ Productions marked * probably deferred to later versions.

## Expressions
```
<sort> ::=
new
actor

<exp> ::=
<id> variable
<lit> literal
Expand All @@ -55,7 +51,6 @@ Productions marked * probably deferred to later versions.
( <exp>,* ) tuple
<exp> . <nat> tuple projection
<exp> ? option injection
<sort> <id>? { <exp-field>;* } object
<exp> . <id> object projection
<exp> := <exp> assignment
<unop>= <exp> unary update
Expand Down Expand Up @@ -113,12 +108,13 @@ Productions marked * probably deferred to later versions.
## Declarations
```
<dec> ::= declaration
<exp> expression
let <pat> = <exp> immutable
var <id> (: <typ>)? = <exp> mutable
func <id>? <typ-params>? <pat> (: <typ>)? = <exp> function
type <id> <typ-params>? = <typ> type
actor? class <id> <typ-params>? <pat> (: <typ>)? = <exp> class
<exp> expression
let <pat> = <exp> immutable
var <id> (: <typ>)? = <exp> mutable
(new|object|actor|shared) <id>? =? { <exp-field>;* } object
shared? func <id>? <typ-params>? <pat> (: <typ>)? =? <exp> function
type <id> <typ-params>? = <typ> type
actor? class <id> <typ-params>? <pat> (: <typ>)? =? <exp> class
```

## Programs
Expand Down
1 change: 1 addition & 0 deletions src/lexer.mll
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ rule token mode = parse
| "new" { NEW }
| "not" { NOT }
| "null" { NULL }
| "object" { OBJECT }
| "or" { OR }
| "let" { LET }
| "loop" { LOOP }
Expand Down
44 changes: 28 additions & 16 deletions src/parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ let share_typfield tf =
let share_dec d =
match d.it with
| FuncD ({it = Type.Local; _} as s, x, tbs, p, t, e) ->
FuncD ({s with it = Type.Sharable}, x, tbs, p, t, e) @? d.at
FuncD ({s with it = Type.Sharable}, x, tbs, p, t, e) @? d.at
| _ -> d

let share_exp e =
Expand All @@ -89,7 +89,7 @@ let share_expfield (ef : exp_field) =
%token AWAIT ASYNC BREAK CASE CONTINUE LABEL
%token IF IN IS ELSE SWITCH LOOP WHILE FOR LIKE RETURN
%token ARROW ASSIGN
%token FUNC TYPE ACTOR CLASS PRIVATE NEW SHARED
%token FUNC TYPE OBJECT ACTOR CLASS PRIVATE NEW SHARED
%token SEMICOLON SEMICOLON_EOL COMMA COLON SUB DOT QUEST
%token AND OR NOT
%token ASSERT
Expand Down Expand Up @@ -167,6 +167,7 @@ seplist1(X, SEP) :

%inline obj_sort :
| NEW { Type.Object Type.Local @@ at $sloc }
| OBJECT { Type.Object Type.Local @@ at $sloc }
| SHARED { Type.Object Type.Sharable @@ at $sloc }
| ACTOR { Type.Actor @@ at $sloc }

Expand Down Expand Up @@ -322,10 +323,6 @@ exp_block :
| LCURLY ds=seplist(dec, semicolon) RCURLY
{ BlockE(ds) @? at $sloc }

exp_obj :
| LCURLY efs=seplist(exp_field, semicolon) RCURLY
{ efs }

exp_nullary :
| e=exp_block
{ e }
Expand All @@ -337,13 +334,6 @@ exp_nullary :
{ e }
| LPAR es=seplist1(exp, COMMA) RPAR
{ TupE(es) @? at $sloc }
| s=obj_sort xf=id_opt efs=exp_obj
{ let anon = if s.it = Type.Actor then "actor" else "object" in
let efs' =
if s.it = Type.Object Type.Local
then efs
else List.map share_expfield efs
in ObjE(s, xf anon $sloc, efs') @? at $sloc }
| PRIM s=TEXT
{ PrimE(s) @? at $sloc }

Expand Down Expand Up @@ -445,6 +435,14 @@ exp_nonvar :
{ e }
| d=dec_nonvar
{ DecE(d) @? at $sloc }
(* TODO(andreas): hack, remove *)
| s=obj_sort xf=id_opt EQ? efs=obj_body
{ let anon = if s.it = Type.Actor then "actor" else "object" in
let efs' =
if s.it = Type.Object Type.Local
then efs
else List.map share_expfield efs
in ObjE(s, xf anon $sloc, efs') @? at $sloc }

exp :
| e=exp_nonvar
Expand Down Expand Up @@ -545,7 +543,7 @@ dec_nonvar :
then efs
else List.map share_expfield efs
in
let id as tid = xf "class" $sloc in
let tid = xf "class" $sloc in
ClassD(xf "class" $sloc, tid, tps, s, p, x, efs') @? at $sloc }

dec :
Expand All @@ -555,6 +553,16 @@ dec :
{ d }
| e=exp_nondec
{ ExpD e @? at $sloc }
(* TODO(andreas): move to dec_nonvar once other production is gone *)
| s=obj_sort xf=id_opt EQ? efs=obj_body
{ let anon = if s.it = Type.Actor then "actor" else "object" in
let efs' =
if s.it = Type.Object Type.Local
then efs
else List.map share_expfield efs
in
let p = VarP(xf anon $sloc) @? at $sloc in
LetD(p, ObjE(s, xf anon $sloc, efs') @? at $sloc) @? at $sloc }

func_dec :
| tps=typ_params_opt p=pat_nullary rt=return_typ? fb=func_body
Expand All @@ -574,9 +582,13 @@ func_body :
| EQ e=exp { (false, e) }
| e=exp_block { (true, e) }

obj_body :
| LCURLY efs=seplist(exp_field, semicolon) RCURLY
{ efs }

class_body :
| EQ xf=id_opt efs=exp_obj { xf "object" $sloc, efs }
| efs=exp_obj { ("anon-object-" ^ string_of_pos (at $sloc).left) @@ at $sloc, efs }
| EQ xf=id_opt efs=obj_body { xf "object" $sloc, efs }
| efs=obj_body { ("anon-object-" ^ string_of_pos (at $sloc).left) @@ at $sloc, efs }


(* Programs *)
Expand Down
2 changes: 1 addition & 1 deletion src/typing.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1033,7 +1033,7 @@ and check_dec env t dec =
check_exp env t exp;
dec.note <- exp.note;
(* TBR: push in external type annotation;
unfortunately, this is enough, because of the earlier recursive phases
unfortunately, this isn't enough, because of the earlier recursive phases
| FuncD (id, [], pat, typ, exp) ->
(* TBR: special-case unit? *)
if T.eq env.cons t T.unit then
Expand Down
12 changes: 6 additions & 6 deletions test/run/actors.as
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
let tictac_actor = actor self {
tic_msg(n : Int) { if (n > 0) self.tac_msg(n - 1) };
tac_msg(n : Int) { if (n > 0) self.tic_msg(n - 1) };
actor tictac_actor {
tic_msg(n : Int) { if (n > 0) tictac_actor.tac_msg(n - 1) };
tac_msg(n : Int) { if (n > 0) tictac_actor.tic_msg(n - 1) };
};
let _ = tictac_actor.tic_msg(10);

Expand All @@ -12,9 +12,9 @@ let tictac_async = new this {
};
let _ = tictac_async.tic_async(10);

let tictac_actor_async = actor self {
tic_msg_async(n : Int) : async () { if (n > 0) ignore(self.tac_msg_async(n - 1)) };
tac_msg_async(n : Int) : async () { if (n > 0) ignore(self.tic_msg_async(n - 1)) };
actor tictac_actor_async {
tic_msg_async(n : Int) : async () { if (n > 0) ignore(tictac_actor_async.tac_msg_async(n - 1)) };
tac_msg_async(n : Int) : async () { if (n > 0) ignore(tictac_actor_async.tic_msg_async(n - 1)) };
};
let _ = tictac_actor_async.tic_msg_async(10);

Expand Down
8 changes: 4 additions & 4 deletions test/run/is.as
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ assert(not ({} is C));
assert(not ({} is G));
assert(not ({} is A));
assert(not ({} is H));
assert(not (actor {} is C));
assert(not (actor {} is G));
assert(not (actor {} is A));
assert(not (actor {} is H));
assert(not ((actor {}) is C));
assert(not ((actor {}) is G));
assert(not ((actor {}) is A));
assert(not ((actor {}) is H));

assert(not (C() is A));
assert(not (C() is G));
Expand Down
2 changes: 1 addition & 1 deletion test/run/ok/actor.tc.ok
Original file line number Diff line number Diff line change
@@ -1 +1 @@
actor.as:14.31-14.49: type error, misplaced await
actor.as:17.17-17.35: type error, misplaced await
4 changes: 2 additions & 2 deletions test/run/switch.as
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ let x4 = switch (null : {}?) {
};
assert (x4 == 1);

let x5 = switch (new {}?) {
let x5 = switch ((new {})?) {
case null 0;
case x 1;
};
assert (x5 == 1);

let oo : {}? = new {}?;
let oo : {}? = (new {})?;
let x6 = switch oo {
case null 0;
case _ 1;
Expand Down