Skip to content

Commit

Permalink
Implement complex type specification (and declaration) (#193)
Browse files Browse the repository at this point in the history
The following are now parsed correctly and construct the correct type
in `oq3_semantics`:
`complex w;`
`complex[float] w;`
`complex[float[32]] w;`

Note that this does not yet implement complex literals. Nor any other
behavior peculiar to complex numbers.
  • Loading branch information
jlapeyre committed Mar 25, 2024
1 parent 8b7a788 commit 5ccf7af
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 4 deletions.
23 changes: 22 additions & 1 deletion crates/oq3_parser/src/grammar/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,10 @@ pub(crate) fn array_type_spec(p: &mut Parser<'_>) -> bool {
// Parse a scalar or quantum type.
// Don't record error if array is found. Do not parse array.
fn non_array_type_spec(p: &mut Parser<'_>) -> bool {
if p.at(T![complex]) {
complex_type_spec(p);
return true;
}
let m = p.start();
type_name(p);
if p.at(T!['[']) {
Expand All @@ -417,6 +421,22 @@ fn non_array_type_spec(p: &mut Parser<'_>) -> bool {
true
}

fn complex_type_spec(p: &mut Parser<'_>) {
assert!(p.at(T![complex]));
let m = p.start();
p.bump_any();
// designator is optional for `complex`.
if p.at(T!['[']) {
p.bump(T!['[']);
if !p.at(T![float]) {
p.error("Expecting `float` in complex designator`");
}
non_array_type_spec(p);
p.expect(T![']']);
}
m.complete(p, SCALAR_TYPE);
}

pub(crate) fn qubit_type_spec(p: &mut Parser<'_>) -> bool {
assert!(p.at(T![qubit]));
let m = p.start();
Expand All @@ -432,8 +452,9 @@ pub(crate) fn qubit_type_spec(p: &mut Parser<'_>) -> bool {
}

pub(crate) fn designator(p: &mut Parser<'_>) -> bool {
assert!(p.at(T!['[']));
let m = p.start();
p.eat(T!['[']);
p.bump(T!['[']);
// Log error for a literal designator that is not integer. We are
// conservative here. I am not sure that an expression that begins with one
// of the following literals cannot have an integer type. I am pretty sure
Expand Down
21 changes: 18 additions & 3 deletions crates/oq3_semantics/src/syntax_to_semantics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -908,8 +908,24 @@ fn from_scalar_type(
isconst: bool,
context: &mut Context,
) -> Type {
// We only support literal integer designators at the moment.
let width = match scalar_type.designator().and_then(|desg| desg.expr()) {
// If the scalar type is `complex`, then scalar_type.scalar_type() will return
// the base type, which is a float type. If scalar_type.scalar_type() is `None`,
// then it is a simple scalar type and the designator is in scalar_type.designator.
// Note that this is the point where we throw away the token `float`, which is
// superfluous.
// In OQ3 source, `complex` types have a different syntax from other scalar types.
// Eg, we write `int[32]`, but we don't write `complex[32]`, but rather `complex[float[32]]`.
// However `Type::Complex` has exactly the same form as other scalar types. In this case
// `width` is understood to be the width of each of real and imaginary components.
let designator = if let Some(float_type) = scalar_type.scalar_type() {
// complex
float_type.designator()
} else {
// not complex
scalar_type.designator()
};
let width = match designator.and_then(|desg| desg.expr()) {
// We only support literal integer designators at the moment.
Some(synast::Expr::Literal(ref literal)) => {
match literal.kind() {
synast::LiteralKind::IntNumber(int_num) => Some(int_num.value().unwrap() as u32),
Expand Down Expand Up @@ -957,7 +973,6 @@ fn from_classical_declaration_statement(
}
let scalar_type = type_decl.scalar_type().unwrap();
let typ = from_scalar_type(&scalar_type, type_decl.const_token().is_some(), context);

let name_str = type_decl.name().unwrap().string();
let initializer = from_expr(type_decl.expr(), context);
// FIXME: This error and several others can and should be moved to a subsequent pass.
Expand Down

0 comments on commit 5ccf7af

Please sign in to comment.