add: more samples and make them work
This commit is contained in:
67
src/lower.rs
67
src/lower.rs
@@ -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 }))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user