Mercurial > cpdt > repo
comparison src/StackMachine.v @ 19:5db67b182ef8
Translation
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Wed, 03 Sep 2008 15:59:37 -0400 |
parents | 82618ad75252 |
children | c0cbf324ec7d |
comparison
equal
deleted
inserted
replaced
18:82618ad75252 | 19:5db67b182ef8 |
---|---|
718 end. | 718 end. |
719 | 719 |
720 | 720 |
721 (** ** Translation *) | 721 (** ** Translation *) |
722 | 722 |
723 (** To define our compilation, it is useful to have an auxiliary function for concatenating two stack machine programs. *) | |
724 | |
723 Fixpoint tconcat ts ts' ts'' (p : tprog ts ts') {struct p} : tprog ts' ts'' -> tprog ts ts'' := | 725 Fixpoint tconcat ts ts' ts'' (p : tprog ts ts') {struct p} : tprog ts' ts'' -> tprog ts ts'' := |
724 match p in (tprog ts ts') return (tprog ts' ts'' -> tprog ts ts'') with | 726 match p in (tprog ts ts') return (tprog ts' ts'' -> tprog ts ts'') with |
725 | TNil _ => fun p' => p' | 727 | TNil _ => fun p' => p' |
726 | TCons _ _ _ i p1 => fun p' => TCons i (tconcat p1 p') | 728 | TCons _ _ _ i p1 => fun p' => TCons i (tconcat p1 p') |
727 end. | 729 end. |
730 | |
731 (** With that function in place, the compilation is defined very similarly to how it was before, modulo the use of dependent typing. *) | |
728 | 732 |
729 Fixpoint tcompile t (e : texp t) (ts : tstack) {struct e} : tprog ts (t :: ts) := | 733 Fixpoint tcompile t (e : texp t) (ts : tstack) {struct e} : tprog ts (t :: ts) := |
730 match e in (texp t) return (tprog ts (t :: ts)) with | 734 match e in (texp t) return (tprog ts (t :: ts)) with |
731 | TNConst n => TCons (TINConst _ n) (TNil _) | 735 | TNConst n => TCons (TINConst _ n) (TNil _) |
732 | TBConst b => TCons (TIBConst _ b) (TNil _) | 736 | TBConst b => TCons (TIBConst _ b) (TNil _) |
733 | TBinop _ _ _ b e1 e2 => tconcat (tcompile e2 _) | 737 | TBinop _ _ _ b e1 e2 => tconcat (tcompile e2 _) |
734 (tconcat (tcompile e1 _) (TCons (TIBinop _ b) (TNil _))) | 738 (tconcat (tcompile e1 _) (TCons (TIBinop _ b) (TNil _))) |
735 end. | 739 end. |
736 | 740 |
741 (** One interesting feature of the definition is the underscores appearing to the right of [=>] arrows. Haskell and ML programmers are quite familiar with compilers that infer type parameters to polymorphic values. In Coq, it is possible to go even further and ask the system to infer arbitary terms, by writing underscores in place of specific values. You may have noticed that we have been calling functions without specifying all of their arguments. For instance, the recursive calls here to [tcompile] omit the [t] argument. Coq's %\textit{%#<i>#implicit argument#</i>#%}% mechanism automatically inserts underscores for arguments that it will probably be able to infer. Inference of such values is far from complete, though; generally, it only works in cases similar to those encountered with polymorphic type instantiation in Haskell and ML. | |
742 | |
743 The underscores here are being filled in with stack types. That is, the Coq type inferencer is, in a sense, inferring something about the flow of control in the translated programs. We can take a look at exactly which values are filled in: *) | |
744 | |
737 Print tcompile. | 745 Print tcompile. |
746 | |
747 (** [[ | |
748 | |
749 tcompile = | |
750 fix tcompile (t : type) (e : texp t) (ts : tstack) {struct e} : | |
751 tprog ts (t :: ts) := | |
752 match e in (texp t0) return (tprog ts (t0 :: ts)) with | |
753 | TNConst n => TCons (TINConst ts n) (TNil (Nat :: ts)) | |
754 | TBConst b => TCons (TIBConst ts b) (TNil (Bool :: ts)) | |
755 | TBinop arg1 arg2 res b e1 e2 => | |
756 tconcat (tcompile arg2 e2 ts) | |
757 (tconcat (tcompile arg1 e1 (arg2 :: ts)) | |
758 (TCons (TIBinop ts b) (TNil (res :: ts)))) | |
759 end | |
760 : forall t : type, texp t -> forall ts : tstack, tprog ts (t :: ts) | |
761 ]] *) | |
762 | |
763 | |
764 (** We can check that the compiler generates programs that behave appropriately on our sample programs from above: *) | |
765 | |
766 Eval simpl in tprogDenote (tcompile (TNConst 42) nil) tt. | |
767 (** [[ | |
768 = (42, tt) : vstack (Nat :: nil) | |
769 ]] *) | |
770 Eval simpl in tprogDenote (tcompile (TBConst true) nil) tt. | |
771 (** [[ | |
772 = (true, tt) : vstack (Bool :: nil) | |
773 ]] *) | |
774 Eval simpl in tprogDenote (tcompile (TBinop TTimes (TBinop TPlus (TNConst 2) (TNConst 2)) (TNConst 7)) nil) tt. | |
775 (** [[ | |
776 = (28, tt) : vstack (Nat :: nil) | |
777 ]] *) | |
778 Eval simpl in tprogDenote (tcompile (TBinop (TEq Nat) (TBinop TPlus (TNConst 2) (TNConst 2)) (TNConst 7)) nil) tt. | |
779 (** [[ | |
780 = (false, tt) : vstack (Bool :: nil) | |
781 ]] *) | |
782 Eval simpl in tprogDenote (tcompile (TBinop TLt (TBinop TPlus (TNConst 2) (TNConst 2)) (TNConst 7)) nil) tt. | |
783 (** [[ | |
784 = (true, tt) : vstack (Bool :: nil) | |
785 ]] *) | |
738 | 786 |
739 | 787 |
740 (** ** Translation correctness *) | 788 (** ** Translation correctness *) |
741 | 789 |
742 Lemma tcompileCorrect' : forall t (e : texp t) | 790 Lemma tcompileCorrect' : forall t (e : texp t) |