Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

All notable changes to this project will be documented in this file.

## [0.3.0] - 2025-03-13

### Enhancements
- Allow using constants defined in the IDL as integers.

## [0.2.1] - 2025-03-12

### Fixes
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ strip = true
panic = "abort"

[workspace.package]
version = "0.2.1"
version = "0.3.0"
1 change: 1 addition & 0 deletions idlc_ast/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ idlc_errors = {path = "../idlc_errors" }
pest = "2.7.9"
pest_derive = "2.7.9"
thiserror = "1.0.59"
lazy_static = "1.5.0"
2 changes: 1 addition & 1 deletion idlc_ast/src/idl_grammar.pest
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ float_type = @{ "float" ~ ("32" | "64") }
primitive_type = @{ (integer_type | float_type) }
value = @{ ("-"? ~ "0x" ~ ASCII_HEX_DIGIT+ | "-"? ~ ASCII_DIGIT+ ~ ("." ~ ASCII_DIGIT+)?) }

array_size = @{ ASCII_DIGIT+ }
array_size = @{ ASCII_DIGIT+ | ident }
bounded_array = { "[" ~ array_size ~ "]" }
unbounded_array = { "[" ~ "]" }

Expand Down
57 changes: 53 additions & 4 deletions idlc_ast/src/pst.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
// Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
// SPDX-License-Identifier: BSD-3-Clause

use std::collections::HashMap;
use std::{path::PathBuf, rc::Rc};

use pest::{iterators::Pair, Parser};
use pest_derive::Parser;

use lazy_static::lazy_static;
use std::sync::Mutex;

lazy_static! {
static ref HASHMAP: Mutex<HashMap<String, String>> = {
let m = HashMap::new();
Mutex::new(m)
};
}

// Import all AST types
use super::ast::{
Const, Count, Documentation, Function, FunctionAttribute, Ident, Interface, InterfaceNode,
Expand Down Expand Up @@ -179,6 +190,7 @@ impl From<Pair<'_, Rule>> for ParamTypeIn {
fn from(rule: Pair<Rule>) -> Self {
debug_assert_eq!(rule.as_rule(), Rule::param_type);
let mut inner = rule.into_inner();
let map = HASHMAP.lock().unwrap();
let r#type = Type::from(ast_unwrap!(inner.next()));
if let Type::Custom(r#type) = &r#type {
if r#type == "buffer" {
Expand All @@ -190,7 +202,18 @@ impl From<Pair<'_, Rule>> for ParamTypeIn {
match pair.as_rule() {
Rule::unbounded_array => Self::Array(r#type, None),
Rule::bounded_array => {
let array_len: Count = ast_unwrap!(pair.into_inner().as_str().parse());
let array_val: String = ast_unwrap!(pair.into_inner().as_str().parse());
let is_decimal = array_val.parse::<u16>();
let array_len = match is_decimal {
Ok(val) => Count::new(val).unwrap(),
Err(_) => {
if let Some(value) = map.get(&array_val) {
Count::new(value.parse::<u16>().unwrap()).unwrap()
} else {
idlc_errors::unrecoverable!("Unknown variable {array_val}")
}
}
};
Self::Array(r#type, Some(array_len))
}
_ => unreachable!(),
Expand All @@ -204,6 +227,7 @@ impl From<Pair<'_, Rule>> for ParamTypeOut {
fn from(rule: Pair<Rule>) -> Self {
debug_assert_eq!(rule.as_rule(), Rule::param_type);
let mut inner = rule.into_inner();
let map = HASHMAP.lock().unwrap();
let r#type = Type::from(ast_unwrap!(inner.next()));
if let Type::Custom(r#type) = &r#type {
if r#type == "buffer" {
Expand All @@ -215,7 +239,18 @@ impl From<Pair<'_, Rule>> for ParamTypeOut {
match pair.as_rule() {
Rule::unbounded_array => Self::Array(r#type, None),
Rule::bounded_array => {
let array_len: Count = ast_unwrap!(pair.into_inner().as_str().parse());
let array_val: String = ast_unwrap!(pair.into_inner().as_str().parse());
let is_decimal = array_val.parse::<u16>();
let array_len = match is_decimal {
Ok(val) => Count::new(val).unwrap(),
Err(_) => {
if let Some(value) = map.get(&array_val) {
Count::new(value.parse::<u16>().unwrap()).unwrap()
} else {
idlc_errors::unrecoverable!("Unknown variable {array_val}")
}
}
};
Self::Array(r#type, Some(array_len))
}
_ => unreachable!(),
Expand Down Expand Up @@ -256,6 +291,7 @@ fn parse_struct(pair: Pair<Rule>) -> Rc<Node> {
let mut struct_pst = pair.into_inner().skip(1);
let ident: Ident = ast_unwrap!(struct_pst.next()).into();
let mut fields = Vec::<StructField>::new();
let map = HASHMAP.lock().unwrap();
for rule in struct_pst {
match rule.as_rule() {
Rule::struct_field => {
Expand All @@ -264,8 +300,19 @@ fn parse_struct(pair: Pair<Rule>) -> Rc<Node> {
let next = ast_unwrap!(iter.next());
let (elem, ident) = match next.as_rule() {
Rule::bounded_array => {
let array_len: Count =
let array_val: String =
ast_unwrap!(next.clone().into_inner().as_str().parse());
let is_decimal = array_val.parse::<u16>();
let array_len = match is_decimal {
Ok(val) => Count::new(val).unwrap(),
Err(_) => {
if let Some(value) = map.get(&array_val) {
Count::new(value.parse::<u16>().unwrap()).unwrap()
} else {
idlc_errors::unrecoverable!("Unknown variable {array_val}")
}
}
};
let ident = ast_unwrap!(iter.next()).as_str().to_string();
(array_len, ident)
}
Expand Down Expand Up @@ -297,7 +344,7 @@ fn parse_const(pair: Pair<Rule>, allow_undefined_behavior: bool) -> Const {
let mut inner = pair.into_inner().skip(1);

let ty = ast_unwrap!(inner.next()).as_str();
let ident = ast_unwrap!(inner.next()).into();
let ident: Ident = ast_unwrap!(inner.next()).into();
let value = ast_unwrap!(inner.next()).as_str();
let primitive = if allow_undefined_behavior {
Primitive::try_from(ty).unwrap()
Expand All @@ -306,6 +353,8 @@ fn parse_const(pair: Pair<Rule>, allow_undefined_behavior: bool) -> Const {
idlc_errors::unrecoverable!("'{value}' isn't in range for type '{ty}' [{e}]")
})
};
let mut map = HASHMAP.lock().unwrap();
map.insert(ident.to_string(), value.to_string());

Const {
ident,
Expand Down
7 changes: 5 additions & 2 deletions tests/idl/ITest.idl
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@ struct F2 {
uint8 b;
};

const uint32 CONST_VAL = 2;
const uint32 CONST_VAL_INF = 3;

struct ArrInStruct {
uint8[2] a;
uint8[CONST_VAL] a;
F2[2] c;
uint16 d;
};
Expand Down Expand Up @@ -62,7 +65,7 @@ interface ITest1 {
*/
method well_documented_method(in uint32 foo, out uint32 bar);
method test_obj_array_in(in ITest1[3] o_in, out uint32 a);
method test_obj_array_out(out ITest1[3] out, out uint32 a);
method test_obj_array_out(out ITest1[CONST_VAL_INF] out, out uint32 a);
method objects_in_struct(in ObjInStruct input, out ObjInStruct output);
#[optional]
method unimplemented(in uint32 foo); // this method should NOT have an implementation and that is OK
Expand Down