Skip to content

Commit 18e639b

Browse files
tautschnigkiro-agentkeyboardDrummer-bot
authored
Add bitvector types (bv8, bv16, bv32, bv64) to Laurel (#701)
Introduce explicit bitvector types in Laurel so that front-ends can use them directly rather than encoding them as constrained integer types. - Add TBv(size) to HighType with equality support - Add bv8, bv16, bv32, bv64 grammar rules in LaurelGrammar.st - Translate to Core's LMonoTy.bitvec in LaurelToCoreTranslator - Add formatting and fix exhaustive match in ToLaurelTest By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. --------- Co-authored-by: Kiro <kiro-agent@users.noreply.github.com> Co-authored-by: keyboardDrummer-bot <keyboardDrummer-bot@users.noreply.github.com>
1 parent a9f721d commit 18e639b

11 files changed

Lines changed: 83 additions & 10 deletions

File tree

Strata/Languages/Laurel/FilterPrelude.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ private partial def collectHighTypeNames (ty : HighTypeMd) : CollectM Unit := do
7878
| .Pure base => collectHighTypeNames base
7979
| .Intersection types => types.forM collectHighTypeNames
8080
| .TVoid | .TBool | .TInt | .TFloat64 | .TReal | .TString | .THeap
81-
| .Unknown => pure ()
81+
| .TBv _ | .Unknown => pure ()
8282

8383
/-- Collect all referenced names (procedure calls, type references) from a StmtExpr tree. -/
8484
private partial def collectExprNames (expr : StmtExprMd) : CollectM Unit := do

Strata/Languages/Laurel/Grammar/AbstractToConcreteTreeTranslator.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ partial def highTypeValToArg : HighType → Arg
4343
| .TFloat64 => laurelOp "float64Type"
4444
| .TReal => laurelOp "realType"
4545
| .TString => laurelOp "stringType"
46+
| .TBv n => laurelOp "bvType" #[.num sr n]
4647
| .TMap k v => laurelOp "mapType" #[highTypeToArg k, highTypeToArg v]
4748
| .UserDefined name => laurelOp "compositeType" #[ident name.text]
4849
| .TCore s => laurelOp "coreType" #[ident s]

Strata/Languages/Laurel/Grammar/ConcreteToAbstractTreeTranslator.lean

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ instance : Inhabited Parameter where
8383
def mkHighTypeMd (t : HighType) (md : MetaData) : HighTypeMd := ⟨t, md⟩
8484
def mkStmtExprMd (e : StmtExpr) (md : MetaData) : StmtExprMd := ⟨e, md⟩
8585

86+
def translateNat (arg : Arg) : TransM Nat := do
87+
let .num _ n := arg
88+
| TransM.error s!"translateNat expects num literal"
89+
return n
90+
8691
partial def translateHighType (arg : Arg) : TransM HighTypeMd := do
8792
let md ← getArgMetaData arg
8893
match arg with
@@ -93,6 +98,9 @@ partial def translateHighType (arg : Arg) : TransM HighTypeMd := do
9398
| q`Laurel.float64Type, _ => return mkHighTypeMd .TFloat64 md
9499
| q`Laurel.realType, _ => return mkHighTypeMd .TReal md
95100
| q`Laurel.stringType, _ => return mkHighTypeMd .TString md
101+
| q`Laurel.bvType, #[widthArg] =>
102+
let width ← translateNat widthArg
103+
return mkHighTypeMd (.TBv width) md
96104
| q`Laurel.coreType, #[.ident _ name] => return mkHighTypeMd (.TCore name) md
97105
| q`Laurel.mapType, #[keyArg, valArg] =>
98106
let keyType ← translateHighType keyArg
@@ -101,14 +109,9 @@ partial def translateHighType (arg : Arg) : TransM HighTypeMd := do
101109
| q`Laurel.compositeType, #[nameArg] =>
102110
let name ← translateIdent nameArg
103111
return mkHighTypeMd (.UserDefined name) md
104-
| _, _ => TransM.error s!"translateHighType expects intType, boolType, arrayType or compositeType, got {repr op.name}"
112+
| _, _ => TransM.error s!"translateHighType: unsupported type operator {repr op.name}"
105113
| _ => TransM.error s!"translateHighType expects operation"
106114

107-
def translateNat (arg : Arg) : TransM Nat := do
108-
let .num _ n := arg
109-
| TransM.error s!"translateNat expects num literal"
110-
return n
111-
112115
def translateString (arg : Arg) : TransM String := do
113116
let .strlit _ s := arg
114117
| TransM.error s!"translateString expects string literal"

Strata/Languages/Laurel/Grammar/LaurelGrammar.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ module
99
-- Laurel dialect definition, loaded from LaurelGrammar.st
1010
-- NOTE: Changes to LaurelGrammar.st are not automatically tracked by the build system.
1111
-- Update this file (e.g. this comment) to trigger a recompile after modifying LaurelGrammar.st.
12-
-- Last grammar change: added space before while/for loop body in format strings.
12+
-- Last grammar change: parameterized bvType with arbitrary width
1313
public import Strata.DDM.Integration.Lean
1414
public meta import Strata.DDM.Integration.Lean
1515

Strata/Languages/Laurel/Grammar/LaurelGrammar.st

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ op boolType : LaurelType => "bool";
99
op realType : LaurelType => "real";
1010
op float64Type : LaurelType => "float64";
1111
op stringType : LaurelType => "string";
12+
op bvType (width: Num): LaurelType => "bv" width;
1213
// Core type passthrough: parsed as Ident, translated to HighType.TCore
1314
op coreType (name: Ident): LaurelType => "Core " name;
1415
op mapType (keyType: LaurelType, valueType: LaurelType): LaurelType => "Map " keyType " " valueType;

Strata/Languages/Laurel/Laurel.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ inductive HighType : Type where
155155
| Pure (base : WithMetadata HighType)
156156
/-- An intersection of types. Used for implicit intersection types, e.g. `Scientist & Scandinavian`. -/
157157
| Intersection (types : List (WithMetadata HighType))
158+
/-- Bitvector type of a given width. -/
159+
| TBv (size : Nat)
158160
/-- Temporary construct meant to aid the migration of Python->Core to Python->Laurel.
159161
Type "passed through" from Core. Intended to allow translations to Laurel to refer directly to Core. -/
160162
| TCore (s: String)
@@ -336,6 +338,7 @@ def highEq (a : HighTypeMd) (b : HighTypeMd) : Bool := match _a: a.val, _b: b.va
336338
| HighType.TReal, HighType.TReal => true
337339
| HighType.TString, HighType.TString => true
338340
| HighType.THeap, HighType.THeap => true
341+
| HighType.TBv n1, HighType.TBv n2 => n1 == n2
339342
| HighType.TTypedField t1, HighType.TTypedField t2 => highEq t1 t2
340343
| HighType.TSet t1, HighType.TSet t2 => highEq t1 t2
341344
| HighType.TMap k1 v1, HighType.TMap k2 v2 => highEq k1 k2 && highEq v1 v2

Strata/Languages/Laurel/LaurelToCoreTranslator.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ def translateType (ty : HighTypeMd) : TranslateM LMonoTy := do
8484
| .TInt => return LMonoTy.int
8585
| .TBool => return LMonoTy.bool
8686
| .TString => return LMonoTy.string
87+
| .TBv n => return LMonoTy.bitvec n
8788
| .TVoid => return LMonoTy.bool -- Using bool as placeholder for void
8889
| .THeap => return .tcons "Heap" []
8990
| .TTypedField _ => return .tcons "Field" []
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/-
2+
Copyright Strata Contributors
3+
4+
SPDX-License-Identifier: Apache-2.0 OR MIT
5+
-/
6+
7+
import StrataTest.Util.TestDiagnostics
8+
import StrataTest.Languages.Laurel.TestExamples
9+
10+
open StrataTest.Util
11+
12+
namespace Strata
13+
namespace Laurel
14+
15+
def bvProgram := r"
16+
// Bitvector types in procedure signatures and variable declarations.
17+
18+
// Parameters and return types
19+
procedure identity32(x: bv 32) returns (r: bv 32) {
20+
r := x
21+
};
22+
23+
procedure identity8(x: bv 8) returns (r: bv 8) {
24+
r := x
25+
};
26+
27+
// Local variable with bv type
28+
procedure localBv() returns (r: bv 16) {
29+
var x: bv 16 := r;
30+
r := x
31+
};
32+
33+
// Opaque procedure returning bv64 — caller gets typed result
34+
procedure opaqueBv64() returns (r: bv 64);
35+
procedure callOpaque() returns (r: bv 64) {
36+
r := opaqueBv64()
37+
};
38+
39+
// Mixed bv and int parameters
40+
procedure mixedTypes(a: bv 32, b: int) returns (r: int) {
41+
r := b
42+
};
43+
"
44+
45+
#guard_msgs(drop info, error) in
46+
#eval testInputWithOffset "BitvectorTypes" bvProgram 14 processLaurelFile
47+
48+
end Laurel
49+
end Strata

StrataTest/Languages/Laurel/Examples/Objects/T1_MutableFields.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ procedure simpleAssign() {
3030
var c: Container := new Container;
3131
var iv: int := c#intValue;
3232
var rv: real := c#realValue;
33-
var bv: bool := c#boolValue;
33+
var boolVar: bool := c#boolValue;
3434
var sv: string := c#stringValue;
3535
3636
c#intValue := 2;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Bitvector types through the GOTO/CBMC pipeline.
2+
3+
procedure identity32(x: bv 32) returns (r: bv 32) {
4+
r := x
5+
};
6+
7+
procedure identity8(x: bv 8) returns (r: bv 8) {
8+
r := x
9+
};
10+
11+
procedure localBv() returns (r: bv 16) {
12+
var x: bv 16 := r;
13+
r := x
14+
};

0 commit comments

Comments
 (0)