Skip to content

Commit fcf9cdb

Browse files
Semantics (#28)
* made it an error to put a value of 0 for step * syntatic sugar for slices * cargo fmt * made it an error to put a value of 0 for step * syntatic sugar for slices * cargo fmt * implemented hash maps for name lookup for structs * cargo format * new git ignore to ignore snapshots * updated error for invalid step argument * Minor spelling fix --------- Co-authored-by: Nikil-Shyamsunder <[email protected]>
1 parent c4938c4 commit fcf9cdb

8 files changed

+240
-215
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/target
22
Cargo.lock
33
.idea/
4+
/tests/snapshots

src/ir.rs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,9 @@ entity_impl!(SymbolId, "symbol");
304304
#[derive(Debug, Clone, Eq, PartialEq, Default)]
305305
pub struct SymbolTable {
306306
entries: PrimaryMap<SymbolId, SymbolTableEntry>,
307-
by_name: FxHashMap<String, SymbolId>,
307+
by_name_sym: FxHashMap<String, SymbolId>,
308308
structs: PrimaryMap<StructId, Struct>,
309+
by_name_struct: FxHashMap<String, StructId>,
309310
}
310311

311312
impl SymbolTable {
@@ -323,17 +324,17 @@ impl SymbolTable {
323324
let lookup_name = entry.full_name(self);
324325

325326
assert!(
326-
!self.by_name.contains_key(&lookup_name),
327+
!self.by_name_sym.contains_key(&lookup_name),
327328
"we already have an entry for {lookup_name}!",
328329
);
329330

330331
let id = self.entries.push(entry);
331-
self.by_name.insert(lookup_name, id);
332+
self.by_name_sym.insert(lookup_name, id);
332333
id
333334
}
334335

335336
pub fn symbol_id_from_name(&self, name: &str) -> Option<SymbolId> {
336-
self.by_name.get(name).copied()
337+
self.by_name_sym.get(name).copied()
337338
}
338339

339340
pub fn add_with_parent(&mut self, name: String, parent: SymbolId) -> SymbolId {
@@ -365,28 +366,28 @@ impl SymbolTable {
365366
let lookup_name = entry.full_name(self);
366367

367368
assert!(
368-
!self.by_name.contains_key(&lookup_name),
369+
!self.by_name_sym.contains_key(&lookup_name),
369370
"we already have an entry for {lookup_name}!",
370371
);
371372

372373
let id = self.entries.push(entry);
373-
self.by_name.insert(lookup_name, id);
374+
self.by_name_sym.insert(lookup_name, id);
374375
id
375376
}
376377

377378
pub fn add_struct(&mut self, name: String, pins: Vec<Field>) -> StructId {
378-
let s = Struct { name, pins };
379-
self.structs.push(s)
380-
}
379+
let s = Struct {
380+
name: name.to_string(),
381+
pins,
382+
};
383+
let id = self.structs.push(s);
381384

382-
pub fn struct_id_from_name(&mut self, name: &str) -> Option<StructId> {
383-
self.structs
384-
.iter()
385-
.find_map(|(id, s)| if s.name() == name { Some(id) } else { None })
385+
self.by_name_struct.insert(name, id);
386+
id
386387
}
387388

388-
pub fn struct_from_struct_id(&mut self, struct_id: StructId) -> &Struct {
389-
&self.structs[struct_id]
389+
pub fn struct_id_from_name(&mut self, name: &str) -> Option<StructId> {
390+
self.by_name_struct.get(name).copied()
390391
}
391392

392393
pub fn struct_ids(&self) -> Vec<StructId> {
@@ -398,7 +399,7 @@ impl Index<&str> for SymbolTable {
398399
type Output = SymbolTableEntry;
399400

400401
fn index(&self, index: &str) -> &Self::Output {
401-
let index = self.by_name[index];
402+
let index = self.by_name_sym[index];
402403
&self.entries[index]
403404
}
404405
}

src/parser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ impl<'a> ParserContext<'a> {
184184
.st
185185
.struct_id_from_name(path_id_2)
186186
.ok_or_else(|| format!("Undefined struct: {}", path_id_2))?;
187-
let dut_struct = self.st.struct_from_struct_id(struct_id).clone();
187+
let dut_struct = self.st[struct_id].clone();
188188
let dut_symbol_id = self
189189
.st
190190
.add_without_parent(path_id_1.to_string(), Type::Struct(struct_id));

src/serialize.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,16 @@ pub fn serialize_expr(tr: &Transaction, st: &SymbolTable, expr_id: &ExprId) -> S
4747
serialize_expr(tr, st, lhs) + " == " + &serialize_expr(tr, st, rhs)
4848
}
4949
Expr::Slice(expr, idx1, idx2) => {
50-
serialize_expr(tr, st, expr)
51-
+ "["
52-
+ idx1.to_string().as_str()
53-
+ ":"
54-
+ idx2.to_string().as_str()
55-
+ "]"
50+
if *idx2 == *idx1 {
51+
serialize_expr(tr, st, expr) + "[" + idx1.to_string().as_str() + "]"
52+
} else {
53+
serialize_expr(tr, st, expr)
54+
+ "["
55+
+ idx1.to_string().as_str()
56+
+ ":"
57+
+ idx2.to_string().as_str()
58+
+ "]"
59+
}
5660
}
5761
}
5862
}

src/typecheck.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
// author: Kevin Laeufer <[email protected]>
55
// author: Francis Pham <[email protected]>
66

7+
use baa::BitVecOps;
8+
79
use crate::parser;
810
use crate::{diagnostic::*, ir::*, serialize::*};
911

@@ -65,6 +67,17 @@ fn check_stmt_types(
6567
Stmt::Step(exprid) => {
6668
let expr_type = check_expr_types(tr, st, handler, exprid)?;
6769
if let Type::BitVec(_) = expr_type {
70+
if let Expr::Const(val) = &tr[exprid] {
71+
if val.to_i64().unwrap() >= 1 {
72+
return Ok(());
73+
}
74+
handler.emit_diagnostic_expr(
75+
tr,
76+
exprid,
77+
&format!("Argument to step must be a positive, non-zero integer literal."),
78+
Level::Error,
79+
);
80+
}
6881
Ok(())
6982
} else {
7083
handler.emit_diagnostic_stmt(

0 commit comments

Comments
 (0)