Luke Taylor ([email protected]), Nick Doan ([email protected]), Caleb Ledi ([email protected]), Duru Uğurlu ([email protected]), Chloe Lam ([email protected])
First, install required dependencies:
opam install dune
opam install llvm.14.0.6 # or whatever version of llvm you have installed
After installing dependencies, you will be able to:
- Run
make
to build the mainuntangled.exe
executable. - Run
./untangled.exe < path/to/program.unt -o exe_name
to compile an Untangled program to an executable namedexe_name
.
You will also be able to:
- Run
make test
to run the full series of automated tests. See Testing for additional options. Requires Python 3. - Run
make vscode-extension
to build and install the VS Code extension for Untangled syntax highlighting. Requires VS Code, a recent version of Node.js, and thecode
command in your PATH. - Run
make docs
to generate a PDF of the Language Reference Manual. The generated PDF appears atdocs/untangled.pdf
. Requires a recent version Node.js. - Run
make test-ast
to run all ast tests inside of the tests/ast folder - Run
make test-semant
to run all tests inside of the tests/semant folder - Run
make test-e2e
to run all tests inside of the tests/e2e folder - Run
make clean
to remove artifacts of all of these
You can invoke the test script directly using python3 tests
to pass additional command line
arguments. Note that in this case, it is your responsibility to run make
first to ensure the
executable is up to date.
python3 tests --filter e2e/real-programs/factorial e2e/real-programs/string-of-int ...
runs only the specified tests- Use wildcards like
python3 tests --filter "ast/*" "e2e/real-programs/*" ...
to run all the tests inside a folder (including nested subfolders)
- Use wildcards like
python3 tests --record-ground-truths
writes new.gt
ground truths for all testspython3 tests --record-ground-truths test1 pattern2 ...
writes new.gt
ground truths for the specified tests (following the filter syntax above).
Tests are written as .unt
files nested inside the tests
folder. Within the /tests
folder, there are subfolders for different “levels” of tests; each level tests a progressively
further stage of compiler execution.
tests/ast
- tests that check the pretty-printed abstract syntax trees of several Untangled programs against ground truthstest/sast
- tests that check the pretty-printed semantically-checked ASTs of several Untangled programs against ground truths (these are ASTs with additional semantic information added in)test/e2e
- end-to-end (integration) tests that compile, link, and execute full Untangled programs if there are no semantic errors, capturing what they write tostdout
and comparing against ground truths.
A given “level” of tests may optionally also be subdivided further into “test groups,” which have no special function other than to organize test files and to make it easier to run only a subset of tests at a time.
For each set of tests, comparing the output against a gold standard allows us to ensure that the compiler behaves correctly. For the end-to-end tests, we intentionally write programs such that the printed output is sufficient to assess the correctness of a given test run.
The following integration tests are currently included:
tests/e2e/basics/hello-world.unt
- a simple program which prints the string "Hello, World!" from the main threadtests/e2e/basics/reassign.unt
- a simple program that reassigns the value of a variable and prints the new value of the variabletests/e2e/basics/scope.unt
- a simple program that has multiple variable declarations that shadow each other. It prints the variable at difernt moments in time to verify that the appropriate variable shadowstests/e2e/basics/variable-declaration.unt
- a simple program that declares and initializes a variable and then prints ittests/e2e/basics/exit.unt
- tests thatexit()
terminates the program with status is 0tests/e2e/basics/failure-nonzero-exit.unt
- tests thatexit()
terminates the program with status 1
tests/e2e/binop/string-concat-var.unt
- a simple program that declares and initializes multiple strings, concatenates them and prints the resulttests/e2e/binop/concat.unt
- a simple program that concatenates to string literals and prints themtests/e2e/binop/string_equality.unt
- a simple program that compares strings of multiple different types against each other and prints specific output according to the resulttests/e2e/binop/bool-binop.unt
- tests binary operations on boolean valuestests/e2e/binop/failure-int-pow.unt
- tests that power operation fails when the base is 0 and the exponent is negativetests/e2e/binop/failure-float-pow.unt
- tests the power operation on float typestests/e2e/binop/int-pow.unt
- tests the power operation on integer typestests/e2e/binop/address/array-comparison
- tests equality for array typestests/e2e/binop/address/semaphore-comparison
- tests equality for array typestests/e2e/binop/address/thread-comparison
- tests equality for thread typestests/e2e/binop/address/tuple-comparison
- tests equality for tuple types
tests/e2e/builtin/bool_of_string.unt
- tests boolean to string conversiontests/e2e/builtin/failure-bool_of_string.unt
- tests that the program raises an assertion if the argument is not a boolean valuetests/e2e/builtin/failure-float-of-string.unt
- tests that the program raises an assertion if the argument can't be converted from a float to a stringtests/e2e/builtin/failure-int-of-string.unt
- tests that the program raises an assertion if the argument can't be converted from an integer to a stringtests/e2e/builtin/float_to_int.unt
- tests converting a float type to an integer typetests/e2e/builtin/int_to_float.unt
- tests converting an integer type to a float typetests/e2e/builtin/make_semaphore.unt
- tests the builtin functionmake_semaphore
successfully initializes a semaphorenumber_of_string
- tests builtin functions to convert integer and float types to stringtests/e2e/builtin/string_of.unt
- a simple program that converts variables of multiple types (bool, float, int) to strings and prints the result
tests/e2e/control-flow/for-loop/unt
- tests that for loops execute properly by printing in the for loop's bodytests/e2e/control-flow/functions.unt
- a simple program that calls a function in different ways and and generates output both inside the function and based on the return value of the function.tests/e2e/control-flow/if.unt
- a simple program that has if statements with boolean literals inside of them. According to the predicate passed to the if statements, different values are printed out.tests/e2e/control-flow/while.unt
- a simple program that concatenates 'X' to an empty string in a loop. The final string is printed in order to test the accuracy of the number of iterations.
tests/e2e/failing/declaration/failure-arent.unt
- a simple program that tries to declare "parent" which is a protected keywordtests/e2e/failing/declaration/failure-self.unt
- a simple program that tries to declare “self” which is a protected keyword
tests/e2e/failing/receive/failure-non-exhaustive.unt
- a simple program that does not pattern-match exhaustively on the receive statementtests/e2e/failing/receive/failure-pattern-out-of-scope.unt
- a simple program that tries to access a variable declared in a specific receive case is not available elsewheretests/e2e/failing/receive/failure-redclaration.unt
- checks that a semantic error is raised if the same identifier is used in a pattern
tests/e2e/function/array-arg.unt
- tests that functions can receive array as arguments and ensure that array arguments are passed by referencetests/e2e/function/clash-name.unt
- tests that ensure functions can share the same identifier with threadstests/e2e/function/factorial.unt
- a factorial implementation to test recursiontests/e2e/function/fib.unt
- a fibonacci calculator to test recursiontests/e2e/function/return-non-primitives.unt
- tests that arrays and tuples are returned as referencestests/e2ed/send-thread.unt
- sends a thread handler as a function argument and receive a message from the functiontests/e2e/tuple-arg.unt
- tests that ensure functions can receive tuple as arguments and ensure that tuples are immutable
tests/e2e/non-primitives/array-extract.unt
- tests index and assignment operationstests/e2e/non-primitives/array-literal.unt
- tests array literal are correctly constructed by printing its contenttests/e2e/non-primitives/failure-array-oob.unt
- tests that an out of bound array indexing raises an exceptiontests/e2e/non-primitives/sem-op.unt
- tests that semaphores can properly incremented and decremented without deadlocking the programtests/e2e/non-primitives/tuple-unpack.unt
- tests that a tuple can be unpacked
tests/e2e/real-programs/lame-merge-sort.unt
- a merge sort implementation using a recursive functiontests/e2e/real-programs/lrm-program.unt
- tests the program proposed in the LRM that spawns 2 threads, each of which computes the sum concurrentlytests/e2e/real-programs/merge-sort.unt
- a merge sort implementation usingthread_def
instances. The implementation is similar to a recursive function, except that the computations are done usingthread_def
instancestests/e2e/real-programs/proposal-primes.unt
- tests the Mersenne prime checker from the LRM usingthread_def
instancestests/e2e/real-programs/string-of-int.unt
- implements a function to “stringify” an integer value in pure Untangled (i.e. without using the built-instring_of_int
function)
tests/e2e/threading/basic-spawn.unt
- spawns a thread, which prints the string "HELLO"tests/e2e/threading/send-and-receive.unt
- spawns a thread and send to child thread literals primitivesstring
,int
,boolean
,float
, andtuple
. The child thread that it receives the message from the message queue by printing out the received value in order.tests/e2e/threading/send-child-float.unt
- spawns a thread and send the child a float. The child receives the integer and prints ittests/e2e/threading/send-child-tuple.unt
- spawns a thread and send the child a tuple. The child receives the tuple and prints ittests/e2e/threading/send-parent.unt
- spawns a child thread which sends a message to its parent. The parent receives the message and prints ittests/e2e/threading/array-variable-send-receive.unt
- Spawns a thread and sends 3 different representations of arrays. Checks to see that all three match the correct receive casetests/e2e/threading/end-thread.unt
- Checks whether the end function in a thread will only end its corresponding thread's execution.- j
tests/e2e/threading/exit-from-thread.unt
- Checks that an exit function will end the execution of the entire program. tests/e2e/threading/mutex-test.unt
- Checks that the semaphore actually locks by changing the order of a print sequence.tests/e2e/threading/mutexed-array.unt
- Checks that asemaphore can be used toeliminate data races. (matched withtests/e2e/threading/unmutexed-array.unt
)tests/e2e/threading/nested-receive.unt
- Checks whether it is possible to nest receive statements.tests/e2e/threading/self-send-self.unt
-Checs that a thread can send a message to itself.tests/e2e/threading/send-array-tuple-second.unt
- Checks pattern matching on a tuple that contains an arraytests/e2e/threading/send-child-array.unt
- Checks that a child thread can safely send an array containing value to its parenttests/e2e/threading/send-child-int.unt
- spawns a thread and send the child an integer. The child receives the integer and prints ittests/e2e/threading/send-child-string.unt
- Checks that sending a string does worktests/e2e/threading/send-other.unt
- Checks that sending threads works properlytests/e2e/threading/send-self.unt
- Checks that sending the self thread works as expectedtests/e2e/threading/send-semaphore.unt
- Checks that sending a semaphore works as expected and sends a reference that can be used frommultiple placestests/e2e/threading/tuple-variable-send-receive.unt
- Checks that all 3 different ways of sending tuples works with pattern matchingtests/e2e/threading/undefine-values.unt
- Checks that undefined values do not break our pattern matching algorithmtests/e2e/threading/unmutexed-array.unt
- Replicates the data race conditions (corresponds to thetests/e2e/threading/mutexed-array.unt
)tests/e2e/threading/wildcard-pattern.unt
- Tests that the wilcard patterns within tuples work.
tests/e2e/unop/unop.unt
- Performs unary operations and prints their results to ensure they match the expected result
The MDX file at docs/src/main.mdx
(MDX is Markdown with support for React components) is the
source file for the Language Reference Manual. You can edit it like a normal markdown file. You can
also define additional react components in docs/src/components
, and then import/use them in the
MDX file.
While writing, you can run npm run dev
from inside the docs
folder to start a local server that
will render a preview of the LRM, and auto-refresh when you make changes.
Running make docs
from the project root will automatically generate a PDF of the LRM.