add: more samples and make them work

This commit is contained in:
2026-03-12 22:55:14 -07:00
parent 6c4118c489
commit 46935005f7
8 changed files with 525 additions and 90 deletions

View File

@@ -1264,8 +1264,12 @@ impl Parser {
self.advance();
self.expect(&Token::LParen)?;
let digits = self.parse_expression()?;
self.expect(&Token::Colon)?;
let decimals = self.parse_expression()?;
// Decimal positions are optional — `Packed(10)` means `Packed(10:0)`.
let decimals = if self.eat(&Token::Colon) {
self.parse_expression()?
} else {
Expression::Literal(Literal::Integer(0))
};
self.expect(&Token::RParen)?;
Ok(TypeSpec::Packed(Box::new(digits), Box::new(decimals)))
}
@@ -1273,8 +1277,12 @@ impl Parser {
self.advance();
self.expect(&Token::LParen)?;
let digits = self.parse_expression()?;
self.expect(&Token::Colon)?;
let decimals = self.parse_expression()?;
// Decimal positions are optional — `Zoned(10)` means `Zoned(10:0)`.
let decimals = if self.eat(&Token::Colon) {
self.parse_expression()?
} else {
Expression::Literal(Literal::Integer(0))
};
self.expect(&Token::RParen)?;
Ok(TypeSpec::Zoned(Box::new(digits), Box::new(decimals)))
}
@@ -1282,8 +1290,12 @@ impl Parser {
self.advance();
self.expect(&Token::LParen)?;
let digits = self.parse_expression()?;
self.expect(&Token::Colon)?;
let decimals = self.parse_expression()?;
// Decimal positions are optional — `Bindec(10)` means `Bindec(10:0)`.
let decimals = if self.eat(&Token::Colon) {
self.parse_expression()?
} else {
Expression::Literal(Literal::Integer(0))
};
self.expect(&Token::RParen)?;
Ok(TypeSpec::Bindec(Box::new(digits), Box::new(decimals)))
}
@@ -1627,28 +1639,21 @@ impl Parser {
fn parse_dsply(&mut self) -> Result<Statement, LowerError> {
self.advance(); // KwDsply
// Two forms:
// Three forms:
// DSPLY expr;
// DSPLY (expr : msgq : response);
// DSPLY (expr : msgq : response); ← parenthesised colon-separated
// DSPLY expr msgq response; ← space-separated (no parens)
if self.peek() == &Token::LParen {
// peek ahead — if the next token after '(' looks like an expression
// followed by ':' it's the three-arg form
self.advance(); // (
let expr = self.parse_expression()?;
let mut msg_q = None;
let mut response = None;
if self.eat(&Token::Colon) {
if let Token::Identifier(s) = self.peek().clone() {
self.advance();
msg_q = Some(s);
} else {
self.eat(&Token::Colon);
}
// Accept any name-like token for msgq / response, including
// tokens that collide with keywords (e.g. a variable `n`).
msg_q = self.try_parse_ident_or_name().map(|s| s.to_lowercase());
if self.eat(&Token::Colon) {
if let Token::Identifier(s) = self.peek().clone() {
self.advance();
response = Some(s);
}
response = self.try_parse_ident_or_name().map(|s| s.to_lowercase());
}
}
self.eat(&Token::RParen);
@@ -1656,8 +1661,28 @@ impl Parser {
Ok(Statement::Dsply(DsplyStmt { expr, msg_q, response }))
} else {
let expr = self.parse_expression()?;
// Space-separated msgq and response operands (no parentheses):
// DSPLY prompt ' ' response_var;
// DSPLY prompt msgq response_var;
// After the expression, a string literal or another identifier
// signals the optional msgq operand, followed by the response var.
let mut msg_q = None;
let mut response = None;
match self.peek().clone() {
Token::StringLit(s) => {
self.advance();
msg_q = Some(s);
// Optional response variable follows the msgq.
response = self.try_parse_ident_or_name().map(|s| s.to_lowercase());
}
Token::Identifier(_) => {
msg_q = self.try_parse_ident_or_name().map(|s| s.to_lowercase());
response = self.try_parse_ident_or_name().map(|s| s.to_lowercase());
}
_ => {}
}
self.eat_semicolon();
Ok(Statement::Dsply(DsplyStmt { expr, msg_q: None, response: None }))
Ok(Statement::Dsply(DsplyStmt { expr, msg_q, response }))
}
}