Skip to content

Commit

Permalink
Make exit() a builtin
Browse files Browse the repository at this point in the history
Instead of env.exit() we now have exit(cap: WorldCap, exit_code: int) as
a builtin function. The primary benefit is that functions are executed
synchronously unlike actor methods which are async. Thus, env.exit()
typically required using `await async env.exit(0)` whereas as a function
it is called as a synchronous procedure, so `exit(env.cap, 0)` is
enough.

Having to add `await async` meant users could do the wrong thing. With
exit() as a function, there is no ambiguity. The user cannot do anything
wrong! Also, this is shorter and more to the point. Less confusing to
new usres. The only weird thing now is the capability argument...

I think we should have a new ExitCap capability, but I want to keep down
the amount of clutter right now, in particular for something as
important as 'exit'. Beginners will see it early and it's scary when it
look all too scary. Accepting WorldCap means we can do `exit(env.cap,
0)` otherwise it would probably be like `exit(ExitCap(env.cap), 0)` and
it's just extra bits complicating things. I think we should have ExitCap
but as exit() is so common that it should be acceptable to use WorldCap
directly. For the few programs where one actually wants to delegate a
restricted ExitCap capability, that should be possible to by having an
ExitCap but it would require exit() to accept a union, either an ExitCap
or WorldCap. We don't have unions yet, so it will have to wait.
  • Loading branch information
plajjan committed Aug 6, 2023
1 parent 991188f commit 069a527
Show file tree
Hide file tree
Showing 132 changed files with 275 additions and 273 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ following code:
``` Acton
actor main(env):
print("Hello, world!")
await async env.exit(0)
exit(env.cap, 0)
```

Compile the program and run it:
Expand Down
6 changes: 0 additions & 6 deletions base/builtin/env.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,6 @@ void read_stdin(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
uv_read_start((uv_stream_t*)tty, alloc_buffer, read_stdin);
return $R_CONT(c$cont, B_None);
}
$R B_EnvD_exitG_local (B_Env self, $Cont c$cont, B_int n) {
return_val = from$int(n);
rts_shutdown();
return $R_CONT(c$cont, B_None);
}


B_Env B_EnvG_newactor(B_WorldCap wc, B_list args) {
B_Env $tmp = $NEWACTOR(B_Env);
Expand Down
5 changes: 3 additions & 2 deletions base/src/__builtin__.act
Original file line number Diff line number Diff line change
Expand Up @@ -902,5 +902,6 @@ actor Env (wc: WorldCap, args: list[str]):
action def stdin_install(cb: action(str) -> None) -> None:
NotImplemented

action def exit(n: int):
NotImplemented
# TODO: cap should be Union[ExitCap, WorldCap]
def exit(cap: WorldCap, exit_code: int) -> None:
NotImplemented
7 changes: 7 additions & 0 deletions base/src/__builtin__.ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,10 @@ void B___ext_init__() {
B_ContainerD_listG_methods.__fromiter__ = (B_list (*)(B_ContainerD_list, B_Iterable, $WORD))B_CollectionD_SequenceD_listD___fromiter__;
B_ContainerD_listG_methods.__iter__ = (B_Iterator (*)(B_ContainerD_list, B_list))B_CollectionD_SequenceD_listD___iter__;
}

B_NoneType B_exit (B_WorldCap cap, B_int exit_code) {
log_info("Exiting...");
return_val = from$int(exit_code);
rts_shutdown();
return B_None;
}
2 changes: 1 addition & 1 deletion compiler/ActonCompiler.hs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ createProject name = do
++ "** Run\n\n#+BEGIN_SRC shell\nout/rel/bin/" ++ name ++ "\n#+END_SRC\n\n"
)
createDirectoryIfMissing True (srcDir paths)
writeFile (joinPath [(srcDir paths), name ++ ".act"]) "#\n#\n\nactor main(env):\n print(\"Hello World!\")\n await async env.exit(0)\n"
writeFile (joinPath [(srcDir paths), name ++ ".act"]) "#\n#\n\nactor main(env):\n print(\"Hello World!\")\n exit(env.cap, 0)\n"
putStrLn("Created project " ++ name)
putStrLn("Enter your new project directory with:\n cd " ++ name)
putStrLn("Compile:\n actonc build")
Expand Down
2 changes: 1 addition & 1 deletion compiler/test/actonc/project/auto_root/src/test.act
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ import b

actor main(env):
b.foo()
await async env.exit(0)
exit(env.cap, 0)
2 changes: 1 addition & 1 deletion compiler/test/actonc/project/conf_2bin/src/a.act
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
actor main(env):
print("a")
await async env.exit(0)
exit(env.cap, 0)
2 changes: 1 addition & 1 deletion compiler/test/actonc/project/conf_2bin/src/b.act
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
actor main(env):
print("b")
await async env.exit(0)
exit(env.cap, 0)
2 changes: 1 addition & 1 deletion compiler/test/actonc/project/qualified_root/src/test.act
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ import b

actor main(env):
b.foo()
await async env.exit(0)
exit(env.cap, 0)
2 changes: 1 addition & 1 deletion compiler/test/actonc/root/test.act
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
actor main(env):
await async env.exit(0)
exit(env.cap, 0)
2 changes: 1 addition & 1 deletion examples/StringsAndBytes.act
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ actor main(env):
s = "\x48ello, world"
print(s)

env.exit(0)
exit(env.cap, 0)

2 changes: 1 addition & 1 deletion examples/abs.act
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
actor main(env):
x = -3
print(abs(x))
env.exit(0)
exit(env.cap, 0)
2 changes: 1 addition & 1 deletion examples/average.act
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ actor main(env):
for i in map(int,v): print(i)
for x in map(float,v): print(x)
# print(average(v))
env.exit(0)
exit(env.cap, 0)
2 changes: 1 addition & 1 deletion examples/bsplit.act
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ def e(prec):

actor main(env):
print(e(10000))
env.exit(0)
exit(env.cap, 0)

2 changes: 1 addition & 1 deletion examples/client.act
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ actor main(env):

if len(env.argv) != 3:
print("usage: client [HOST] [PORT]")
await async env.exit(-1)
exit(env.cap, -1)

connect_cap = net.TCPConnectCap(net.TCPCap(net.NetCap(env.cap)))
client = net.TCPIPConnection(connect_cap, env.argv[1], int(env.argv[2]), on_connect, on_receive, on_error)
4 changes: 2 additions & 2 deletions examples/count.act
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ actor main(env):

if len(env.argv) > 2:
print("Usage: count COUNT")
await async env.exit(1)
exit(env.cap, 1)

if len(env.argv) > 1:
count_to = int(env.argv[1])

def _work():
print(i)
if count_to and i == count_to:
await async env.exit(0)
exit(env.cap, 0)
i += 1
after 1: _work()

Expand Down
2 changes: 1 addition & 1 deletion examples/counter.act
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ actor main(env):
ctr = counter(0)
n = ctr.next()
print(n)
env.exit(0)
exit(env.cap, 0)
2 changes: 1 addition & 1 deletion examples/eq_list_dict.act
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,6 @@ actor main(env):
print("Not le, wrong")


env.exit(0)
exit(env.cap, 0)


2 changes: 1 addition & 1 deletion examples/files.act
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ actor main(env):
data = f.read()
print(data.decode())

env.exit(0)
exit(env.cap, 0)
2 changes: 1 addition & 1 deletion examples/helloworld.act
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
actor main(env):
print("Hello, world!")
await async env.exit(0)
exit(env.cap, 0)
2 changes: 1 addition & 1 deletion examples/mathtest.act
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ actor main(env):
a = numpy.linspace(0.0,1.0,20)
b = cos(a)
print(b)
env.exit(0)
exit(env.cap, 0)


2 changes: 1 addition & 1 deletion examples/overlap.act
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ actor main(env):
print("Should be 0:", f(""))
print("Should be 1:", g(0))
print("Should be 2:", h(3.14))
env.exit(0)
exit(env.cap, 0)
2 changes: 1 addition & 1 deletion examples/print_time.act
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ actor main(env):
def f():
print(time.time())
f()
env.exit(0)
exit(env.cap, 0)
2 changes: 1 addition & 1 deletion examples/reprtest.act
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ actor main(env):
for i in range(0,10,1):
d[i] = str(i)
print(d)
env.exit(0)
exit(env.cap, 0)


2 changes: 1 addition & 1 deletion examples/sieve.act
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ actor main(env):
print(count(sieve(int(env.argv[1]))))
else:
print("Usage: sieve <positive integer>")
env.exit(0)
exit(env.cap, 0)
2 changes: 1 addition & 1 deletion examples/sumto.act
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ actor main(env):
else:
target = int(123)
print(sumto(int(target)))
env.exit(0)
exit(env.cap, 0)
2 changes: 1 addition & 1 deletion examples/sumto2.act
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ def sumto(n):

actor main(env):
print(sumto(int(env.argv[1])))
env.exit(0)
exit(env.cap, 0)
4 changes: 2 additions & 2 deletions examples/worker.act
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ actor worker(report):
actor main(env):
def report():
print('Done!')
env.exit(0)
exit(env.cap, 0)

worker(report)
env.exit(0)
exit(env.cap, 0)
16 changes: 8 additions & 8 deletions test/builtins_auto/builtin_functions_test.act
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,24 @@ def even(n):
actor main(env):
if list(filter(even,lst)) != [10,12,14]:
print("filter")
env.exit(1)
exit(env.cap, 1)
if list(map(lambda x : x*x,lst)) != [100, 121, 144, 169, 196]:
print("map")
env.exit(1)
exit(env.cap, 1)
if max(lst,None) != 14:
print("max")
env.exit(1)
exit(env.cap, 1)
if hex(65536*65536) != "0x100000000":
print("hex")
env.exit(1)
exit(env.cap, 1)
if chr(8707) != '∃':
print("chr")
env.exit(1)
exit(env.cap, 1)
if ord('∃') != 8707:
print("ord")
env.exit(1)
exit(env.cap, 1)
if ascii("Björn ∃") != "'Bj\\xc3\\xb6rn \\xe2\\x88\\x83'":
print("ascii")
env.exit(1)
exit(env.cap, 1)

env.exit(0)
exit(env.cap, 0)
2 changes: 1 addition & 1 deletion test/builtins_auto/bytearray_test.act
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ actor main(env):
# del b2[0:10000:i] # delete everything except the Z's
# print(b2)

env.exit(0)
exit(env.cap, 0)
4 changes: 2 additions & 2 deletions test/builtins_auto/container_test.act
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
actor main(env):
lst = list(range(1,100,1))
if 17 not in lst or 171 in lst or 100 in lst:
env.exit(1)
env.exit(0)
exit(env.cap, 1)
exit(env.cap, 0)


28 changes: 14 additions & 14 deletions test/builtins_auto/dict.act
Original file line number Diff line number Diff line change
Expand Up @@ -5,67 +5,67 @@ actor main(env):
d["b"] = "B"
if d != {"a": "A", "b": "B"}:
print("Unexpected result of dict[\"b\"]=\"b\":", d)
await async env.exit(1)
exit(env.cap, 1)

if len(d) != 2:
print("Unexpected result of len(d):", len(d))
await async env.exit(1)
exit(env.cap, 1)

if list(d.keys()) != ["a", "b"]:
print("Unexpected result of d.keys():", d.keys())
await async env.exit(1)
exit(env.cap, 1)

if repr(list(d.items())) != repr([("a", "A"), ("b", "B")]):
print("Unexpected result of d.items():", d.items())
await async env.exit(1)
exit(env.cap, 1)

if list(d.values()) != ["A", "B"]:
print("Unexpected result of d.values():", d.values())
await async env.exit(1)
exit(env.cap, 1)

del d["b"]
if d != {"a": "A"}:
print("Unexpected result of del dict[\"b\"]:", d)
await async env.exit(1)
exit(env.cap, 1)

# d["pop"] = 123
# p = d.pop("pop")
# if p != 123:
# print("Unexpected result of d.pop(\"b\"):", p)
# await async env.exit(1)
# exit(env.cap, 1)

d["popi"] = "POPI"
pi = d.popitem()
if pi.0 != "popi" and pi.1 != "POPI":
print("Unexpected result of d.popitem():", str(pi.0), str(pi.1))
await async env.exit(1)
exit(env.cap, 1)

g = d.get("a", "")
if g != "A":
print("Unexpected result of d.get(\"a\"):", g)
await async env.exit(1)
exit(env.cap, 1)

# TODO: fix, seemingly broken?
# d.update({"c": "C"})
# if d != {"a": "A", "c": "C"}:
# print("Unexpected result of dict.update():", d)
# await async env.exit(1)
# exit(env.cap, 1)

# sd = d.setdefault("setdef", "a")
# print(d)
# if sd is not None and sd.0 is not None and sd.0 != "setdef":
# print("Unexpected result of d.setdefault(\"setdef\", 1):", str(sd))
# await async env.exit(1)
# exit(env.cap, 1)

# d2 = d.copy()
# if d2 != {"a": 1}:
# print("Unexpected result of d.copy():", d2)
# await async env.exit(1)
# exit(env.cap, 1)

# d.clear()
# if d != {}:
# print("Unexpected result of d.clear():", d)
# await async env.exit(1)
# exit(env.cap, 1)


await async env.exit(0)
exit(env.cap, 0)
14 changes: 7 additions & 7 deletions test/builtins_auto/dict_test2.act
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,27 @@ actor main(env):
r = r*r % 1000
s += int(dict[str(r)])
if s != 99446:
env.exit(1)
exit(env.cap, 1)
if str(678) not in dict:
env.exit(1)
exit(env.cap, 1)
for i in range(1,1000,1):
if i%10 > 0:
del dict[str(i)]
if len(dict) != 99:
env.exit(1)
exit(env.cap, 1)
t = 0
for k in dict:
t += int(k)
if t != 49500:
env.exit(1)
exit(env.cap, 1)
deflt = '666'
w = dict.get('100',deflt)
w2 = dict.get('37',deflt)
if w != '101' or w2 != '666':
env.exit(1)
exit(env.cap, 1)
for j in range(11,200,20):
other[str(j)] = str(2*j)
dict.update(other.items())
if len(dict) != 109:
env.exit(1)
env.exit(0)
exit(env.cap, 1)
exit(env.cap, 0)
2 changes: 1 addition & 1 deletion test/builtins_auto/int.act
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ actor main(env):
raise ValueError("int('123') != 123")
if hash(2**131) >= 2**64:
raise ValueError("hash(2**131) too big")
await async env.exit(0)
exit(env.cap, 0)
Loading

0 comments on commit 069a527

Please sign in to comment.