summaryrefslogtreecommitdiff
path: root/src/pretty_print_lem.ml
AgeCommit message (Collapse)Author
2018-04-26Lem: Add Size class annotations for nested bitvector typesThomas Bauereiss
2018-04-18Fix bug in pretty-printing loops to LemThomas Bauereiss
2018-04-09Stop vector_typ_args_of from failing when order is a variableBrian Campbell
Now it just returns the actual arguments and a separate function calculates the start index when required.
2018-04-04Use solver properly to simplify nexps in mono analysis, Lem printingBrian Campbell
Turn on complex nexp rewriting for mono by default (NB: solving is currently quite slow, will optimise)
2018-04-04Initial rewrite to move complex nexps in fn sigs into constraintsBrian Campbell
(for monomorphisation, off for now because the analysis needs extended). Also tighten up orig_nexp, make Lem backend replace # in type variables.
2018-03-23Fix indentation of loops in generated IsabelleThomas Bauereiss
2018-03-22Tune Lem pretty-printingThomas Bauereiss
In particular, improve indentation of if-expressions, and provide infix syntax for monadic binds in Isabelle, allowing Lem to preserve source whitespace.
2018-03-14Make partiality more explicit in library functions of Lem shallow embeddingThomas Bauereiss
Some functions are partial, e.g. converting a bitvector to an integer, which might fail for the bit list representation due to undefined bits. Undefined cases can be handled in different ways: - call Lem's failwith, which maps to undefined/ARB in Isabelle and HOL (the default so far), - return an option type, - raise a failure in the monad, or - use a bitstream oracle to resolve undefined bits. This patch adds different versions of partial functions corresponding to those options. The desired behaviour can be selected by choosing a binding in the Sail prelude. The naming scheme is that the failwith version is the default, while the other versions have the suffixes _maybe, _fail, and _oracle, respectively.
2018-03-14Add rewriting step for moving execute clauses into auxiliary functionsThomas Bauereiss
For example, generates an auxiliary function execute_ADD (rs, rt, rd) for the clause execute (ADD (rs,rt,rd)) = ... Without this rewriting, the execute function easily becomes too large to be handled by Isabelle (e.g., for CHERI-MIPS; for MIPS alone, it seems to be just about small enough). This used to be implemented in the pretty-printer, but that code was commented out recently in order to support a recursive execute function for RISC-V compressed instructions.
2018-03-13Merge funcls for Lem output, making it suitable for testing with OCamlBrian Campbell
2018-03-07Make union types consistent in the ASTAlasdair Armstrong
Previously union types could have no-argument constructors, for example the option type was previously: union option ('a : Type) = { Some : 'a, None } Now every union constructor must have a type, so option becomes: union option ('a : Type) = { Some : 'a, None : unit } The reason for this is because previously these two different types of constructors where very different in the AST, constructors with arguments were used the E_app AST node, and no-argument constructors used the E_id node. This was particularly awkward, because it meant that E_id nodes could have polymorphic types, i.e. every E_id node that was also a union constructor had to be annotated with a type quantifier, in constrast with all other identifiers that have unquantified types. This became an issue when monomorphising types, because the machinery for figuring out function instantiations can't be applied to identifier nodes. The same story occurs in patterns, where previously unions were split across P_id and P_app nodes - now the P_app node alone is used solely for unions. This is a breaking change because it changes the syntax for union constructors - where as previously option was matched as: function is_none opt = match opt { Some(_) => false, None => true } it is now matched as function is_none opt = match opt { Some(_) => false, None() => true } note that constructor() is syntactic sugar for constructor(()), i.e. a one argument constructor with unit as it's value. This is exactly the same as for functions where a unit-function can be called as f() and not as f(()). (This commit also makes exit() work consistently in the same way) An attempt to pattern match a variable with the same name as a union-constructor now gives an error as a way to guard against mistakes made because of this change. There is probably an argument for supporting the old syntax via some syntactic sugar, as it is slightly prettier that way, but for now I have chosen to keep the implementation as simple as possible. The RISCV spec, ARM spec, and tests have been updated to account for this change. Furthermore the option type can now be included from $SAIL_DIR/lib/ using $include <option.sail>
2018-02-26Add/generate Isabelle lemmas about the monad liftingThomas Bauereiss
Architecture-specific lemmas about concrete registers and types are generated and written to a file <prefix>_lemmas.thy, generic lemmas are in the theories *_extras.thy in lib/isabelle. In particular, State_extras contains simplification lemmas about the lifting from prompt to state monad.
2018-02-20Report unsupported nexps properly in Lem backendBrian Campbell
2018-02-20Look for alternative size annotations when pretty printing LemBrian Campbell
(so that we get enough type annotations for bitvectors)
2018-02-16Avoid nested explicit type annotationsThomas Bauereiss
Isabelle does not like nested annotations like "((exp :: typ) :: typ)".
2018-02-15Rebase state monad onto prompt monadThomas Bauereiss
Generate only one Lem model based on the prompt monad (instead of two models with different monads), and add a lifting from prompt to state monad. Add some Isabelle lemmas about the monad lifting. Also drop the "_embed" and "_sequential" suffixes from names of generated files.
2018-02-15Re-engineer prompt monad of Lem shallow embeddingThomas Bauereiss
- Use simplified monad type (e.g., without the with_aux constructors that are not needed by the shallow embedding). - Add support for registers with arbitrary types (e.g., records, enumerations, vectors of vectors). Instead of using bit lists as the common representation of register values at the monad interface, use a register_value type that is generated per spec as a union of all register types that occur in the spec. Conversion functions between register_value and concrete types are generated. - Use the same representation of register references as the state monad, in preparation of rebasing the state monad onto the prompt monad. - Split out those types from sail_impl_base.lem that are used by the shallow embedding into a new module sail_instr_kinds.lem, and import that. Removing the dependency on Sail_impl_base from the shallow embedding avoids name clashes between the different monad types. Not yet done: - Support for reading/writing register slices. Currently, a rewriting pass pushes register slices in l-expressions to the right-hand side, turning a write to a register slice into a read-modify-write. For interfacing with the concurreny model, we will want to be more precise than that (in particular since some specs represent register files as big single registers containing a vector of bitvectors). - Lemmas about the conversion functions to/from register_value should be generated automatically.
2018-02-05Merge changes to type_check.mlAlasdair Armstrong
2018-02-05Add typ patterns for destructuring existentialsAlasdair Armstrong
2018-02-01Comment out special casing of execute function in Lem pretty-printerThomas Bauereiss
It assumes that execute is non-recursive, which is not the case for RISC-V with compressed instructions. Splitting execute into different auxiliary functions for each clause is probably still useful, as Isabelle is likely to parse many small functions faster than one big (potentially recursive) function, but this splitting should be done in the rewriter instead of the pretty-printer, in order to properly deal with recursion.
2018-01-31Split base definitions of Lem monads and further built-ins (e.g. loop ↵Thomas Bauereiss
combinators) Add Isabelle-specific theories imported directly after monad definitions, but before other combinators. These theories contain lemmas that tell the function package how to deal with monadic binds in function definitions.
2018-01-29Output a few more type annotations for LemThomas Bauereiss
Allow pretty-printing of existential types, if the existentially quantified variables do not actually appear in the Lem output. This is useful for the bit list representation of bitvectors, as it will print the type annotation "list bitU" for bitvectors whose length depends on an existentially quantified variable.
2018-01-23Run tests for Lem shallow embeddingThomas Bauereiss
Uses the typechecker tests for now. Also fix two minor bugs in pretty-printer and rewriter uncovered by the tests.
2018-01-22Update Lem shallow embedding to Sail2Thomas Bauereiss
- Remove vector start indices - Library refactoring: Definitions in sail_operators.lem now use Bitvector type class and work for both bit list and machine word representations - Add Lem bindings to AArch64 and RISC-V preludes TODO: Merge specialised machine word operations from sail_operators_mwords into sail_operators.
2018-01-18Merge remote-tracking branch 'origin/experiments' into sail2Alasdair Armstrong
2018-01-17Fix use of nexps in type annotations when not using machine wordsThomas Bauereiss
2018-01-16Output more type annotations in Lem backendThomas Bauereiss
Keep track of which type variables have been bound in the function declaration, and allow those to be pretty-printed
2018-01-12Merge remote-tracking branch 'origin/experiments' into sail2Alasdair Armstrong
2018-01-05Added bitfield syntax to replicate register bits typeAlasdair Armstrong
For example: bitfield cr : vector(8, dec, bit) = { CR0 : 7 .. 4, LT : 7, CR1 : 3 .. 2, CR2 : 1, CR3 : 0, } The difference this creates a newtype wrapper around the vector type, then generates getters and setters for all the fields once, rather than having to handle this construct separately in every backend.
2018-01-03Updates to interpreterAlasdair Armstrong
Experimenting with porting riscv model to new typechecker
2018-01-02Experimenting with power specAlasdair Armstrong
2017-12-19Support user-defined exceptions in Lem shallow embeddingThomas Bauereiss
The type-checker already supports a user-defined "exception" type that can be used in throw and try-catch expressions. This patch adds support for that to the Lem shallow embedding by adapting the existing exception mechanisms of the state and prompt monads. User-defined exceptions are distinguished from builtin exception cases. For example, the state monad uses type ex 'e = | Exit | Assert of string | Throw of 'e to distinguish between calls to "exit", failed assertions, and user-defined exceptions, respectively. Early return is also handled using the exception mechanism, by lifting to a monad with "either 'r exception" as the exception type, where 'r is the expected return type and "exception" is the user-defined exception type.
2017-12-19Fix a bug in untupling function arguments for LemThomas Bauereiss
Was missing the case where the tuple of arguments is bound against a single variable using P_id (not P_as). Now replaces that with the expected number of argument variables, and rebinds the single variable in the body, as for the other cases.
2017-12-14An experimental version of sail without bitvector start indexes.Alasdair Armstrong
Works with the vector branch of asl_parser
2017-12-14Un-tuple function arguments when pretty-printing to LemThomas Bauereiss
This makes Lem prefer plain "definition" when generating Isabelle output for functions, which is processed by Isabelle much faster than "fun"/"function" definitions. This change is not complete yet, because the Sail library functions still need to be changed to not use tupled arguments (possibly as part of a bigger refactoring of the library). For now, external functions are special-cased in the pretty-printer and get tupled arguments.
2017-12-14Make sequential and mwords global variables in Lem pretty-printerThomas Bauereiss
2017-12-13Use big_nums from LemAlasdair Armstrong
2017-12-06Add top-level pattern match guards internallyBrian Campbell
Also fix bug in mono analysis with generated variables Breaks lots of typechecking tests because it generates unnecessary equality tests on units (and the tests don't have generic equality), which I'll fix next.
2017-12-06Merge remote branch 'experiments' into experimentsThomas Bauereiss
2017-12-06Make AST after rewriting for Lem backend type-checkableThomas Bauereiss
- Add support for some internal nodes to type checker - Add more explicit type annotations during rewriting - Remove hardcoded rewrites for E_vector_update etc from Lem pretty-printer; these will be resolved by the type checker during rewriting now
2017-12-05Update license headers for Sail sourceAlasdair Armstrong
2017-11-30Use doc_typdef_lem from experimentsAlasdair Armstrong
2017-11-30Merge branch 'master' into experimentsAlasdair Armstrong
2017-11-24Use unbound precision big_ints throughout sail.Alasdair Armstrong
Alastair's test cases revealed that using regular ints causes issues throughout sail, where all kinds of things can internally overflow in edge cases. This either causes crashes (e.g. int_of_string fails for big ints) or bizarre inexplicable behaviour. This patch switches the sail AST to use big_int rather than int, and updates everything accordingly. This touches everything and there may be bugs where I mistranslated things, and also n = m will still typecheck with big_ints but fail at runtime (ocaml seems to have decided that static typing is unnecessary for equality...), as it needs to be changed to eq_big_int. I also got rid of the old unused ocaml backend while I was updating things, so as to not have to fix it.
2017-11-16Remove unused Typ_wild constructorAlasdair Armstrong
2017-11-08Allow functions to be selectively declared external only for some backendsThomas Bauereiss
For example, val test = { ocaml: "test_ocaml" } : unit -> unit will only be external for OCaml. For other backends, it will have to be defined.
2017-11-08Allow for different extern names for different backendsAlasdair Armstrong
For example: val test = { ocaml: "test_ocaml", lem: "test_lem" } : unit -> unit val main : unit -> unit function main () = { test (); } for a backend not explicitly provided, the extern name would be simply "test" in this case, i.e. the string version of the id. Also fixed some bugs in the ocaml backend.
2017-11-03Make sure simple parameter sizes appear in Lem mwords outputBrian Campbell
2017-11-02Merge branch 'experiments'Thomas Bauereiss
2017-11-02Optionally generate an initial register state for the sequential Lem shallow ↵Thomas Bauereiss
embedding Checks for command-line flag -undefined_gen and uses the undefined value generator functions of the form undefined_typ to initialise registers