@@ -834,6 +834,66 @@ impl<'a> PVSParser<'a> {
834834 } ) ;
835835 }
836836
837+ // CASES expression: CASES expr OF sel1, sel2, ... ENDCASES
838+ if self . try_consume ( "CASES" ) {
839+ let case_expr = self . parse_expr ( ) ?;
840+ if !self . try_consume ( "OF" ) {
841+ bail ! ( "Expected OF after CASES expression" ) ;
842+ }
843+ let mut selections = Vec :: new ( ) ;
844+ let mut else_clause = None ;
845+ loop {
846+ self . skip_whitespace_and_comments ( ) ;
847+ // Check for ELSE clause
848+ if self . try_consume ( "ELSE" ) {
849+ self . expect_char ( ':' ) ?;
850+ else_clause = Some ( Box :: new ( self . parse_expr ( ) ?) ) ;
851+ break ;
852+ }
853+ // Check for ENDCASES
854+ if self . try_consume ( "ENDCASES" ) {
855+ break ;
856+ }
857+ // Parse constructor pattern: ctor_name(args): result_expr
858+ // or ctor_name: result_expr
859+ let ctor = self . parse_identifier ( ) ?;
860+ let mut pattern_args = Vec :: new ( ) ;
861+ if self . peek_char ( ) == Some ( '(' ) {
862+ self . consume_char ( ) ; // '('
863+ while self . peek_char ( ) != Some ( ')' ) {
864+ pattern_args. push ( self . parse_identifier ( ) ?) ;
865+ if !self . try_consume ( "," ) {
866+ break ;
867+ }
868+ }
869+ self . expect_char ( ')' ) ?;
870+ }
871+ self . expect_char ( ':' ) ?;
872+ let result = self . parse_expr ( ) ?;
873+ selections. push ( PVSCaseSelection {
874+ pattern : if pattern_args. is_empty ( ) {
875+ PVSPattern :: Variable ( ctor)
876+ } else {
877+ PVSPattern :: Constructor {
878+ name : ctor,
879+ args : pattern_args,
880+ }
881+ } ,
882+ expr : result,
883+ } ) ;
884+ // Comma separates selections; also check for ENDCASES
885+ if !self . try_consume ( "," ) {
886+ self . try_consume ( "ENDCASES" ) ;
887+ break ;
888+ }
889+ }
890+ return Ok ( PVSExpr :: Cases {
891+ expr : Box :: new ( case_expr) ,
892+ selections,
893+ else_clause,
894+ } ) ;
895+ }
896+
837897 // LET
838898 if self . try_consume ( "LET" ) {
839899 let mut bindings = Vec :: new ( ) ;
@@ -1301,7 +1361,36 @@ impl<'a> PVSParser<'a> {
13011361 return Ok ( None ) ;
13021362 }
13031363
1364+ // Parse first identifier
13041365 let name = self . parse_identifier ( ) ?;
1366+
1367+ // Handle comma-separated identifiers (e.g., "x, y: VAR nat")
1368+ // Collect additional names if commas follow before colon
1369+ let mut extra_names: Vec < String > = Vec :: new ( ) ;
1370+ while self . peek_char ( ) == Some ( ',' ) {
1371+ self . consume_char ( ) ; // consume ','
1372+ extra_names. push ( self . parse_identifier ( ) ?) ;
1373+ }
1374+
1375+ // Handle function-style declarations: name(params): ...
1376+ // Skip over the parameter list in parentheses before the colon
1377+ if self . peek_char ( ) == Some ( '(' ) {
1378+ let mut depth = 0 ;
1379+ loop {
1380+ match self . consume_char ( ) {
1381+ Some ( '(' ) => depth += 1 ,
1382+ Some ( ')' ) => {
1383+ depth -= 1 ;
1384+ if depth == 0 {
1385+ break ;
1386+ }
1387+ }
1388+ None => bail ! ( "Unexpected end of input in parameter list" ) ,
1389+ _ => { }
1390+ }
1391+ }
1392+ }
1393+
13051394 self . expect_char ( ':' ) ?;
13061395
13071396 // Type declaration
@@ -1314,6 +1403,24 @@ impl<'a> PVSParser<'a> {
13141403 return Ok ( Some ( PVSDeclaration :: TypeDecl { name, definition } ) ) ;
13151404 }
13161405
1406+ // VAR declaration (e.g., "x, y: VAR nat") — variable binding, not a goal
1407+ // Skip it and return None so the parser continues to the next declaration
1408+ if self . try_consume ( "VAR" ) {
1409+ // Consume the type name (e.g., "nat") to advance past it
1410+ let _var_type = self . parse_type ( ) ?;
1411+ return Ok ( Some ( PVSDeclaration :: ConstDecl {
1412+ name,
1413+ declared_type : _var_type,
1414+ definition : None ,
1415+ } ) ) ;
1416+ }
1417+
1418+ // DATATYPE declaration (e.g., "list: DATATYPE BEGIN ... END list")
1419+ if self . try_consume ( "DATATYPE" ) {
1420+ let constructors = self . parse_pvs_datatype_body ( ) ?;
1421+ return Ok ( Some ( PVSDeclaration :: Datatype { name, constructors } ) ) ;
1422+ }
1423+
13171424 // Formula declaration
13181425 let formula_kind = if self . try_consume ( "AXIOM" ) {
13191426 Some ( PVSFormulaKind :: Axiom )
@@ -1338,6 +1445,27 @@ impl<'a> PVSParser<'a> {
13381445 return Ok ( Some ( PVSDeclaration :: FormulaDecl { name, kind, formula } ) ) ;
13391446 }
13401447
1448+ // RECURSIVE function declaration
1449+ if self . try_consume ( "RECURSIVE" ) {
1450+ let declared_type = self . parse_type ( ) ?;
1451+ let body = if self . try_consume ( "=" ) {
1452+ self . parse_expr ( ) ?
1453+ } else {
1454+ PVSExpr :: Name ( "_" . to_string ( ) )
1455+ } ;
1456+ let measure = if self . try_consume ( "MEASURE" ) {
1457+ Some ( self . parse_expr ( ) ?)
1458+ } else {
1459+ None
1460+ } ;
1461+ return Ok ( Some ( PVSDeclaration :: RecursiveDecl {
1462+ name,
1463+ signature : declared_type,
1464+ measure,
1465+ body,
1466+ } ) ) ;
1467+ }
1468+
13411469 // Constant declaration (with optional definition)
13421470 let declared_type = self . parse_type ( ) ?;
13431471 let definition = if self . try_consume ( "=" ) {
@@ -1353,6 +1481,74 @@ impl<'a> PVSParser<'a> {
13531481 } ) )
13541482 }
13551483
1484+ /// Parse the body of a PVS DATATYPE declaration (after "DATATYPE" keyword).
1485+ ///
1486+ /// PVS datatype syntax:
1487+ /// ```text
1488+ /// BEGIN
1489+ /// null: null?
1490+ /// cons(car: T, cdr: list): cons?
1491+ /// END list
1492+ /// ```
1493+ fn parse_pvs_datatype_body ( & mut self ) -> Result < Vec < PVSConstructor > > {
1494+ let mut constructors = Vec :: new ( ) ;
1495+
1496+ // Expect BEGIN
1497+ if !self . try_consume ( "BEGIN" ) {
1498+ bail ! ( "Expected BEGIN after DATATYPE" ) ;
1499+ }
1500+
1501+ // Parse constructors until END
1502+ loop {
1503+ self . skip_whitespace_and_comments ( ) ;
1504+
1505+ // Check for END (the outer parse_theory loop will consume END + name)
1506+ if self . remaining ( ) . to_uppercase ( ) . starts_with ( "END" ) {
1507+ // Consume "END" and the datatype name that follows
1508+ self . try_consume ( "END" ) ;
1509+ // Consume the datatype name
1510+ let _ = self . parse_identifier ( ) ;
1511+ break ;
1512+ }
1513+
1514+ // Parse constructor name
1515+ let ctor_name = self . parse_identifier ( ) ?;
1516+
1517+ // Parse optional accessor list: (field: Type, ...)
1518+ let mut accessors = Vec :: new ( ) ;
1519+ if self . peek_char ( ) == Some ( '(' ) {
1520+ self . consume_char ( ) ; // '('
1521+ while self . peek_char ( ) != Some ( ')' ) {
1522+ let field_name = self . parse_identifier ( ) ?;
1523+ self . expect_char ( ':' ) ?;
1524+ let field_type = self . parse_type ( ) ?;
1525+ accessors. push ( ( field_name, field_type) ) ;
1526+ if !self . try_consume ( "," ) {
1527+ break ;
1528+ }
1529+ }
1530+ self . expect_char ( ')' ) ?;
1531+ }
1532+
1533+ // Parse optional recogniser: ctor_name?
1534+ let recogniser = if self . peek_char ( ) == Some ( ':' ) {
1535+ self . consume_char ( ) ; // ':'
1536+ self . skip_whitespace_and_comments ( ) ;
1537+ Some ( self . parse_identifier ( ) ?)
1538+ } else {
1539+ None
1540+ } ;
1541+
1542+ constructors. push ( PVSConstructor {
1543+ name : ctor_name,
1544+ accessors,
1545+ recogniser,
1546+ } ) ;
1547+ }
1548+
1549+ Ok ( constructors)
1550+ }
1551+
13561552 /// Parse a PVS strategy (tactic)
13571553 pub fn parse_strategy ( & mut self ) -> Result < PVSStrategy > {
13581554 self . skip_whitespace_and_comments ( ) ;
0 commit comments