Implement namespaces

This includes a massive refactoring of the type checker, getting
rid of most of the ets tables and keeping a proper environment.
This commit is contained in:
Ulf Norell
2019-01-21 14:20:57 +01:00
parent 026ff52528
commit 367f87b612
14 changed files with 863 additions and 457 deletions
+1 -1
View File
@@ -66,7 +66,7 @@ encode_decode_sophia_test() ->
encode_decode_sophia_string(SophiaType, String) ->
io:format("String ~p~n", [String]),
Code = [ "contract Call =\n"
Code = [ "contract MakeCall =\n"
, " function foo : ", SophiaType, " => _\n"
, " function __call() = foo(", String, ")\n" ],
{ok, _, {Types, _}, Args} = aeso_compiler:check_call(lists:flatten(Code), []),
+5 -4
View File
@@ -150,11 +150,10 @@ failing_contracts() ->
<<"Ambiguous record type with field y (at line 13, column 25) could be one of\n"
" - r (at line 4, column 10)\n"
" - r' (at line 5, column 10)">>,
<<"Record type r2 does not have field y (at line 15, column 22)">>,
<<"The field z is missing when constructing an element of type r2 (at line 15, column 24)">>,
<<"Repeated name x in pattern\n"
" x :: x (at line 26, column 7)">>,
<<"No record type with fields y, z (at line 14, column 22)">>]}
<<"No record type with fields y, z (at line 14, column 22)">>,
<<"No record type with fields y, w (at line 15, column 22)">>]}
, {"init_type_error",
[<<"Cannot unify string\n"
" and map(int, int)\n"
@@ -166,5 +165,7 @@ failing_contracts() ->
, {"missing_fields_in_record_expression",
[<<"The field x is missing when constructing an element of type r('a) (at line 7, column 40)">>,
<<"The field y is missing when constructing an element of type r(int) (at line 8, column 40)">>,
<<"The fields y, z are missing when constructing an element of type r('1) (at line 6, column 40)">>]}
<<"The fields y, z are missing when constructing an element of type r('a) (at line 6, column 40)">>]}
, {"namespace_clash",
[<<"The contract Call (at line 4, column 10) has the same name as a namespace at (builtin location)">>]}
].
+2 -2
View File
@@ -1,6 +1,6 @@
// Test more advanced chain interactions
contract Chain =
contract ChainTest =
record state = { last_bf : address }
@@ -10,4 +10,4 @@ contract Chain =
function miner() = Chain.coinbase
function save_coinbase() =
put(state{last_bf = Chain.coinbase})
put(state{last_bf = Chain.coinbase})
+5
View File
@@ -0,0 +1,5 @@
// You can't shadow existing contracts or namespaces.
contract Call =
function whatever() = ()
+31
View File
@@ -0,0 +1,31 @@
namespace Lib =
// namespace Internal =
// function rev(xs, ys) =
// switch(xs)
// [] => ys
// x :: xs => rev(xs, x :: ys)
private
function rev(xs, ys) =
switch(xs)
[] => ys
x :: xs => rev(xs, x :: ys)
function reverse(xs : list('a)) : list('a) = rev(xs, [])
function eqlist(xs : list(int), ys : list(int)) =
switch((xs, ys))
([], []) => true
(x :: xs, y :: ys) => x == y && eqlist(xs, ys)
_ => false
contract TestNamespaces =
record state = { x : int }
function init() = { x = 0 }
function palindrome(xs : list(int)) : bool =
Lib.eqlist(xs, Lib.reverse(xs))