summaryrefslogtreecommitdiff
path: root/src/initial_check.ml
AgeCommit message (Collapse)Author
2019-02-08Add parameterization support for bitfields.Prashanth Mundkur
This supports the following syntax: type xlen : Int = 64 type ylen : Int = 1 type xlenbits = bits(xlen) bitfield Mstatus : xlenbits = { SD : xlen - ylen, SXL : xlen - ylen - 1 .. xlen - ylen - 3 }
2019-02-08Allow internal AST nodes in input when -dmagic_hash is onBrian Campbell
2019-02-06Emacs mode understands relationships between Sail filesAlasdair
Allow a file sail.json in the same directory as the sail source file which contains the ordering and options needed for sail files involved in a specific ISA definition. I have an example for v8.5 in sail-arm. The interactive Sail process running within emacs then knows about the relationship between Sail files, so C-c C-l works for files in the ARM spec. Also added a C-c C-x command to jump to a type error. Requires yojson library to build interactive Sail.
2019-01-14Merge remote-tracking branch 'origin/sail2' into asl_flow2Alasdair
2019-01-11Updates for sail-arm releaseAlasdair Armstrong
We want to ensure that no_devices.sail and devices.sail have the same effect footprint, because with a snapshot-type release in sail-arm, we can't rebuild the spec with asl_to_sail every time we switch from running elf binaries to booting OS's. This commit allows registers to have arbitrary effects, so registers that are really representing memory-mapped devices don't have to have the wmem/rmem effect.
2018-12-29Add separate termination_measure declarationsBrian Campbell
2018-12-26More cleanupAlasdair Armstrong
Remove unused name schemes and DEF_kind
2018-12-19Improve sizeof rewriting performanceAlasdair Armstrong
Simply constraints further before calling Z3 to improve performance of sizeof re-writing.
2018-12-13Fix typo in boolean constraint desugaringAlasdair Armstrong
2018-12-13Merge remote-tracking branch 'origin/sail2' into asl_flowAlasdair
2018-12-12Add a test case for various simple boolean propertiesAlasdair Armstrong
test/typecheck/pass/tautology.sail constaints tests of various boolean properties, e.g. // de Morgan _prove(constraint(not('p | 'q) <--> not('p) & not('q))); _prove(constraint(not('p & 'q) <--> not('p) | not('q))); introduce a new _not_prove case which allows us to assert in tests that a constraint is not provable. This test essentially tests that constraints map to sensible problems in the SMT solver, without testing flow typing or any other features. Add a script test/typecheck/update_errors.sh, which regenerates the expected error messages. Testing that type-checking failures is important, but can be brittle when the error messages change for inconsequential reasons. This script automates fixing this. Also ensure that this test case works correctly in Lem
2018-12-12Generalise existentials for non-integer type variablesAlasdair
2018-12-12Remove KOpt_none constructorAlasdair
We should infer type variable kinds better in initial_check.ml, but we really don't want to have to deal with that everywhere, especially when we can no longer easily cheat and assume KOpt_none implies K_int.
2018-12-12Fix various boolean type-variable related issuesAlasdair
Remove some dead code in Pretty_print_common Start thinking a bit about Minisail-esque syntactic sugar in initial_check
2018-12-11Initial attempt at using termination measures in CoqBrian Campbell
This only applies to recursive functions and uses the termination measure merely as a limit to the recursive call depth, rather than proving the measure correct.
2018-12-10Various changes:Alasdair Armstrong
* Improve type inference for numeric if statements (if_infer test) * Correctly handle constraints for existentially quantified constructors (constraint_ctor test) * Canonicalise all numeric types in function arguments, which triggers some weird edge cases between parametric polymorphism and subtyping of numeric arguments * Because of this eq_int, eq_range, and eq_atom etc become identical * Avoid duplicating destruct_exist in Env * Handle some odd subtyping cases better
2018-12-08Compiling againAlasdair
Change Typ_arg_ to A_. We use it a lot more now typ_arg is used instead of uvar as the result of unify. Plus A_ could either stand for argument, or Any/A type which is quite appropriate in most use cases. Restore instantiation info in infer_funapp'. Ideally we would save this instead of recomputing it ever time we need it. However I checked and there are over 300 places in the code that would need to be changed to add an extra argument to E_app. Still some issues causing specialisation to fail however. Improve the error message when we swap how we infer/check an l-expression, as this could previously cause the actual cause of a type-checking failure to be effectively hidden.
2018-12-07Working on better flow typing for ASLAlasdair Armstrong
On a new branch because it's completely broken everything for now
2018-12-06Desugar constraints from atyp rather than n_constraintAlasdair Armstrong
Previously the valid constraints had to be carefully restricted to avoid parser ambiguities between n_constraint and atyp. With the initial check refactored, we can now parse constraints into atyp using ATyp_app for the operators, and changing ATyp_constant into a more general ATyp_lit for true and false. Logically this new structure is more uniform, as atyp is now the parse representation for all Bool-kinded things (constraints), Type-kinded things (regular types), and Int-kinded things (n-expressions), and initial_check.ml now splits all three into n_constraint, typ, and nexp respectively, rather than how it was before with initial_check splitting types and nexps, but constraints already being separate in the parser.
2018-12-06Re-factor initial checkAlasdair Armstrong
Mostly this is to change how we desugar types in order to make us more flexible with what we can parse as a valid constraint as type. Previously the structure of the initial check forced some awkward limitations on what was parseable due to how the parse AST is set up. As part of this, I've taken the de-scattering of scattered functions out of the initial check, and moved it to a re-writing step after type-checking, where I think it logically belongs. This doesn't change much right now, but opens up some more possibilities in the future: Since scattered functions are now typechecked normally, any future module system for Sail would be able to handle them specially, and the Latex documentation backend can now document scattered functions explicitly, rather than relying on hackish 'de-scattering' logic to present documentation as the functions originally appeared. This has one slight breaking change which is that union clauses must appear before their uses in scattered functions, so union ast = Foo : unit function clause execute(Foo()) is ok, but function clause execute(Foo()) union ast = Foo : unit is not. Previously this worked because the de-scattering moved union clauses upwards before type-checking, but as this now happens after type-checking they must appear in the correct order. This doesn't occur in ARM, RISC-V, MIPS, but did appear in Cheri and I submitted a pull request to re-order the places where it happens.
2018-12-04Remove FES_Fexps constructorAlasdair Armstrong
This makes dealing with records and field expressions in Sail much nicer because the constructors are no longer stacked together like matryoshka dolls with unnecessary layers. Previously to get the fields of a record it would be either E_aux (E_record (FES_aux (FES_Fexps (fexps, _), _)), _) but now it is simply: E_aux (E_record fexps, _)
2018-12-04Simplify kinds in the ASTAlasdair Armstrong
Rather than having K_aux (K_kind [BK_aux (BK_int, _)], _) represent the Int kind, we now just have K_aux (K_int, _). Since the language is first order we have no need for fancy kinds in the AST.
2018-11-30Remove constraint synonymsAlasdair Armstrong
They weren't needed for ASL parser like I thought they would be, and they increase the complexity of dealing with constraints throughout Sail, so just remove them. Also fix some compiler warnings
2018-11-30Improvements for ASL parserAlasdair Armstrong
- Fix pretty printing nested constraints - Add flow typing for if condition then { throw exn }; ... blocks - Add optimisations for bitvector concatenation in C
2018-11-09Improvements to latex generationAlasdair Armstrong
The main changes so far are: * Allow markdown formatting in doc comments. We parse the markdown using Omd, which is a OCaml library for parsing markdown. The nice thing about this library is it's pure OCaml and has no dependencies other the the stdlib. Incidentally it was also developed at OCaml labs. Using markdown keeps our doc-comments from becoming latex specfic, and having an actual parser is _much_ nicer than trying to hackily process latex in doc-comments using OCamls somewhat sub-par regex support. * More sane conversion latex identifiers the main approach is to convert Sail identifiers to lowerCamelCase, replacing numbers with words, and then add a 'category' code based on the type of identifier, so for a function we'd have fnlowerCamelCase and for type synonym typelowerCamelCase etc. Because this transformation is non-injective we keep track of identifiers we've generated so we end up with identifierA, identifierB, identifierC when there are collisions. * Because we parse markdown in doc comments doc comments can use Sail identifiers directly in hyperlinks, without having to care about how they are name-mangled down into TeX compatible things. * Allow directives to be passed through the compiler to backends. There are various $latex directives that modify the latex output. Most usefully there's a $latex newcommand name markdown directive that uses the markdown parser to generate latex commands. An example of why this is useful is bellow. We can also use $latex noref id To suppress automatically inserting links to an identifier * Refactor the latex generator to make the overall generation process cleaner * Work around the fact that some operating systems consider case-sensitive file names to be a good thing * Fix a bug where latex generation wouldn't occur unless the directory specified by -o didn't exist This isn't quite all the requested features for good CHERI documentation, but new features should be much easier to add now.
2018-11-07Move inline forall in function definitionsAlasdair Armstrong
* Previously we allowed the following bizarre syntax for a forall quantifier on a function: val foo(arg1: int('n), arg2: typ2) -> forall 'n, 'n >= 0. unit this commit changes this to the more sane: val foo forall 'n, 'n >= 2. (arg1: int('n), arg2: typ2) -> unit Having talked about it today, we could consider adding the syntax val foo where 'n >= 2. (arg1: int('n), arg2: typ2) -> unit which would avoid the forall (by implicitly quantifying variables in the constraint), and be slightly more friendly especially for documentation purposes. Only RISC-V used this syntax, so all uses of it there have been switched to the new style. * Second, there is a new (somewhat experimental) syntax for existentials, that is hopefully more readable and closer to minisail: val foo(x: int, y: int) -> int('m) with 'm >= 2 "type('n) with constraint" is equivalent to minisail: {'n: type | constraint} the type variables in typ are implicitly quantified, so this is equivalent to {'n, constraint. typ('n)} In order to make this syntax non-ambiguous we have to use == in constraints rather than =, but this is a good thing anyway because the previous situation where = was type level equality and == term level equality was confusing. Now all the type type-level and term-level operators can be consistent. However, to avoid breaking anything = is still allowed in non-with constraints, and produces a deprecated warning when parsed.
2018-10-31Rename Reporting_basic to ReportingAlasdair Armstrong
There is no Reporting_complex, so it's not clear what the basic is intended to signify anyway. Add a GitHub issue link to any err_unreachable errors (as they are all bugs)
2018-10-24Add constraint synonymsAlasdair Armstrong
Currently not enabled by default, the flag -Xconstraint_synonyms enables them For generating constraints in ASL parser, we want to be able to give names to the constraints that we attach to certain variables. It's slightly awkward right now when constraints get long complicated because the entire constraint always has to be typed out in full whenever it appears, and there's no way to abstract away from that. This adds constraint synonyms, which work much like type synonyms except for constraints, e.g. constraint Size('n) = 'n in {1, 2, 4, 8} | 128 <= 'n <= 256 these constraints can then be used instead of the full constraint, e.g. val f : forall 'n, where Size('n). int('n) -> unit Unfortunatly we need to have a keyword to 'call' the constraint synonym otherwise the grammer stops being LR(1). This could be resolved by parsing all constraints into Parse_ast.atyp and then de-sugaring them into constraints, which is what happens for n-expressions already, but that would require quite a bit of work on the parser. To avoid this forcing changes to any other parts of Sail, the intended invariant is that all constraints appearing anywhere in a type-checked AST have no constraint synonyms, so they don't have to worry about matching on NC_app, or calling Env.expand_typquant_synonyms (which isn't even exported for this reason).
2018-10-11Change the function type in the ASTAlasdair
Changes the representation of function types in the ast from Typ_fn : typ -> typ to Typ_fn : typ list -> typ to more accurately represent their use in the various backends, where we often compile functions to either their curried representations as in Lem and Isabelle, or just multiple argument functions in C. There's still some oddity because a single pattern in a function clause can bind against multiple arguments, and maybe we want to forbid this in the future. The syntax also hasn't changed (yet), so in theory this change shouldn't break anything (but it invariably will...). In the future we would ideally require that a function with N arguments has exactly N patterns in its declaration, one for each argument so f : (x, y) -> z f _ = ... would be disallowed (as _ matches both x and y), forcing f(_, _) = z this would simply quite a few things, Also we could have a different syntax for function argument lists and tuples, because it's rather hard to define a function that actually takes a tuple with the syntax how it is now. Some issues I noticed when doing this refactoring: Line 1926 of Coq translation. untuple_args_pat is maybe no longer needed? However there's still some funnyness where a pattern can be used to bind multiple function arguments so maybe it still is. Line 2306 of monomorphisation. I simplified the logic here. I think it's equivalent now, but I could be wrong. Line 4517 of rewrites. I'm not sure what make_cstr_mappings is doing here, but hopefully the simpler version is the same.
2018-08-31mappings: Support for unidirectional mapping clausesJon French
2018-08-28add __POS__ argument to Err_unreachable for better error reportingJon French
2018-08-16Remove unused ref typeAlasdair Armstrong
2018-08-16Various cleanups to ott grammarAlasdair Armstrong
Add additional well-formedness check when calling typing rules
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-06-28Deduplicate arguments for different constructors in undefined fnsBrian Campbell
Makes the generated undefined functions smaller, easier to read, and avoids excessive memory usage in Coq (e.g., for large AST types).
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-06-11add 'pat as id' mapping-patternsJon French
2018-06-11Merge branch 'sail2' into mappingsJon French
(involved some manual tinkering with gitignore, type_check, riscv)
2018-06-04Fix an issue with riscv_platform involving flow typingAlasdair Armstrong
- Refactor the flow typing implementation in the type-checker. This should fix an issue involving riscv_platform. Specifically it should now work better when an if statement contains multiple conditions combined with and/or, only some of which imply constraints at the type level. This change also simplifies the implementation of flow typing, and removes some obscure features that were hardly used - specifically, flow typing could modify types, but this was fairly obscure and doesn't seem to affect any of our specifications. More testing is needed to ensure that this change hasn't inadvertantly broken anything, but it does pass all our tests and continue to typecheck arm, riscv and cheri. - Also adds a option for generating faster undefined functions for enum and variant types. Previously I tried to optimise away such functions in the C backend, because they could be slow and cause considerable uneccessary allocation, however this was error prone and it turns out a much simpler solution is to simply make the functions themselves much faster, at the cost of hard-coding certain decisions about what undefined means for these types at compile tile (which is fine for fast emulation). This almost doubles the performance of the generated C code. - Add a wrapper for right shift to avoid UB when shifting by 64 or more places.
2018-05-16Add support for inline val-spec declaration for mappingsJon French
This means that a mapping which formerly had to be pre-declared like val name : a <-> b ... mapping name { x <-> y, ... } can now be shortened to mapping name : a <-> b { x <-> y, ... }
2018-05-10Merge branch 'sail2' into mappingsJon French
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-02scattered mappingsJon French
2018-05-02re-indent to_ast_defJon French
2018-05-02refactor string append pattern ast to be based on lists rather than pairsJon French
2018-05-01add type annotation patterns to mpatsJon French
2018-05-01further progressJon French
2018-05-01conversion from parse_ast to astJon French
2018-05-01re-indent Initial_check.to_ast_typJon French
2018-05-01start of string pattern matching: currently only literalsJon French