Commit 67aa9dcd authored by Lennard Gäher's avatar Lennard Gäher
Browse files

upd frontend

parent 05e3c269
...@@ -203,11 +203,10 @@ dependencies = [ ...@@ -203,11 +203,10 @@ dependencies = [
"env_logger", "env_logger",
"lazy_static", "lazy_static",
"log", "log",
"proc-macro2",
"regex", "regex",
"rustc-hash", "rustc-hash",
"serde 1.0.130", "serde 1.0.130",
"syn", "unicode-xid 0.0.4",
] ]
[[package]] [[package]]
...@@ -354,7 +353,7 @@ version = "1.0.29" ...@@ -354,7 +353,7 @@ version = "1.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d"
dependencies = [ dependencies = [
"unicode-xid", "unicode-xid 0.2.2",
] ]
[[package]] [[package]]
...@@ -513,7 +512,7 @@ checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194" ...@@ -513,7 +512,7 @@ checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"unicode-xid", "unicode-xid 0.2.2",
] ]
[[package]] [[package]]
...@@ -564,6 +563,12 @@ version = "0.1.9" ...@@ -564,6 +563,12 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "unicode-xid"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
version = "0.2.2" version = "0.2.2"
......
dump_borrowck_info=true
output_dir="./output"
| Keyword | Purpose | Properties | Example |
--------------------------------------------------------------------------------------------
| `params` | specify Coq-level parameters | multiple | `#[rr:params("n" : "Z", b : "bool")]` |
| `param` | specify Coq-level parameters | multiple | `#[rr:param("n" : "Z")]` |
| `args` | specify argument types | single | `#[rr::args("n" @ "int i32", "b" @ "boolean"]` |
| `returns` | specify return type | single | `#[rr::returns("42" @ "int i32")]` |
| `requires` | specify a precondition | multiple | `#[rr:requires("⌜i > 42⌝")]` |
| `ensures` | specify a postcondition | multiple | `#[rr::ensures("⌜x > y⌝")]` |
| `exists` | specify an existential for the postco | multiple | `#[rr::exists("x" : "Z")]` |
...@@ -14,8 +14,9 @@ serde = "1.0.130" ...@@ -14,8 +14,9 @@ serde = "1.0.130"
csv = "1.1" csv = "1.1"
config = "0.11" config = "0.11"
lazy_static = "1.4.0" lazy_static = "1.4.0"
syn = { version = "1.0.80", features = ["full", "parsing"] } #syn = { version = "1.0.80", features = ["full", "parsing"] }
proc-macro2 = "1.0" #proc-macro2 = "1.0"
unicode-xid = "0.0.4"
analysis = { path = "../analysis" } analysis = { path = "../analysis" }
......
...@@ -38,7 +38,7 @@ impl CaesiumLiteral { ...@@ -38,7 +38,7 @@ impl CaesiumLiteral {
format!("i2v ({}) {}", i.as_str(), it.caesium_fmt().as_str()) format!("i2v ({}) {}", i.as_str(), it.caesium_fmt().as_str())
}; };
let format_bool = |i: String| { let format_bool = |i: String| {
format!("i2v (Z_of_bool {}) {}", i.as_str(), (CaesiumIntType::CaesiumU8).caesium_fmt().as_str()) format!("i2v (Z_of_bool {}) {}", i.as_str(), (BOOL_REPR).caesium_fmt().as_str())
}; };
match self { match self {
Self::LitI8(i) => format_int(i.to_string(), CaesiumIntType::CaesiumI8), Self::LitI8(i) => format_int(i.to_string(), CaesiumIntType::CaesiumI8),
...@@ -62,12 +62,12 @@ impl CaesiumLiteral { ...@@ -62,12 +62,12 @@ impl CaesiumLiteral {
* Caesium expressions * Caesium expressions
*/ */
pub enum CaesiumExpr { pub enum CaesiumExpr {
Var(String), Var(String),
/// a Coq-level parameter with a given Coq name /// a Coq-level parameter with a given Coq name
MetaParam(String), MetaParam(String),
Literal(CaesiumLiteral), Literal(CaesiumLiteral),
UnOp{ UnOp{
o : CaesiumUnop, o : CaesiumUnop,
ot : CaesiumOpType, ot : CaesiumOpType,
e : Box<CaesiumExpr>, e : Box<CaesiumExpr>,
}, },
...@@ -114,6 +114,12 @@ pub enum CaesiumExpr { ...@@ -114,6 +114,12 @@ pub enum CaesiumExpr {
ly: CaesiumStructLayout, ly: CaesiumStructLayout,
name: String, name: String,
}, },
Annot {
a: CaesiumAnnotation,
e: Box<CaesiumExpr>
},
DropE(Box<CaesiumExpr>),
BoxE(CaesiumLayout),
} }
impl CaesiumExpr { impl CaesiumExpr {
...@@ -155,7 +161,6 @@ impl CaesiumExpr { ...@@ -155,7 +161,6 @@ impl CaesiumExpr {
Self::Borrow{lft, bk, e} => { Self::Borrow{lft, bk, e} => {
let formatted_bk = bk.caesium_fmt(); let formatted_bk = bk.caesium_fmt();
let formatted_e = e.caesium_fmt(); let formatted_e = e.caesium_fmt();
// TODO: needs lifetime info
format!("&ref{{ {}, \"{}\" }} ({})", formatted_bk, lft, formatted_e) format!("&ref{{ {}, \"{}\" }} ({})", formatted_bk, lft, formatted_e)
}, },
Self::AddressOf{mt, e} => { Self::AddressOf{mt, e} => {
...@@ -175,7 +180,18 @@ impl CaesiumExpr { ...@@ -175,7 +180,18 @@ impl CaesiumExpr {
let formatted_ly = ly.caesium_fmt(); let formatted_ly = ly.caesium_fmt();
format!("{} at{{ {} }} \"{}\"", formatted_e, formatted_ly, name) format!("{} at{{ {} }} \"{}\"", formatted_e, formatted_ly, name)
}, },
Self::Annot{a, e} => {
let formatted_e = e.caesium_fmt();
format!("AnnotExpr {} ({}) ({})", a.needs_laters(), a, formatted_e)
},
Self::BoxE(ly) => {
let formatted_ly = ly.caesium_fmt();
format!("box{{{}}}", formatted_ly)
},
Self::DropE(e) => {
let formatted_e = e.caesium_fmt();
format!("drop ({})", formatted_e)
}
// TODO // TODO
_ => format!(""), _ => format!(""),
} }
...@@ -213,8 +229,14 @@ impl CaesiumBorKind { ...@@ -213,8 +229,14 @@ impl CaesiumBorKind {
} }
pub enum CaesiumAnnotation { pub enum CaesiumAnnotation {
/// Start a lifetime as a sublifetime of the intersection of a few other lifetimes
StartLft(CaesiumLft, Vec<CaesiumLft>), StartLft(CaesiumLft, Vec<CaesiumLft>),
/// End this lifetime
EndLft(CaesiumLft), EndLft(CaesiumLft),
/// Extend this lifetime by making the directly owned part static
ExtendLft(CaesiumLft),
/// Shorten the lifetime of an object to the intersection of the given lifetimes
ShortenLft(Vec<CaesiumLft>),
} }
impl fmt::Display for CaesiumAnnotation { impl fmt::Display for CaesiumAnnotation {
fn fmt(&self, f : &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f : &mut fmt::Formatter<'_>) -> fmt::Result {
...@@ -234,11 +256,36 @@ impl fmt::Display for CaesiumAnnotation { ...@@ -234,11 +256,36 @@ impl fmt::Display for CaesiumAnnotation {
}, },
Self::EndLft(l) => { Self::EndLft(l) => {
write!(f, "EndLftAnnot \"{}\"", l) write!(f, "EndLftAnnot \"{}\"", l)
},
Self::ExtendLft(l) => {
write!(f, "ExtendLftAnnot \"{}\"", l)
},
Self::ShortenLft(sup) => {
write!(f, "ShortenLftAnnot [")?;
let mut need_sep = false;
for s in sup.iter() {
if need_sep {
write!(f, ", ")?;
}
write!(f, "\"{}\"", s)?;
need_sep = true;
}
write!(f, "]")
} }
} }
} }
} }
impl CaesiumAnnotation {
pub(crate) fn needs_laters(&self) -> u32 {
match self {
Self::ShortenLft{..} => 0,
_ => 0,
}
}
}
type CaesiumBlockLabel = String; type CaesiumBlockLabel = String;
pub enum CaesiumStmt { pub enum CaesiumStmt {
...@@ -290,23 +337,23 @@ impl CaesiumStmt { ...@@ -290,23 +337,23 @@ impl CaesiumStmt {
format!("{}Return ({})", ind, formatted_e) format!("{}Return ({})", ind, formatted_e)
}, },
CaesiumStmt::Assign{ot, e1, e2, s} => { CaesiumStmt::Assign{ot, e1, e2, s} => {
let formatted_s = s.caesium_fmt(indent); let formatted_s = s.caesium_fmt(indent);
let formatted_e1 = e1.caesium_fmt(); let formatted_e1 = e1.caesium_fmt();
let formatted_e2 = e2.caesium_fmt(); let formatted_e2 = e2.caesium_fmt();
let formatted_ot = ot.caesium_fmt(); let formatted_ot = ot.caesium_fmt();
format!("{}{} <-{{ {} }} {};\n{}", format!("{}{} <-{{ {} }} {};\n{}",
ind, ind,
formatted_e1.as_str(), formatted_e1.as_str(),
formatted_ot.as_str(), formatted_ot.as_str(),
formatted_e2.as_str(), formatted_e2.as_str(),
formatted_s.as_str()) formatted_s.as_str())
}, },
CaesiumStmt::ExprS{e, s} => { CaesiumStmt::ExprS{e, s} => {
let formatted_e = e.caesium_fmt(); let formatted_e = e.caesium_fmt();
let formatted_s = s.caesium_fmt(indent); let formatted_s = s.caesium_fmt(indent);
format!("{}{};\n{}", format!("{}{};\n{}",
ind, ind,
formatted_e.as_str(), formatted_e.as_str(),
formatted_s.as_str()) formatted_s.as_str())
}, },
...@@ -333,7 +380,7 @@ pub enum CaesiumUnop { ...@@ -333,7 +380,7 @@ pub enum CaesiumUnop {
} }
impl CaesiumUnop { impl CaesiumUnop {
fn caesium_fmt(&self, ot: &CaesiumOpType) -> String { fn caesium_fmt(&self, ot: &CaesiumOpType) -> String {
match self { match self {
Self::NegOp => format!("−{{ {} }}", ot.caesium_fmt()), Self::NegOp => format!("−{{ {} }}", ot.caesium_fmt()),
// TODO: don't actually use that on the Caesium side currently // TODO: don't actually use that on the Caesium side currently
Self::NotOp => format!("!!{{ {} }}", ot.caesium_fmt()), Self::NotOp => format!("!!{{ {} }}", ot.caesium_fmt()),
...@@ -344,29 +391,29 @@ impl CaesiumUnop { ...@@ -344,29 +391,29 @@ impl CaesiumUnop {
pub enum CaesiumBinop { pub enum CaesiumBinop {
//arithmetic //arithmetic
AddOp, AddOp,
SubOp, SubOp,
MulOp, MulOp,
DivOp, DivOp,
ModOp, ModOp,
// logical // logical
AndOp, AndOp,
OrOp, OrOp,
//bitwise //bitwise
BitAndOp, BitAndOp,
BitOrOp, BitOrOp,
BitXorOp, BitXorOp,
ShlOp, ShlOp,
ShrOp, ShrOp,
// comparison // comparison
EqOp, EqOp,
NeOp, NeOp,
LtOp, LtOp,
GtOp, GtOp,
LeOp, LeOp,
GeOp, GeOp,
// pointer operations // pointer operations
PtrOffsetOp(CaesiumLayout), PtrOffsetOp(CaesiumLayout),
PtrNegOffsetOp(CaesiumLayout), PtrNegOffsetOp(CaesiumLayout),
PtrDiffOp(CaesiumLayout) PtrDiffOp(CaesiumLayout)
} }
...@@ -375,7 +422,7 @@ impl CaesiumBinop { ...@@ -375,7 +422,7 @@ impl CaesiumBinop {
let rt = String::with_capacity(20); let rt = String::with_capacity(20);
let format_prim = |st:&str| format!("{}{{ {} , {} }}", st, ot1.caesium_fmt(), ot2.caesium_fmt()); let format_prim = |st:&str| format!("{}{{ {} , {} }}", st, ot1.caesium_fmt(), ot2.caesium_fmt());
let format_bool = |st:&str| format!("{}{{ {} , {} , {} }}", st, ot1.caesium_fmt(), ot2.caesium_fmt(), (CaesiumIntType::CaesiumU8).caesium_fmt()); let format_bool = |st:&str| format!("{}{{ {} , {} , {} }}", st, ot1.caesium_fmt(), ot2.caesium_fmt(), (BOOL_REPR).caesium_fmt());
match self { match self {
...@@ -466,11 +513,13 @@ impl CaesiumIntType { ...@@ -466,11 +513,13 @@ impl CaesiumIntType {
} }
} }
// Notes on ADT representation: pub static BOOL_REPR: CaesiumIntType = CaesiumIntType::CaesiumI8;
// Notes on ADT representation:
// - Rust structs have a single variant with several fields. This is directly accomodated by // - Rust structs have a single variant with several fields. This is directly accomodated by
// Caesium structs. // Caesium structs.
// - Rust enums are more complicated. Need one field for the discriminant. // - Rust enums are more complicated. Need one field for the discriminant.
// Then, essentially, a union of several structs?. // Then, essentially, a union of several structs?.
// TODO: think more about the correct model for this. // TODO: think more about the correct model for this.
// - Rust unions seem relatively straightforward based on Caesium unions. // - Rust unions seem relatively straightforward based on Caesium unions.
// - Rust tuple structs should just compile down to tuples aka structs // - Rust tuple structs should just compile down to tuples aka structs
...@@ -488,7 +537,7 @@ impl CaesiumStructLayout { ...@@ -488,7 +537,7 @@ impl CaesiumStructLayout {
} }
// struct itself needs to have size divisible by alignment // struct itself needs to have size divisible by alignment
offset % self.alignment() == 0 offset % self.alignment() == 0
} }
/// Make a struct layout by correctly padding a given prototypical layout. /// Make a struct layout by correctly padding a given prototypical layout.
pub fn make_layout(prely: Vec<(String, CaesiumLayout)>) -> Self { pub fn make_layout(prely: Vec<(String, CaesiumLayout)>) -> Self {
...@@ -558,8 +607,8 @@ pub enum CaesiumLayout { ...@@ -558,8 +607,8 @@ pub enum CaesiumLayout {
// size 1, similar to u8/i8 // size 1, similar to u8/i8
BoolLayout, BoolLayout,
// always 4 bytes // always 4 bytes
CharLayout, CharLayout,
// guaranteed to have size 0 and alignment 1. // guaranteed to have size 0 and alignment 1.
// TODO: Could alternatively represent this as a struct instead? an empty struct has the // TODO: Could alternatively represent this as a struct instead? an empty struct has the
// same representation, essentially // same representation, essentially
UnitLayout, UnitLayout,
...@@ -571,8 +620,9 @@ pub enum CaesiumLayout { ...@@ -571,8 +620,9 @@ pub enum CaesiumLayout {
impl CaesiumLayout { impl CaesiumLayout {
pub fn into_caesium_op_type(self) -> CaesiumOpType { pub fn into_caesium_op_type(self) -> CaesiumOpType {
match self { match self {
//Self::PtrLayout => CaesiumOpType::PtrOp, Self::PtrLayout => CaesiumOpType::PtrOp,
//Self::IntLayout(it) => CaesiumOpType::IntOp(it), Self::IntLayout(it) => CaesiumOpType::IntOp(it),
Self::BoolLayout => CaesiumOpType::IntOp(BOOL_REPR),
// TODO: handle structs? // TODO: handle structs?
layout => CaesiumOpType::UntypedOp(layout), layout => CaesiumOpType::UntypedOp(layout),
} }
...@@ -582,11 +632,11 @@ impl CaesiumLayout { ...@@ -582,11 +632,11 @@ impl CaesiumLayout {
match self { match self {
Self::PtrLayout => "void*".to_string(), Self::PtrLayout => "void*".to_string(),
Self::IntLayout(it) => format!("it_layout {}", it.caesium_fmt().as_str()), Self::IntLayout(it) => format!("it_layout {}", it.caesium_fmt().as_str()),
Self::BoolLayout => format!("it_layout {}", (CaesiumIntType::CaesiumU8).caesium_fmt().as_str()), Self::BoolLayout => format!("it_layout {}", BOOL_REPR.caesium_fmt().as_str()),
// TODO // TODO
Self::CharLayout => format!("char_layout"), Self::CharLayout => format!("char_layout"),
// TODO // TODO
Self::UnitLayout => format!("unit_layout"), Self::UnitLayout => format!("(layout_of unit_layout)"),
//TODO //TODO
Self::StructLayout(ly) => format!("struct_layout"), Self::StructLayout(ly) => format!("struct_layout"),
// TODO // TODO
...@@ -622,13 +672,13 @@ impl CaesiumLayout { ...@@ -622,13 +672,13 @@ impl CaesiumLayout {
pub enum CaesiumOpType { pub enum CaesiumOpType {
IntOp(CaesiumIntType), IntOp(CaesiumIntType),
PtrOp, PtrOp,
StructOp(CaesiumStructLayout), StructOp(CaesiumStructLayout),
UntypedOp(CaesiumLayout), UntypedOp(CaesiumLayout),
} }
impl CaesiumOpType { impl CaesiumOpType {
fn caesium_fmt(&self) -> String { fn caesium_fmt(&self) -> String {
match self { match self {
Self::IntOp(it) => format!("IntOp {}", it.caesium_fmt().as_str()), Self::IntOp(it) => format!("IntOp {}", it.caesium_fmt().as_str()),
Self::PtrOp => "PtrOp".to_string(), Self::PtrOp => "PtrOp".to_string(),
// TODO // TODO
Self::StructOp(ly) => "StructOp TODO TODO".to_string(), Self::StructOp(ly) => "StructOp TODO TODO".to_string(),
...@@ -645,10 +695,22 @@ pub struct CaesiumFunctionCode { ...@@ -645,10 +695,22 @@ pub struct CaesiumFunctionCode {
stack_layout: CaesiumStackMap, stack_layout: CaesiumStackMap,
basic_blocks: HashMap<String, CaesiumStmt>, basic_blocks: HashMap<String, CaesiumStmt>,
/// Coq parameters that the function is parameterized over /// Coq parameters that the function is parameterized over
required_parameters: Vec<(CoqName, CoqType)>, required_parameters: Vec<(CoqName, CoqType)>,
} }
fn make_map_string(sep0: &str, sep: &str, els: Vec<(String, String)>) -> String {
let mut out = String::with_capacity(100);
for (key, value) in els.iter() {
out.push_str(sep);
out.push_str(format!("<[\"{}\" :={}{}{}]>%E $", key, sep0, value, sep).as_str());
}
out.push_str(sep);
out.push_str("∅");
out
}
impl CaesiumFunctionCode { impl CaesiumFunctionCode {
const initial_bb: &'static str = "_bb0"; const initial_bb: &'static str = "_bb0";
pub fn caesium_fmt(&self) -> String { pub fn caesium_fmt(&self) -> String {
...@@ -679,18 +741,8 @@ impl CaesiumFunctionCode { ...@@ -679,18 +741,8 @@ impl CaesiumFunctionCode {
let mut formatted_locals = String::with_capacity(100); let mut formatted_locals = String::with_capacity(100);
formatted_locals.push_str(format!("{}f_local_vars := {}", make_indent(1), format_stack_layout(self.stack_layout.iter_locals()).as_str()).as_str()); formatted_locals.push_str(format!("{}f_local_vars := {}", make_indent(1), format_stack_layout(self.stack_layout.iter_locals()).as_str()).as_str());
let mut formatted_bb = String::with_capacity(1000); let formatted_bb = make_map_string("\n", format!("\n{}", make_indent(2).as_str()).as_str(),
formatted_bb.push_str(format!("{}f_code :=", make_indent(1).as_str()).as_str()); self.basic_blocks.iter().map(|(name, bb)| (name.to_string(), bb.caesium_fmt(3))).collect());
for (name, bb) in self.basic_blocks.iter() {
formatted_bb.push_str("\n");
formatted_bb.push_str(make_indent(2).as_str());
let printed_stmt = bb.caesium_fmt(3);
formatted_bb.push_str(format!("<[\"{}\" :=\n{}\n{}]>%E $", name, printed_stmt, make_indent(2).as_str()).as_str());
}
formatted_bb.push_str("\n");
formatted_bb.push_str(make_indent(2).as_str());
formatted_bb.push_str("∅");
if self.basic_blocks.len() < 1 { if self.basic_blocks.len() < 1 {
panic!("CaesiumFunction has no basic block"); panic!("CaesiumFunction has no basic block");
...@@ -704,15 +756,20 @@ impl CaesiumFunctionCode { ...@@ -704,15 +756,20 @@ impl CaesiumFunctionCode {
formatted_params.push_str(format!("({}, : {})", name, ty).as_str()); formatted_params.push_str(format!("({}, : {})", name, ty).as_str());
} }
format!("Definition {} {} : function := {{|\n{};\n{};\n{};\n{};\n|}}", format!("Definition {}_def {} : function := {{|\n{};\n{};\n{}f_code := {};\n{};\n|}}.",
self.name.as_str(), self.name.as_str(),
formatted_params.as_str(), formatted_params.as_str(),
formatted_args.as_str(), formatted_args.as_str(),
formatted_locals.as_str(), formatted_locals.as_str(),
make_indent(1).as_str(),
formatted_bb.as_str(), formatted_bb.as_str(),
formatted_init.as_str()) formatted_init.as_str())
} }
/// Get the number of arguments of the function.
pub fn get_argument_count(&self) -> usize {
self.stack_layout.iter_args().len()
}
} }
...@@ -732,8 +789,8 @@ impl CaesiumStackMap { ...@@ -732,8 +789,8 @@ impl CaesiumStackMap {
let mut names = HashSet::new(); let mut names = HashSet::new();
CaesiumStackMap { CaesiumStackMap {
arg_map, arg_map,
local_map, local_map,
used_names: names, used_names: names,
} }
...@@ -792,10 +849,10 @@ pub struct CaesiumFunctionCodeBuilder { ...@@ -792,10 +849,10 @@ pub struct CaesiumFunctionCodeBuilder {
impl CaesiumFunctionCodeBuilder { impl CaesiumFunctionCodeBuilder {
pub fn new() -> CaesiumFunctionCodeBuilder { pub fn new() -> CaesiumFunctionCodeBuilder {
CaesiumFunctionCodeBuilder { CaesiumFunctionCodeBuilder {
stack_layout: CaesiumStackMap::new(), stack_layout: CaesiumStackMap::new(),
basic_blocks: HashMap::new(), basic_blocks: HashMap::new(),
} }