Following the Documentation recommendations, this README has the following sections:
This artifact demonstrates a minimal prototype implementation of Welterweight Go (WG) as a command-line interpreter tool wgi.
WG captures a functional core subset of Go centering on interfaces, structs and methods with Go’s structural typing, along with a range of features that exercise Go’s type system and runtime mechanisms for type coercions, including anonymous types, underlying types, (dynamic) type assertions, (static) type conversions, generics, type sets, and generic type constraints. WG further extends Go with new features, including generic methods, method set intersections for constraints, and recursively bounded generics.
The wgi interpreter can be used to perform a few functions based on the formal model presented in the paper:
The main (and only) statement in the submitted paper regarding our implementation and aritfact is the below. While the paper does not discuss this implementation (it focusses on presenting our formal developments), we submit this artifact as an accompaniment.
l.84 We have developed a prototype based on our presented compilation approach. We plan to submit it for artifact evaluation.
This artifact supports the above statement by providing:
Dockerfile includes the build commands; wgi is pre-built inside the image but the build commands can be rerun.This artifact further provides:
wgi binary and a Makefile for running the examples: see 2.5 and 3.1.The artifact archive paper779.zip contains:
README-paper779-artifact.html with pandoc.css for formatting – has clickable links;README-paper779-artifact.md – links clickable depending on your markdown viewer;README-paper779-artifact.pdf.popl26-paper779-docker.tar.gzDockerfile used to build the image. It can be used to rebuild the image (for your own platform) if you wish.
popl26-paper779.pdfPrerequisites:
Notes on the Docker image:
linux/amd64 and has been successfully tested on linux/arm64 (Mac M4).
WARNING: The requested image's platform (linux/amd64) does not match... but in our testing the image still works by default (via emulation).
An explicit emulation command (cf. step 3 in 2.3) is:
Alternatively, rebuild the image yourself (for your platform); takes just a few minutes. On the command-line go to the directory with the Dockerfile and run:
You can install additional software within the container as required, e.g.,
Steps from scratch:
popl26-paper779-docker.tar.gz in some local directory; say, $MY_DIR.Load the image. In $MY_DIR, do:
Run a container with an interactive session. In $MY_DIR, do:
Run a pre-written example. Inside the container, do:
Expected output. The program should terminate successfully and you should see:
[parse] Parsing AST:
package main;
type World[] struct {};
func (x0 World[]) hello[]() World[]@World[] { return x0.hello[]() };
func main() { _ = World[]{}.hello[]() }…snip…
9: [R-Call] World[](World[](World[](World[](World[](World[](World[](World[](World[](World[]{}.hello[]())))))))))
[Eval] Checking OK: World[]
10: [R-Call] World[](World[](World[](World[](World[](World[](World[](World[](World[](World[](World[]{}.hello[]()))))))))))
[Eval] Checking OK: World[]
World[](World[](World[](World[](World[](World[](World[](World[](World[](World[](World[]{}.hello[]()))))))))))Kick-the-tires: run all tests in one go. Inside the container, do:
Expected output. A mix of examples and unit tests will be run. It may take around 1 or 2 minutes in total. You will see the file name of each example/test possibly followed by some output depending on the program. Overall you should see:
cd test && go test
-- ../examples/wg/oopsla20/fig4/functions.wg
main.FF[]{}
Bool[]@Bool[](FF[],map[Cond_D:FF.Cond_D Equal_D:FF.Equal_D Not_D:FF.Not_D],FF[]{})
-- ../examples/wg/oopsla20/fig6/lists.wg…snip…
| Directory | Path inside container | Env var | Notes |
| Go path |
/home/paper779/artifact/go |
GO_PATH
|
Workspace dir of Go installation |
| WG home |
$GO_PATH/src/github.com/rhu1/wg/
|
WG_HOME
|
WG project base dir |
| Tests |
$WG_HOME/test
|
|
WG project test dir |
| Examples |
$WG_HOME/examples
|
WG examples | |
| Go bin |
$GOPATH/bin/
|
Installation dir of wgi binary
|
The Go bin dir is included in $PATH.
Building and installing wgi inside the artifact.
wgi binary has been pre-compiled and installed for convenience. See the Dockerfile for the command-line instructions (just a few lines of code); they can be repeated inside the container if desired.$WG_HOME/README.md for more notes on building and installing wgi.Compiling/running individual WG examples.
The following commands should be run from $WG_HOME.
Type check and run a WG program:
10 is the number of evaluation steps (≥ 0) to attempt. An error is printed if the program terminates before reaching that number.-1 to attempt evalution until termination. Non-terminating programs will run until interrupted by the user (e.g., press ctrl-c).Compile to LWG, type check and print:
Compile to LWG, type check and run:
-1 attempts evaluation until termination.Compile a terminating WG program; then run the WG and LWG programs and check their final result values correspond (cf. the “lollipop” relation, Fig. 21 in Appendix C.3):
ctrl-c); the value correspondence check will not be performed.Some combinations are possible; e.g.
See 3. Evaluation instructions for more information on the examples.
Please note the following when using wgi.
[] for an empty list of generic type parameters, must be written out in full, even if they may be omitted in actual Go.WG_HOME/examples.int, and the only operation is +.For convenience, the below runs all the examples and tests in one go.
We now explain how the examples and tests are organised.
The make test command simply enters the $WG_HOME/test directory and runs the go test commmand, which performs all of the tests coded inside these two files:
wg_test.go – Tests the following:
$WG_HOME/examples/wg/hello – Hello world examples.$WG_HOME/examples/wg/popl26 – All of the examples from the submitted paper.$WG_HOME/test/wg – Various positive (ok) and negative (ko) unit tests.fgg_test.go – Tests additional examples from the artifact of the work on Featherweight Go (FG).
$WG_HOME examples/wg outside those already mentioned.Regarding the source material of the examples:
$WG_HOME/examples/wg/popl26 correspond to the figures, sections and labelled examples of the submitted paper where the examples are drawn from. Some of these subdirs also contain variations of the given example. See those parts of the paper for explanations of the examples.
func function types and functions in Figs. 1 and 2 in the paper are encoded in WG using interfaces, structs and methods (cf. L92 in the paper).float64 and string have been replaced by int as that is the only base type supported by the implementation at present.$WG_HOME/examples/wg/oopsla20 are ported from the mentioned FG artifact and correspond to the figures in the FG paper.$WG_HOME/monom/mono-ko contains examples that are not monomorphisable (e.g., they feature polymorphic recursion), and hence cannot be compiled in FG or actual Go but are fully supported in WG.Regarding the expected output for the unit tests and examples when running make test:
$WG_HOME/test/wg/ko.-eval=100 though the eval arg itself is moot.)examples/wg/hello.examples/wg/monom/mono-ko/ except for incompleteness-subtyping.wg.-eval=100 and -eval-lwg=100.$WG_HOME/test/wg/ok.examples/wg/ outside those already mentioned above.-lolli=-1.See 2.5 for explanation of the mentioned testing flags.
An example of output from make test for the latter case:
-- ../examples/wg/oopsla20/fig4/functions.wg
main.FF[]{}
Bool[]@Bool[](FF[],map[Cond_D:FF.Cond_D Equal_D:FF.Equal_D Not_D:FF.Not_D],FF[]{})FF struct literal).Bool@Bool, concrete RTTI FF, method table with methods Cond_D, Equal_D and Not_D, and encapsulated empty struct value {} with metatheoretical struct type FF).See the paper for the full details of WG and LWG.
See Appendix A.1 for the output from a run of make test in full.
The WG code project under $WG_HOME has a typical Go structure:
Makefile – See the Dockerfile for the build/installation commands used.cmd/wgi – Contains the main function for the wgi executable.examples – See 3.1.parser
parser/wg – Parser sources generated by ANTLR (cf. make generate-parser).parser/pregen – pre-generated parser sources (cf. make install-pregen-parser).internal
internal/wg – Main WG implementation.internal/lwg – Main LWG implementation.internal/parser – Converts ANTLR-generated CST to WG AST.base and frontend – Additional source directories.test – see 3.1.See $WG_HOME/README.md for more notes on building and installing wgi.
Inside the container:
apt-get install nano vim -y // Just examples; pick your favourite editor
cd $WG_HOME
vim tmp/scratch.wg // Or other editor…edit and save the WG file…
See 2.6 for notes (warnings) on writing WG code. No syntactic sugar is supported, so empty brackets (e.g., empty generic parameter lists) and declaration separators (e.g., semicolons) all need to be written out in full.
make test in fullBelow is the full output from a run of make test.
cd test && go test
-- ../examples/wg/oopsla20/fig4/functions.wg
main.FF[]{}
Bool[]@Bool[](FF[],map[Cond_D:FF.Cond_D Equal_D:FF.Equal_D Not_D:FF.Not_D],FF[]{})
-- ../examples/wg/oopsla20/fig6/lists.wg
main.Cons[main.Bool[]]{head:main.FF[]{}, tail:main.Cons[main.Bool[]]{head:main.TT[]{}, tail:main.Nil[main.Bool[]]{}}}
List[Bool[]]@List[Bool[]](Cons[Bool[]],map[Map_D:Cons.Map_D],Cons[Bool[]]{Bool[]@Any[](FF[],map[],FF[]{}), List[Bool[]]@List[Bool[]](Cons[Bool[]],map[Map_D:Cons.Map_D],Cons[Bool[]]{Bool[]@Any[](TT[],map[],TT[]{}), List[Bool[]]@List[Bool[]](Nil[Bool[]],map[Map_D:Nil.Map_D],Nil[Bool[]]{})})})
-- ../examples/wg/oopsla20/fig7/graph.wg
main.A[]{}
main.A[]{}
-- ../examples/wg/oopsla20/fig10/nomono.wg
main.Box[main.Box[main.Box[main.Box[main.D[]]]]]{value:main.Box[main.Box[main.Box[main.D[]]]]{value:main.Box[main.Box[main.D[]]]{value:main.Box[main.D[]]{value:main.D[]{}}}}}
Any[]@Any[](Box[Box[Box[Box[D[]]]]],map[],Box[Box[Box[Box[D[]]]]]{Box[Box[Box[D[]]]]@Any[](Box[Box[Box[D[]]]],map[],Box[Box[Box[D[]]]]{Box[Box[D[]]]@Any[](Box[Box[D[]]],map[],Box[Box[D[]]]{Box[D[]]@Any[](Box[D[]],map[],Box[D[]]{D[]@Any[](D[],map[],D[]{})})})})})
-- ../examples/wg/oopsla20/fig19/dispatcher.wg
main.Int[]{}
main.Int[]{}
-- ../examples/wg/misc/irregular/irregular.wg
main.Node[main.Nat[]]{label:main.Succ[]{pred:main.Succ[]{pred:main.Zero[]{}}}, children:main.Node[main.Pair[main.Nat[]]]{label:main.Pair[main.Nat[]]{fst:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Zero[]{}}}}, snd:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Zero[]{}}}}}}, children:main.Node[main.Pair[main.Pair[main.Nat[]]]]{label:main.Pair[main.Pair[main.Nat[]]]{fst:main.Pair[main.Nat[]]{fst:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Zero[]{}}}}}}, snd:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Zero[]{}}}}}}}}, snd:main.Pair[main.Nat[]]{fst:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Zero[]{}}}}}}}}, snd:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Zero[]{}}}}}}}}}}}, children:main.Leaf[main.Pair[main.Pair[main.Pair[main.Nat[]]]]]{}}}}
Balanced[Nat[]]@Balanced[Nat[]](Node[Nat[]],map[BalancedMap_D:Node.BalancedMap_D],Node[Nat[]]{Nat[]@Any[](Succ[],map[],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Zero[],map[Add_D:Zero.Add_D],Zero[]{})})}), Balanced[Pair[Nat[]]]@Balanced[Pair[Nat[]]](Node[Pair[Nat[]]],map[BalancedMap_D:Node.BalancedMap_D],Node[Pair[Nat[]]]{Pair[Nat[]]@Any[](Pair[Nat[]],map[],Pair[Nat[]]{Nat[]@Any[](Succ[],map[],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Zero[],map[Add_D:Zero.Add_D],Zero[]{})})})}), Nat[]@Any[](Succ[],map[],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Zero[],map[Add_D:Zero.Add_D],Zero[]{})})})})})}), Balanced[Pair[Pair[Nat[]]]]@Balanced[Pair[Pair[Nat[]]]](Node[Pair[Pair[Nat[]]]],map[BalancedMap_D:Node.BalancedMap_D],Node[Pair[Pair[Nat[]]]]{Pair[Pair[Nat[]]]@Any[](Pair[Pair[Nat[]]],map[],Pair[Pair[Nat[]]]{Pair[Nat[]]@Any[](Pair[Nat[]],map[],Pair[Nat[]]{Nat[]@Any[](Succ[],map[],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Zero[],map[Add_D:Zero.Add_D],Zero[]{})})})})})}), Nat[]@Any[](Succ[],map[],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Zero[],map[Add_D:Zero.Add_D],Zero[]{})})})})})})})}), Pair[Nat[]]@Any[](Pair[Nat[]],map[],Pair[Nat[]]{Nat[]@Any[](Succ[],map[],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Zero[],map[Add_D:Zero.Add_D],Zero[]{})})})})})})})}), Nat[]@Any[](Succ[],map[],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Zero[],map[Add_D:Zero.Add_D],Zero[]{})})})})})})})})})})}), Balanced[Pair[Pair[Pair[Nat[]]]]]@Balanced[Pair[Pair[Pair[Nat[]]]]](Leaf[Pair[Pair[Pair[Nat[]]]]],map[BalancedMap_D:Leaf.BalancedMap_D],Leaf[Pair[Pair[Pair[Nat[]]]]]{})})})})
-- ../examples/wg/misc/irregular/irregular2.wg
Node[Nat[]]{Succ[]{Succ[]{Zero[]{}}}, Leaf[Pair[Nat[]]]{}}
Balanced[Nat[]]@Balanced[Nat[]](Node[Nat[]],map[BalancedMap_D:Node.BalancedMap_D],Node[Nat[]]{Nat[]@Any[](Succ[],map[],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Zero[],map[Add_D:Zero.Add_D],Zero[]{})})}), Balanced[Pair[Nat[]]]@Balanced[Pair[Nat[]]](Leaf[Pair[Nat[]]],map[BalancedMap_D:Leaf.BalancedMap_D],Leaf[Pair[Nat[]]]{})})
-- ../examples/wg/misc/monomorph/monomorph.wg
main.Pair[main.List[main.Bool[]], main.List[main.Nat[]]]{Fst:main.Cons[main.Bool[]]{head:main.FF[]{}, tail:main.Cons[main.Bool[]]{head:main.TT[]{}, tail:main.Nil[main.Bool[]]{}}}, Snd:main.Cons[main.Nat[]]{head:main.Succ[]{pred:main.Succ[]{pred:main.Zero[]{}}}, tail:main.Cons[main.Nat[]]{head:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Zero[]{}}}}, tail:main.Cons[main.Nat[]]{head:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Succ[]{pred:main.Zero[]{}}}}}, tail:main.Nil[main.Nat[]]{}}}}}
main.Pair[main.List[main.Bool[]], main.List[main.Nat[]]]{Fst:List[Bool[]]@Any[](Cons[Bool[]],map[],Cons[Bool[]]{Bool[]@Any[](FF[],map[],FF[]{}), List[Bool[]]@List[Bool[]](Cons[Bool[]],map[Map_D:Cons.Map_D],Cons[Bool[]]{Bool[]@Any[](TT[],map[],TT[]{}), List[Bool[]]@List[Bool[]](Nil[Bool[]],map[Map_D:Nil.Map_D],Nil[Bool[]]{})})}), Snd:List[Nat[]]@Any[](Cons[Nat[]],map[],Cons[Nat[]]{Nat[]@Any[](Succ[],map[],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Zero[],map[Add_D:Zero.Add_D],Zero[]{})})}), List[Nat[]]@List[Nat[]](Cons[Nat[]],map[Map_D:Cons.Map_D],Cons[Nat[]]{Nat[]@Any[](Succ[],map[],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Zero[],map[Add_D:Zero.Add_D],Zero[]{})})})}), List[Nat[]]@List[Nat[]](Cons[Nat[]],map[Map_D:Cons.Map_D],Cons[Nat[]]{Nat[]@Any[](Succ[],map[],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Succ[],map[Add_D:Succ.Add_D],Succ[]{Nat[]@Nat[](Zero[],map[Add_D:Zero.Add_D],Zero[]{})})})})}), List[Nat[]]@List[Nat[]](Nil[Nat[]],map[Map_D:Nil.Map_D],Nil[Nat[]]{})})})})}
-- ../examples/wg/monom/mono-ko/box.wg
-- ../examples/wg/monom/mono-ko/box2.wg
-- ../examples/wg/monom/mono-ko/incompleteness-subtyping.wg
S[]{}
S[]{}
-- ../examples/wg/monom/mono-ko/monom-imp.wg
-- ../examples/wg/monom/mono-ko/mutual-poly-rec.wg
-- ../examples/wg/monom/mono-ko/mutual-rec-iface.wg
-- ../examples/wg/monom/mono-ko/nested-fix.wg
-- ../examples/wg/monom/mono-ko/two-type-param.wg
-- ../examples/wg/hello/hello.wg
-- ../examples/wg/hello/fmtprintf/fmtprintf.wg
-- ./wg/ok/Test01.wg
A[]{}
A[]{}
-- ./wg/ok/Test02.wg
S[]{}
Any[]@Any[](S[],map[],S[]{})
-- ./wg/ok/Test03.wg
A[]{}
A[]{}
-- ./wg/ok/Test04.wg
B[]{}
B[]{}
-- ./wg/ok/Test05.wg
MyInt[](43)
MyInt[](43)
-- ./wg/ok/Test06.wg
A[]{}
A[]{}
-- ./wg/ko/Test07.wg
TypeDecl not OK:
-- ./wg/ok/Test09.wg
A[]{int(42)}
A[]{int(42)}
-- ./wg/ok/Test09.wg
A[]{int(42)}
A[]{int(42)}
-- ./wg/ok/Test10.wg
-- ./wg/ok/Test11.wg
S[]{}
S[]{}
-- ./wg/ko/Test12.wg
Arg expr type must be assignable to param type: arg=A3[], param=I2[]@I[I2[]]
-- ./wg/ok/Test13.wg
Cell[int]{int(42)}
interface {}@interface {}(Cell[int],map[],Cell[int]{int@interface {}(int,map[],int(42))})
-- ./wg/ko/Test14.wg
Type actual must implement type formal: actual=Cell[int], param=I[]
-- ./wg/ko/Test15.wg
Arg expr type must be assignable to param type: arg=Cell[int], param=struct { f int@int }@I[]
-- ./wg/ko/Test16.wg
Type actual must implement type formal: actual=struct { x int@int }, param=I[]
-- ./wg/ok/Test17.wg
int(3)
int(3)
-- ./wg/ok/Test18.wg
int(84)
int(84)
-- ./wg/ok/Test19.wg
MyInt[](84)
MyInt[](84)
-- ./wg/ok/Test20.wg
int(84)
int(84)
-- ./wg/ko/Test21.wg
TypeDecl not OK:
-- ./wg/ko/Test22.wg
TypeDecl not OK:
-- ./wg/ok/Test23.wg
struct { f int@int }{int(42)}
struct { f int@int }{int(42)}
-- ./wg/ok/Test24.wg
int(42)
int(42)
-- ./wg/ko/Test25.wg
Type I[] not struct: I[]{int(42)}:
-- ../examples/wg/popl26/fig1/join.wg
int(42)
int(42)
-- ../examples/wg/popl26/fig1/joinOp.wg
int(45)
int(45)
-- ../examples/wg/popl26/sec2_2/bar.wg
int(42)
int(42)
-- ../examples/wg/popl26/fig2/extjoinConsMyInt.wg
MyInt[](41)
MyInt[](41)
-- ../examples/wg/popl26/fig2/extjoinConsMyIntOp.wg
MyInt[](44)
MyInt[](44)
-- ../examples/wg/popl26/fig2/extjoinMyIntCons.wg
MyInt[](40)
MyInt[](40)
-- ../examples/wg/popl26/fig2/extjoinMyIntConsOp.wg
MyInt[](43)
MyInt[](43)
-- ../examples/wg/popl26/sec3/ordered.wg
int(1)
int(1)
-- ../examples/wg/popl26/sec3/ordered2.wg
MyInt[](3)
MyInt[](3)
-- ../examples/wg/popl26/sec3/ordered3.wg
struct {}{}
struct {}{}
-- ../examples/wg/popl26/sec3/ordered4.wg
Type actual must implement type formal: actual=A[], param=Ordered[]
-- ../examples/wg/popl26/sec3/ordered5.wg
struct {}{}
struct {}{}
-- ../examples/wg/popl26/ex3_1/assign.wg
Point[]{int(1), int(1)}
Point[]{int(1), int(1)}
-- ../examples/wg/popl26/ex3_1/assign2.wg
Point[]{int(1), int(1)}
Point[]{int(1), int(1)}
-- ../examples/wg/popl26/ex3_1/assign3.wg
Point[]{int(1), int(1)}
Point[]{int(1), int(1)}
-- ../examples/wg/popl26/ex3_1/assign4.wg
struct { x int@int; y int@int }{int(1), int(1)}
struct { x int@int; y int@int }{int(1), int(1)}
-- ../examples/wg/popl26/ex3_1/assign5.wg
struct { x int@int; y int@int }{int(1), int(1)}
struct { x int@int; y int@int }{int(1), int(1)}
-- ../examples/wg/popl26/ex3_2/constraint.wg
MyStruct[]{int(43)}
MyStruct[]{int(43)}
-- ../examples/wg/popl26/ex3_2/constraint2.wg
MyStruct[]{int(43)}
MyStruct[]{int(43)}
-- ../examples/wg/popl26/ex3_2/constraint3.wg
int(2)
int(2)
-- ../examples/wg/popl26/ex3_2/constraint4.wg
int(42)
int(42)
-- ../examples/wg/popl26/ex3_2/constraintOp.wg
int(85)
int(85)
-- ../examples/wg/popl26/sec4/shape.wg
Circle[]{Point[]{int(1), int(1)}, int(2)}
Shape[]@Shape[](Circle[],map[draw_D:Circle.draw_D shape_D:Circle.shape_D],Circle[]{Point[]{int(1), int(1)}, int(2)})
-- ../examples/wg/popl26/sec4/shape2.wg
Circle[]{Point[]{int(1), int(1)}, int(2)}
interface {}@interface {}(Circle[],map[],Circle[]{Point[]{int(1), int(1)}, int(2)})
-- ../examples/wg/popl26/sec4/shape3.wg
Circle[]{Point[]{int(1), int(1)}, int(2)}
interface {}@interface {}(Circle[],map[],Circle[]{Point[]{int(1), int(1)}, int(2)})
-- ../examples/wg/popl26/sec4/shape4.wg
Circle[]{Point[]{int(1), int(1)}, int(2)}
interface {}@interface {}(Circle[],map[],Circle[]{Point[]{int(1), int(1)}, int(2)})
-- ../examples/wg/popl26/sec4/shape5.wg
struct { p Point[]@Point[]; r int@int }{Point[]{int(1), int(1)}, int(2)}
interface {}@interface {}(struct { p Point[]@Point[]; r int@int },map[],struct { p Point[]@Point[]; r int@int }{Point[]{int(1), int(1)}, int(2)})
-- ../examples/wg/popl26/sec5/cell.wg
Cell[int]{int(42)}
Cell[int]{int@interface {}(int,map[],int(42))}
-- ../examples/wg/popl26/sec5/cell2.wg
StringerCell[]{MyInt[](42)}
StringerCell[]{MyStringer[]@MyStringer[](MyInt[],map[String_D:MyInt.String_D],MyInt[](42))}
-- ../examples/wg/popl26/ex5_1/process.wg
int(42)
int(42)
-- ../examples/wg/popl26/ex5_1/process2.wg
int(42)
int(42)
-- ../examples/wg/popl26/ex5_1/process3.wg
int(43)
int(43)
-- ../examples/wg/popl26/ex5_1/process4.wg
int(44)
int(44)
PASS
ok github.com/rhu1/wg/test 105.873s