summaryrefslogtreecommitdiff
path: root/src/rewriter.ml
AgeCommit message (Collapse)Author
2018-08-28add __POS__ argument to Err_unreachable for better error reportingJon French
2018-08-24Fix rewriter issuesAlasdair Armstrong
Allow pat_lits rewrite to map L_unit to wildcard patterns, rather than introducing eq_unit tests as guards. Add a fold_function and fold_funcl functions in rewriter.ml that apply the pattern and expression algebras to top-level functions, which means that they correctly get applied to top-level function patterns when they are used. Currently modifying the re-writing passes to do this introduces some bugs which needs investigated further. The current situation is that top-level patterns and patterns elsewhere are often treated differently because rewrite_exp doesn't (and indeed cannot, due to how the re-writer is structured) rewrite top level patterns. Fix pattern completeness check for unit literals Fix a bug in Sail->ANF transform where blocks were always annotated with type unit incorrectly. This caused issues in pattern literal re-writes where the guard was a block returning a boolean. A test case for this is added as test/c/and_block.sail. Fix a bug caused by nested polymorphic function calls and matching in top-level patterns. Test case is test/c/tl_poly_match.sail. Pass location info through codegen_conversion for better error reporting
2018-08-23Move vector_string_to_bit_list from its odd place in Rewriter.rewrite_pat to ↵Jon French
an explicit rewrite step in Rewrites, just before pat_lits
2018-08-18Correctly specialise type annotation in polymorphic functionsAlasdair
2018-08-17Extend guarded patterns rewriting to exception catchingBrian Campbell
Also fix nested matches and generic rewriting under E_throw.
2018-08-07Revert "Warnings: deal with all the deprecation warnings"Alasdair Armstrong
One day we will be free from the 4.02.3 menace, but today is not that day. :( This should fix Sail on Jenkins This reverts commit 86e29bcbb1597c4ef1f6cae8edbeed42f9a31414.
2018-07-27Make type annotations abstract in type_check.mliAlasdair Armstrong
Rather than exporting the implementation of type annotations as type tannot = (Env.t * typ * effect) option we leave it abstract as type tannot Some additional functions have been added to type_check.mli to work with these abstract type annotations. Most use cases where the type was constructed explicitly can be handled by using either mk_tannot or empty_tannot. For pattern matching on a tannot there is a function val destruct_tannot : tannot -> (Env.t * typ * effect) option Note that it is specifically not guaranteed that using mk_tannot on the elements returned by destruct_tannot re-constructs the same tannot, as destruct_tannot is only used to give the old view of a type annotation, and we may add additional information that will not be returned by destruct_tannot.
2018-07-26Some tweaks to not and or patternsAlasdair Armstrong
- Fix ambiguities in parser.mly - Ensure that no new identifiers are bound in or-patterns and not-patterns, by adding a no_bindings switch to the environment. These patterns shouldn't generate any bogus flow typing constraints because we just pass through the original environment without adding any possible constraints (although this does mean we don't get any flow typing from negated numeric literals right now, which is a TODO). - Reformat some code to match surrounding code. - Add a typechecking test case for not patterns - Add a typechecking test case for or patterns At least at the front end everything should work now, but we need to do a little bit more to rewrite these patterns away for lem etc.
2018-07-26Patterns: add or and not patternsAlastair Reid
These match the new ASL pattern constructors: - !p matches if the pattern p does not match - { p1, ... pn } matches if any of the patterns p1 ... pn match We desugar the set pattern "{p1, ... pn}" into "p1 | (p2 | ... pn)". ASL does not have pattern binding but Sail does. The rules at the moment are that none of the pattern can contain patterns. This could be relaxed by allowing "p1 | p2" to bind variables provided p1 and p2 both bind the same variables.
2018-07-26Warnings: deal with all the deprecation warningsAlastair Reid
Changes are: - String.capitalize -> String.capitalize_ascii - String.uppercase -> String.uppercase_ascii - String.lowercase -> String.lowercase_ascii Basically just making the change that the warning message suggested.
2018-07-25Remove unused internal AST nodesAlasdair Armstrong
E_internal_cast, E_sizeof_internal, E_internal_exp, E_internal_exp_user, E_comment, and E_comment_struc were all unused. For a lem based interpreter, we want to be able to compile it to iUsabelle, and due to slowness inherent in Isabelle's datatype package we want to remove unused constructors in our AST type. Also remove the lem_ast backend - it's heavily bitrotted, and for loading the ARM ast into the interpreter it's just not viable to use this approach as it just doesn't scale. We really need a way to be able to serialise and deserialise the AST efficiently in Lem.
2018-06-26Add configuration registers so __SetConfig ASL can be translatedAlasdair Armstrong
Registers can now be marked as configuration registers, for example: register configuration CFG_RVBAR = 0x1300000 They work like ordinary registers except they can only be set by functions with the 'configuration' effect and have no effect when read. They also have an initialiser, like a let-binding. Internally there is a new reg_dec constructor DEC_config. They are intended to represent configuration parameters for the model, which can change between runs, but don't change during execution. Currently they'll only work when compiled to C. Internally registers can now have custom effects for reads and writes rather than just rreg and wreg, so the type signatures of Env.add_register and Env.get_register have changed, as well as the Register lvar, so in the type checker we now write: Env.add_register id read_effect write_effect typ rather than Env.add_register id typ For the corresponding change to ASL parser there's a function is_config in asl_to_sail.ml which controls what becomes a configuration register for ARM. Some things we have to keep as let-bindings because Sail can't handle them changing at runtime - e.g. the length of vectors in other top-level definitions. Luckily __SetConfig doesn't (yet) try to change those options. Together these changes allow us to translate the ASL __SetConfig function, which means we should get command-line option compatibility with ArchEx for running the ARM conformance tests.
2018-05-10Merge branch 'sail2' into mappingsJon French
2018-05-04Rename type vars in Coq backend when they clash with identifiersBrian Campbell
Add value-only version of compute_{pat,exp}_alg to help Experiment with adding equality constraints between type vars and args in Coq output
2018-05-03Flow typing and l-expression changes for ASL parserAlasdair Armstrong
1. Experiment with allowing some flow typing on mutable variables for translating ASL in a more idiomatic way. I realise after updating some of the test cases that this could have some problematic side effects for lem translation, where mutable variables are translated into monadic code. We'd need to ensure that whatever flow typing happens for mutable variables also works for monadic code, including within transformed loops. If this doesn't work out some of these changes may need to be reverted. 2. Make the type inference for l-expressions a bit smarter. Splits the type checking rules for l-expressions into a inference part and a checking part like the other bi-directional rules. Should not be able to type check slightly more l-expresions, such as nested vector slices that may not have checked previously. The l-expression rules for vector patterns should be simpler now, but they are also more strict about bounds checking. Previously the bounds checks were derived from the corresponding operations that would appear on the RHS (i.e. LEXP_vector would get it's check from vector_access). This meant that the l-expression bounds checks could be weakend by weakening the checks on those operations. Now this is no longer possible, there is a -no_lexp_bounds_check option which turns of bounds checking in l-expressions. Currently this is on for the generated ARM spec, but this should only be temporary. 3. Add a LEXP_vector_concat which mirrors P_vector_concat except in l-expressions. Previously there was a hack that overloaded LEXP_tup for this to translate some ASL patterns, but that was fairly ugly. Adapt the rewriter and other parts of the code to handle this. The rewriter for lexp tuple vector assignments is now a rewriter for vector concat assignments. 4. Include a newly generated version of aarch64_no_vector 5. Update the Ocaml test suite to use builtins in lib/
2018-05-02refactor string append pattern ast to be based on lists rather than pairsJon French
2018-05-01mostly added mappings to type-checker and pretty-printerJon French
2018-05-01start of string pattern matching: currently only literalsJon French
2018-04-26Avoid adding explicit type annotations with generated type variablesThomas Bauereiss
2018-04-26Make effect propagation in rewriter more efficientThomas Bauereiss
Use non-recursive fix_eff_exp instead of recursive propagate_exp_effect, assuming that the effects of subexpressions have already been fixed by the recursive calls of the rewriter.
2018-02-16Avoid nested explicit type annotationsThomas Bauereiss
Isabelle does not like nested annotations like "((exp :: typ) :: typ)".
2018-02-05Add typ patterns for destructuring existentialsAlasdair Armstrong
2018-01-12Merge remote-tracking branch 'origin/experiments' into sail2Alasdair Armstrong
2018-01-12OCaml interactive mode can now run full aarch64 examples, and ocaml test cases.Alasdair Armstrong
2018-01-03Lots of experimental changes on this branchAlasdair Armstrong
* Changed comment syntax to C-style /* */ and // * References to registers and mutable variables are never created implicitly - a reference to a register or variable R is now created via the expression "ref R". References are assigned like "(*Y) = X", with "(*ref R) = X" being equivalent to "R = X". Everything is always explicit now, which simplifies the logic in the typechecker. There's also now an invariant that every id directly in a LEXP is mutable, which is actually required for our rewriter steps to be sound. * More flexible syntax for L-expressions to better support wierd power-idioms, some syntax sugar means that: X.GET(a, b, c) ==> _mod_GET(X, a, b, c) X->GET(a, b, c) ==> _mod_GET(ref X, a, b, c) for setters, this can be combined with the (still somewhat poorly named) LEXP_memory construct, such that: X->SET(a, b, c) = Y ==> _mod_SET(ref X, a, b, c, Y) Currently I use the _mod_ prefix for these 'modifier' functions, but we could omit that a la rust. * The register bits typedef construct no longer exists in the typechecker. This construct never worked consistently between backends and inc/dec vectors, and it can be easily replaced by structs with fancy setters/getters if need be. One can also use custom type operators to mimic the syntax, i.e. type operator ... ('n : Int) ('m : Int) = slice('n, 'm) struct cr = { CR0 : 32 ... 35, /* 32 : LT; 33 : GT; 34 : EQ; 35 : SO; */ CR1 : 36 ... 39, /* 36 : FX; 37 : FEX; 38 : VX; 39 : OX; */ CR2 : 40 ... 43, CR3 : 44 ... 47, CR4 : 48 ... 51, CR5 : 52 ... 55, CR6 : 56 ... 59, CR7 : 60 ... 63, } This greatly simplifies a lot of the logic in the typechecker, as it means that E_field is no longer ambiguously overloaded between records and register bit typedefs. This also makes writing semantics for these constructs much simpler.
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-14Fix all compiler warning except in lem pretty printer and monomorphisationAlasdair Armstrong
2017-12-13Use big_nums from LemAlasdair Armstrong
2017-12-07More OCaml test casesAlasdair Armstrong
Improved handling of try/catch Better handling of unprovable constraints when the environment contains false
2017-12-07Fix regressions in OCaml outputAlasdair Armstrong
Recent patches have made the rewriter more strict about performing type correct rewrites. This is mostly a good thing but did cause some problems with the ocaml backend. Currently the sizeof rewriter doesn't seem to preserve type correctness - I suspect this is because when it resolves the sizeofs, it generates constraints that are true, but not in a form where the typechecker can see that they are true. I disabled the re-check after the sizeof rewriting pass to fix this. Maybe we don't want to do this anyway because it's slow. Changes to function clauses with guards + monomorphisation changed how the typechecker handles literal patterns. I added a rewriting pass to rewrite literals to guarded equality checks, which is run before generating ocaml. The rewriter currently uses Env.empty in a view places. This can cause bugs because Env.empty is a totally unitialised environment that doesn't satisfy invariants we expect of an environment. This should be changed to initial_env and it shouldn't be exported, I fixed a few cases where this caused things to go wrong, but it should probably not be exported from Type_check.ml.
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-05Better support for exceptions in sail for ASL specs that need them.Alasdair Armstrong
2017-12-05Update license headers for Sail sourceAlasdair Armstrong
2017-11-27Split rewriter into separate rewriting library and rewrite passesAlasdair Armstrong
As discussed previously, we wanted to start refactoring the re-writer to make it a bit less monolithic, and in the future potentially break it into separate files for backend-specific rewrites and stuff. - rewriter.ml now contains the generic re-writing code - rewrites.ml contains the rewriting passes themselves It would be nice if the generic rewriting code didn't depend on the typechecker, because then it could be used in ASL parser on untyped code.
2017-11-27Merge branch 'experiments' of https://bitbucket.org/Peter_Sewell/sail into ↵Alasdair Armstrong
experiments
2017-11-27Compile assertions into OCamlAlasdair Armstrong
and_bool and or_bool now are treated specially in the ocaml backend, so that they have the correct short-circuiting behaviour. This is required so that assertions don't fail for the ARM spec for predicates that shouldn't be tested in certain circumstances, for example things like: IsAArch32() && AArch32_specific_predicate Also fixed an issue in the sail library for ocaml where greater than or equal to was being mapped to greater than.
2017-11-27Fix bitvector pattern removal typoBrian Campbell
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-10Fixed some tricky typechecking bugsAlasdair Armstrong
2017-11-07Fix typo in constraint rewriterThomas Bauereiss
2017-11-07Declare prelude functions as externThomas Bauereiss
Also, rename a few functions for uniformity, e.g. bool_and -> and_bool
2017-11-03Fixed a bug where true and false get mixed up in rewriterAlasdair Armstrong
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
2017-11-02Fix translation of repeat-until loops to LemThomas Bauereiss
2017-10-31Pretty-print Sail assertions in LemThomas Bauereiss
Map to calls to monadic function assert_exp that throws an exception if the assertion is false
2017-10-31Remove redundant nexp simplification functionThomas Bauereiss