Skip to content

Commit

Permalink
extract list and tuple
Browse files Browse the repository at this point in the history
  • Loading branch information
NTTVy03 committed Jan 6, 2025
1 parent 49c4ac2 commit ce223c8
Show file tree
Hide file tree
Showing 10 changed files with 199 additions and 150 deletions.
2 changes: 1 addition & 1 deletion crates/parser/src/grammar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ mod declaration;
mod expression;
mod function;
mod include;
mod list_identity;
mod list;
mod main_component;
mod pragma;
mod statement;
Expand Down
12 changes: 8 additions & 4 deletions crates/parser/src/grammar/declaration.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
use super::expression::{expression, identifier_list, parameter_list};
use super::{expression::expression, list::{expression_tuple, identifier_tuple}};
use crate::{parser::Parser, token_kind::TokenKind::*};

// [N][M-1]
fn array(p: &mut Parser) -> bool {
let is_array = p.at(LBracket);

while p.at(LBracket) {
let array_marker = p.open();
p.expect(LBracket);
expression(p);
p.expect(RBracket);
p.close(array_marker, ArrayQuery);
}

is_array
Expand Down Expand Up @@ -89,7 +91,7 @@ pub(super) fn var_declaration(p: &mut Parser) {
// tuple of variables
// eg: var (in1, in2, in3) = (1, 2, 3);
if p.at(LParen) {
identifier_list(p);
identifier_tuple(p);
if p.at_var_assign() {
p.advance();
expression(p);
Expand Down Expand Up @@ -127,7 +129,7 @@ pub(super) fn signal_declaration(p: &mut Parser) {
// tuple of signal
// eg: signal (in1, in2, in3) <== tuple_value;
if p.at(LParen) {
identifier_list(p);
identifier_tuple(p);
// can not assign for input signal
if assign_able && p.at_inline_assign_signal() {
p.advance();
Expand Down Expand Up @@ -181,7 +183,9 @@ pub(super) fn component_declaration(p: &mut Parser) {
p.close(m_c, TemplateName);

// template params
parameter_list(p);
let parameter_marker = p.open();
expression_tuple(p);
p.close(parameter_marker, Call);
}

p.close(m, ComponentDecl);
Expand Down
202 changes: 89 additions & 113 deletions crates/parser/src/grammar/expression.rs
Original file line number Diff line number Diff line change
@@ -1,90 +1,59 @@
use list::expression_tuple;

use crate::parser::Marker;

use super::*;

pub(super) fn expression(p: &mut Parser) {
let m = p.open();
let open_marker = p.open();
circom_expression(p);
p.close(m, Expression);
p.close(open_marker, Expression);
}

/**
* grammar: "(param1, param2,..., paramn)"
* can be an empty ()
* TODO: why parse a stament inside expression module???
* manage 2 cases: normal expression (a++, a-b,...), tenary_conditional_statement (a ? b : c)
* circom_expression = expr ? expr: expr |
* expr
*/
pub(super) fn parameter_list(p: &mut Parser) {
let m = p.open();
p.expect(LParen);

while !p.at(RParen) && !p.eof() {
// each parameter can be an expression
expression(p);
fn circom_expression(p: &mut Parser) {
if let Some(lhs) = expression_rec(p, 0) {
let current_kind = p.current();

// there are no parameters remaining
if p.eat(Comma) == false {
break;
if matches!(current_kind, MarkQuestion) {
tenary_conditional_statement(p, lhs);
}
}

p.expect(RParen);

p.close(m, ParameterList);
}

/**
* grammar: "(iden1, iden2,..., idenn)"
* can be an empty ()
*/
pub(super) fn identifier_list(p: &mut Parser) {
let m = p.open();
p.expect(LParen);

// iden1, iden2, iden3
list_identity::parse(p);
* grammar: <condition> ? <expression-1> : <expression-2>
* <condition> is also an expression,
* whose open and close events are already in the Parser event list
* lhs is that open event
*/
pub fn tenary_conditional_statement(p: &mut Parser, lhs: Marker) {
// <condition>
let open_marker = p.open_before(lhs);
p.close(open_marker, Condition);

// <condition> ?
p.expect(MarkQuestion);

// <condition> ? <expression-1>
let first_expression = p.open();
expression_rec(p, 0);
p.close(first_expression, Expression);

// <condition> ? <expression-1> :
p.expect(Colon);

// <condition> ? <expression-1> : <expression-2>
let last_expression = p.open();
expression_rec(p, 0);
p.close(last_expression, Expression);

p.expect(RParen);
p.close(m, IdentifierList);
}

/**
* grammar:
* "= | <== | <--" expression
*/
// pub(super) fn tuple_init(p: &mut Parser) {
// let m = p.open();
// p.expect_any(&[Assign, RAssignSignal, RAssignConstraintSignal]);
// expression(p);
// p.close(m, TupleInit);
// }

fn expression_atom(p: &mut Parser) -> Option<Marker> {
let m_close: Marker;
match p.current() {
Number => {
let m = p.open();
p.advance();
m_close = p.close(m, Number);
Some(m_close)
}
Identifier => {
let m = p.open();
p.advance();
m_close = p.close(m, Identifier);
Some(m_close)
}
LParen => {
let m = p.open();
p.expect(LParen);
expression_rec(p, 0);
p.expect(RParen);
m_close = p.close(m, Tuple);
Some(m_close)
}
_ => {
p.advance_with_error("Invalid Token");
None
}
}
p.close(open_marker, TenaryConditional);
}

/**
Expand All @@ -95,14 +64,13 @@ pub fn expression_rec(p: &mut Parser, pb: u16) -> Option<Marker> {
// next, consume first atom (identifier/number/tuple)
let parse_able: Option<Marker> = {
if let Some(pp) = p.current().prefix() {
println!("Prefix...");
let kind = p.current();
let m = p.open();
let open_marker = p.open();
// consume prefix token (++, --, -, +, !)
p.advance();
// continue with the next tokens
expression_rec(p, pp);
Some(p.close(m, kind))
Some(p.close(open_marker, kind))
} else {
expression_atom(p)
}
Expand All @@ -113,61 +81,66 @@ pub fn expression_rec(p: &mut Parser, pb: u16) -> Option<Marker> {
let mut lhs = parse_able.unwrap();

while !p.eof() {
let current_kind = p.current();
let kind = p.current();

if let Some((lp, rp)) = kind.infix() {
// infix case: <a> + <b>
// <a> is already consume in parse_able

if let Some((lp, rp)) = current_kind.infix() {
// TODO: what does it mean???
if rp <= pb {
return None;
}

let m = p.open_before(lhs);
// open event that wrap the first parameter (<a>)
let open_marker = p.open_before(lhs);

// consume the infix token
p.advance();

// extract the second parameter
// eg: <a> + <b> --> extract <b>
expression_rec(p, lp);
lhs = p.close(m, current_kind);

} else if let Some(pp) = current_kind.postfix() {
println!("Postfix...");
lhs = p.close(open_marker, kind);

} else if let Some(pp) = kind.postfix() {
if pp <= pb {
return None;
}

match current_kind {
match kind {
LParen => {
// function call
let m = p.open_before(lhs);
parameter_list(p);
lhs = p.close(m, Call);
let open_marker = p.open_before(lhs);
expression_tuple(p);
lhs = p.close(open_marker, Call);
}
LBracket => {
// array subscript: abc[N - 1]
let m = p.open_before(lhs);
let open_marker = p.open_before(lhs);
p.expect(LBracket);
expression(p);
p.expect(RBracket);
p.close(m, ArrayQuery);
p.close(open_marker, ArrayQuery);
}
Dot => {
// attribute access
// abc[N - 1].def OR abc.def --> component call
let m = p.open_before(lhs);
let open_marker = p.open_before(lhs);
p.expect(Dot);
p.expect(Identifier);
p.close(m, ComponentCall);
p.close(open_marker, ComponentCall);
}
UnitDec | UnitInc => {
let m = p.open_before(lhs);
// consume token and do nothing
let open_marker = p.open_before(lhs);
// consume token ++/-- and do nothing
p.advance();
p.close(m, Expression);
p.close(open_marker, Expression);
}
_ => {
// not a postfix token
p.advance_with_error(&format!("Expect a postfix token, but found {:?}", current_kind));
p.advance_with_error(&format!("Expect a postfix token, but found {:?}", kind));
break;
}
};
}
Expand All @@ -176,34 +149,37 @@ pub fn expression_rec(p: &mut Parser, pb: u16) -> Option<Marker> {
}
}

// return the outer open marker
Some(lhs)
}

/**
* circom_expression = expr ? expr: expr |
* expr
* the unit element in expression
* eg: a, b, 5, 100, (<expression>)
*/
fn circom_expression(p: &mut Parser) {
if let Some(mut lhs) = expression_rec(p, 0) {
let current_kind = p.current();
if matches!(current_kind, MarkQuestion) {
let m = p.open_before(lhs);
lhs = p.close(m, Condition);

let m = p.open_before(lhs);
fn expression_atom(p: &mut Parser) -> Option<Marker> {
let kind = p.current();

match kind {
Number | Identifier => {
let open_marker = p.open();
p.advance();

let first_expression = p.open();
expression_rec(p, 0);
p.close(first_expression, Expression);

p.expect(Colon);

let last_expression = p.open();
let m_close = p.close(open_marker, kind);
Some(m_close)
},
LParen => {
// (<expression>)
let open_marker = p.open();
p.expect(LParen);
expression_rec(p, 0);
p.close(last_expression, Expression);

p.close(m, TenaryConditional);
p.expect(RParen);
let m_close = p.close(open_marker, Expression);
Some(m_close)
},
_ => {
p.advance_with_error("Invalid Token");
None
}
}
}

12 changes: 6 additions & 6 deletions crates/parser/src/grammar/function.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use list::identifier_tuple;

use crate::grammar::*;

// fucntion name()
Expand All @@ -10,12 +12,10 @@ pub fn function_parse(p: &mut Parser) {
p.expect(Identifier);
p.close(fn_name_marker, FunctionName);

p.expect(LParen);
let arg_marker = p.open();
list_identity::parse(p);
p.close(arg_marker, ParameterList);
p.expect(RParen);

let parameter_marker = p.open();
identifier_tuple(p);
p.close(parameter_marker, ParameterList);

block::block(p);

p.close(m, FunctionDef);
Expand Down
Loading

0 comments on commit ce223c8

Please sign in to comment.