Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement extern #130

Open
2 of 5 tasks
Tracked by #119
jlapeyre opened this issue Feb 16, 2024 · 2 comments
Open
2 of 5 tasks
Tracked by #119

Implement extern #130

jlapeyre opened this issue Feb 16, 2024 · 2 comments
Labels
Looking for assignee Looking to contribute? Browse these. required feature Feature or behavior in OQ3 spec, needs implementation

Comments

@jlapeyre
Copy link
Collaborator

jlapeyre commented Feb 16, 2024

  • lexer
  • oq3_parser
  • oq3_syntax (AST)
  • ASG
  • AST -> ASG

For example this fails to parse without errors, although it is valid OQ3.

extern f(int x);

Implementing extern requires several steps, as do most or all language features. However there is a model that you can follow closely at every step.

AST

It will be just about the same as the entry for Def, but of course, the block will be absent.

cd ./codegen_scripts
./mkgenerated.sh
/cpnodes.sh && ./cpgenerated.sh

If this fails, you might ask in this issue for help.

  • Check that code was generated similar to this code for Def:
    impl ast::HasName for Def {}
    impl Def {
    pub fn def_token(&self) -> Option<SyntaxToken> {
    support::token(&self.syntax, T![def])
    }
    pub fn typed_param_list(&self) -> Option<TypedParamList> {
    support::child(&self.syntax)
    }
    pub fn return_signature(&self) -> Option<ReturnSignature> {
    support::child(&self.syntax)
    }
    pub fn body(&self) -> Option<BlockExpr> {
    support::child(&self.syntax)
    }
    pub fn semicolon_token(&self) -> Option<SyntaxToken> {
    support::token(&self.syntax, T![;])
    }
    }

These methods will be called from syntax_to_semantics.rs to translate the AST to ASG.

substituting extern for def. And

fn def_stmt(p: &mut Parser<'_>, m: Marker) {
assert!(p.at(T![def]));
p.bump_any();
// Read the name of the subroutine. (This records an error message on failure.)
name_r(p, ITEM_RECOVERY_SET);
// Read optional gate parameters (not qubit and params)
if p.at(T!['(']) {
params::param_list_def_params(p);
} else {
p.error("expected function arguments in def");
}
opt_ret_type(p);
// Read the code block.
expressions::try_block_expr(p);
// Mark this attempt at reading an item as complete.
m.complete(p, DEF);
}

ASG

Follow this model:

#[derive(Clone, Debug, PartialEq)]
pub struct DefStmt {
name: SymbolIdResult,
params: Vec<SymbolIdResult>,
block: Block,
return_type: Option<Type>,
}

AST -> ASG

Follow this model:

synast::Stmt::Def(def_stmt) => {
let name_node = def_stmt.name().unwrap();
with_scope!(context, ScopeType::Subroutine,
let params = bind_typed_parameter_list(def_stmt.typed_param_list(), context);
let block = from_block_expr(def_stmt.body().unwrap(), context);
);
// FIXME: Should we let subroutines have a parameterized type?
// This would be very convenient for matching signatures.
// let num_params = match params {
// Some(ref params) => params.len(),
// None => 0,
// };
let ret_type = def_stmt.return_signature()
.and_then(|x| x.scalar_type())
.map(|x| from_scalar_type(&x, true, context));
let def_name_symbol_id = context.new_binding(
name_node.string().as_ref(),
&Type::Void,
&name_node,
);
Some(asg::DefStmt::new(def_name_symbol_id, params.unwrap(), block, ret_type).to_stmt())
}

Done

And it's as easy as that! Now enjoy parsing extern statements !

@jlapeyre jlapeyre added Looking for assignee Looking to contribute? Browse these. required feature Feature or behavior in OQ3 spec, needs implementation labels Mar 26, 2024
@RasmitDevkota
Copy link

I would like to work on this issue as a start for contributing to #119!

@RasmitDevkota
Copy link

RasmitDevkota commented May 11, 2024

I see in openqasm3_parser/crates/oq3_parser/src/grammar/items.rs that there are kinds defined in openqasm3_parser/crates/oq3_parser/src/syntax_kind/syntax_kind_enum.rs, but I don't see one specifically for EXTERN, only one for EXTERN_KW. I assume this is needed, so does this need to be defined manually or was it supposed to be generated at some point? Also, although it wasn't mentioned in the tasks, would it be correct to add Extern to each of the casting-related functions for Stmt and AnyHasName?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Looking for assignee Looking to contribute? Browse these. required feature Feature or behavior in OQ3 spec, needs implementation
Projects
None yet
Development

No branches or pull requests

2 participants