From 30d80d191f8169643780276ca685c39016b36592 Mon Sep 17 00:00:00 2001 From: gluax Date: Thu, 29 Apr 2021 14:03:29 -0400 Subject: [PATCH 01/24] require comma or semi-colon for now --- grammar/README.md | 81 +++++++++++++++++---------------------- grammar/abnf-grammar.txt | 7 +--- parser/src/parser/file.rs | 66 ++++++++++++++++++++++++------- 3 files changed, 90 insertions(+), 64 deletions(-) diff --git a/grammar/README.md b/grammar/README.md index 959d593d5f..e2d6ee438c 100644 --- a/grammar/README.md +++ b/grammar/README.md @@ -466,7 +466,7 @@ described above. newline = line-feed / carriage-return / carriage-return line-feed ``` -Go to: _[carriage-return](#user-content-carriage-return), [line-feed](#user-content-line-feed)_; +Go to: _[line-feed](#user-content-line-feed), [carriage-return](#user-content-carriage-return)_; Line terminators form whitespace, along with spaces and horizontal tabs. @@ -476,7 +476,7 @@ Line terminators form whitespace, along with spaces and horizontal tabs. whitespace = space / horizontal-tab / newline ``` -Go to: _[horizontal-tab](#user-content-horizontal-tab), [newline](#user-content-newline), [space](#user-content-space)_; +Go to: _[horizontal-tab](#user-content-horizontal-tab), [space](#user-content-space), [newline](#user-content-newline)_; There are two kinds of comments in Leo, as in other languages. @@ -494,7 +494,7 @@ the ones used in the Java language reference. comment = block-comment / end-of-line-comment ``` -Go to: _[end-of-line-comment](#user-content-end-of-line-comment), [block-comment](#user-content-block-comment)_; +Go to: _[block-comment](#user-content-block-comment), [end-of-line-comment](#user-content-end-of-line-comment)_; @@ -511,7 +511,7 @@ rest-of-block-comment = "*" rest-of-block-comment-after-star / not-star rest-of-block-comment ``` -Go to: _[not-star](#user-content-not-star), [rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star), [rest-of-block-comment](#user-content-rest-of-block-comment)_; +Go to: _[rest-of-block-comment](#user-content-rest-of-block-comment), [not-star](#user-content-not-star), [rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star)_; @@ -521,7 +521,7 @@ rest-of-block-comment-after-star = "/" / not-star-or-slash rest-of-block-comment ``` -Go to: _[rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star), [not-star-or-slash](#user-content-not-star-or-slash), [rest-of-block-comment](#user-content-rest-of-block-comment)_; +Go to: _[rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star), [rest-of-block-comment](#user-content-rest-of-block-comment), [not-star-or-slash](#user-content-not-star-or-slash)_; @@ -596,7 +596,7 @@ lowercase-letter = %x61-7A ; a-z letter = uppercase-letter / lowercase-letter ``` -Go to: _[lowercase-letter](#user-content-lowercase-letter), [uppercase-letter](#user-content-uppercase-letter)_; +Go to: _[uppercase-letter](#user-content-uppercase-letter), [lowercase-letter](#user-content-lowercase-letter)_; An identifier is a non-empty sequence of letters, digits, and underscores, @@ -764,7 +764,7 @@ atomic-literal = untyped-literal / address-literal ``` -Go to: _[signed-literal](#user-content-signed-literal), [untyped-literal](#user-content-untyped-literal), [field-literal](#user-content-field-literal), [product-group-literal](#user-content-product-group-literal), [boolean-literal](#user-content-boolean-literal), [address-literal](#user-content-address-literal), [unsigned-literal](#user-content-unsigned-literal)_; +Go to: _[product-group-literal](#user-content-product-group-literal), [address-literal](#user-content-address-literal), [boolean-literal](#user-content-boolean-literal), [unsigned-literal](#user-content-unsigned-literal), [field-literal](#user-content-field-literal), [untyped-literal](#user-content-untyped-literal), [signed-literal](#user-content-signed-literal)_; After defining the (mostly) alphanumeric tokens above, @@ -809,7 +809,7 @@ token = keyword / symbol ``` -Go to: _[keyword](#user-content-keyword), [atomic-literal](#user-content-atomic-literal), [package-name](#user-content-package-name), [annotation-name](#user-content-annotation-name), [symbol](#user-content-symbol), [format-string](#user-content-format-string), [identifier](#user-content-identifier)_; +Go to: _[annotation-name](#user-content-annotation-name), [symbol](#user-content-symbol), [atomic-literal](#user-content-atomic-literal), [identifier](#user-content-identifier), [package-name](#user-content-package-name), [keyword](#user-content-keyword), [format-string](#user-content-format-string)_; @@ -866,7 +866,7 @@ group-type = %s"group" arithmetic-type = integer-type / field-type / group-type ``` -Go to: _[integer-type](#user-content-integer-type), [field-type](#user-content-field-type), [group-type](#user-content-group-type)_; +Go to: _[group-type](#user-content-group-type), [integer-type](#user-content-integer-type), [field-type](#user-content-field-type)_; The arithmetic types, along with the boolean and address types, @@ -887,7 +887,7 @@ address-type = %s"address" scalar-type = boolean-type / arithmetic-type / address-type ``` -Go to: _[boolean-type](#user-content-boolean-type), [arithmetic-type](#user-content-arithmetic-type), [address-type](#user-content-address-type)_; +Go to: _[arithmetic-type](#user-content-arithmetic-type), [address-type](#user-content-address-type), [boolean-type](#user-content-boolean-type)_; Circuit types are denoted by identifiers and the keyword `Self`. @@ -904,7 +904,7 @@ self-type = %s"Self" circuit-type = identifier / self-type ``` -Go to: _[self-type](#user-content-self-type), [identifier](#user-content-identifier)_; +Go to: _[identifier](#user-content-identifier), [self-type](#user-content-self-type)_; A tuple type consists of zero, two, or more component types. @@ -927,7 +927,7 @@ or a tuple of one or more dimensions. array-type = "[" type ";" array-dimensions "]" ``` -Go to: _[array-dimensions](#user-content-array-dimensions), [type](#user-content-type)_; +Go to: _[type](#user-content-type), [array-dimensions](#user-content-array-dimensions)_; @@ -948,7 +948,7 @@ i.e. types whose values contain (sub-)values aggregate-type = tuple-type / array-type / circuit-type ``` -Go to: _[tuple-type](#user-content-tuple-type), [array-type](#user-content-array-type), [circuit-type](#user-content-circuit-type)_; +Go to: _[array-type](#user-content-array-type), [circuit-type](#user-content-circuit-type), [tuple-type](#user-content-tuple-type)_; Scalar and aggregate types form all the types. @@ -958,7 +958,7 @@ Scalar and aggregate types form all the types. type = scalar-type / aggregate-type ``` -Go to: _[scalar-type](#user-content-scalar-type), [aggregate-type](#user-content-aggregate-type)_; +Go to: _[aggregate-type](#user-content-aggregate-type), [scalar-type](#user-content-scalar-type)_; The lexical grammar given earlier defines product group literals. @@ -1007,7 +1007,7 @@ a group literal is either a product group literal or an affine group literal. group-literal = product-group-literal / affine-group-literal ``` -Go to: _[product-group-literal](#user-content-product-group-literal), [affine-group-literal](#user-content-affine-group-literal)_; +Go to: _[affine-group-literal](#user-content-affine-group-literal), [product-group-literal](#user-content-product-group-literal)_; As often done in grammatical language syntax specifications, @@ -1036,7 +1036,7 @@ primary-expression = identifier / circuit-expression ``` -Go to: _[expression](#user-content-expression), [tuple-expression](#user-content-tuple-expression), [array-expression](#user-content-array-expression), [literal](#user-content-literal), [circuit-expression](#user-content-circuit-expression), [identifier](#user-content-identifier)_; +Go to: _[array-expression](#user-content-array-expression), [tuple-expression](#user-content-tuple-expression), [circuit-expression](#user-content-circuit-expression), [identifier](#user-content-identifier), [literal](#user-content-literal), [expression](#user-content-expression)_; Tuple expressions construct tuples. @@ -1097,7 +1097,7 @@ Go to: _[array-dimensions](#user-content-array-dimensions), [expression](#user-c array-construction = array-inline-construction / array-repeat-construction ``` -Go to: _[array-inline-construction](#user-content-array-inline-construction), [array-repeat-construction](#user-content-array-repeat-construction)_; +Go to: _[array-repeat-construction](#user-content-array-repeat-construction), [array-inline-construction](#user-content-array-inline-construction)_; @@ -1133,7 +1133,7 @@ Go to: _[circuit-inline-element](#user-content-circuit-inline-element), [circuit circuit-inline-element = identifier ":" expression / identifier ``` -Go to: _[expression](#user-content-expression), [identifier](#user-content-identifier)_; +Go to: _[identifier](#user-content-identifier), [expression](#user-content-expression)_; @@ -1184,7 +1184,7 @@ postfix-expression = primary-expression / postfix-expression "[" [expression] ".." [expression] "]" ``` -Go to: _[expression](#user-content-expression), [primary-expression](#user-content-primary-expression), [identifier](#user-content-identifier), [function-arguments](#user-content-function-arguments), [circuit-type](#user-content-circuit-type), [postfix-expression](#user-content-postfix-expression), [natural](#user-content-natural)_; +Go to: _[natural](#user-content-natural), [identifier](#user-content-identifier), [postfix-expression](#user-content-postfix-expression), [circuit-type](#user-content-circuit-type), [function-arguments](#user-content-function-arguments), [primary-expression](#user-content-primary-expression), [expression](#user-content-expression)_; Unary operators have the highest operator precedence. @@ -1198,7 +1198,7 @@ unary-expression = postfix-expression / "-" unary-expression ``` -Go to: _[unary-expression](#user-content-unary-expression), [postfix-expression](#user-content-postfix-expression)_; +Go to: _[postfix-expression](#user-content-postfix-expression), [unary-expression](#user-content-unary-expression)_; Next in the operator precedence is exponentiation, @@ -1212,7 +1212,7 @@ exponential-expression = unary-expression / unary-expression "**" exponential-expression ``` -Go to: _[unary-expression](#user-content-unary-expression), [exponential-expression](#user-content-exponential-expression)_; +Go to: _[exponential-expression](#user-content-exponential-expression), [unary-expression](#user-content-unary-expression)_; Next in precedence come multiplication and division, both left-associative. @@ -1224,7 +1224,7 @@ multiplicative-expression = exponential-expression / multiplicative-expression "/" exponential-expression ``` -Go to: _[exponential-expression](#user-content-exponential-expression), [multiplicative-expression](#user-content-multiplicative-expression)_; +Go to: _[multiplicative-expression](#user-content-multiplicative-expression), [exponential-expression](#user-content-exponential-expression)_; Then there are addition and subtraction, both left-assocative. @@ -1332,7 +1332,7 @@ statement = expression-statement / block ``` -Go to: _[constant-declaration](#user-content-constant-declaration), [variable-declaration](#user-content-variable-declaration), [console-statement](#user-content-console-statement), [block](#user-content-block), [assignment-statement](#user-content-assignment-statement), [return-statement](#user-content-return-statement), [loop-statement](#user-content-loop-statement), [conditional-statement](#user-content-conditional-statement), [expression-statement](#user-content-expression-statement)_; +Go to: _[loop-statement](#user-content-loop-statement), [conditional-statement](#user-content-conditional-statement), [constant-declaration](#user-content-constant-declaration), [expression-statement](#user-content-expression-statement), [variable-declaration](#user-content-variable-declaration), [assignment-statement](#user-content-assignment-statement), [console-statement](#user-content-console-statement), [return-statement](#user-content-return-statement), [block](#user-content-block)_; @@ -1373,7 +1373,7 @@ variable-declaration = %s"let" identifier-or-identifiers [ ":" type ] "=" expres constant-declaration = %s"const" identifier-or-identifiers [ ":" type ] "=" expression ";" ``` -Go to: _[identifier-or-identifiers](#user-content-identifier-or-identifiers), [type](#user-content-type), [expression](#user-content-expression)_; +Go to: _[type](#user-content-type), [expression](#user-content-expression), [identifier-or-identifiers](#user-content-identifier-or-identifiers)_; @@ -1397,7 +1397,7 @@ Note that blocks are required in all branches, not merely statements. branch = %s"if" expression block ``` -Go to: _[block](#user-content-block), [expression](#user-content-expression)_; +Go to: _[expression](#user-content-expression), [block](#user-content-block)_; @@ -1407,7 +1407,7 @@ conditional-statement = branch / branch %s"else" conditional-statement ``` -Go to: _[block](#user-content-block), [branch](#user-content-branch), [conditional-statement](#user-content-conditional-statement)_; +Go to: _[branch](#user-content-branch), [block](#user-content-block), [conditional-statement](#user-content-conditional-statement)_; A loop statement implicitly defines a loop variable @@ -1419,7 +1419,7 @@ The body is a block. loop-statement = %s"for" identifier %s"in" expression ".." expression block ``` -Go to: _[expression](#user-content-expression), [block](#user-content-block), [identifier](#user-content-identifier)_; +Go to: _[identifier](#user-content-identifier), [expression](#user-content-expression), [block](#user-content-block)_; An assignment statement is straightforward. @@ -1492,7 +1492,7 @@ Go to: _[format-string](#user-content-format-string)_; print-call = print-function print-arguments ``` -Go to: _[print-function](#user-content-print-function), [print-arguments](#user-content-print-arguments)_; +Go to: _[print-arguments](#user-content-print-arguments), [print-function](#user-content-print-function)_; An annotation consists of an annotation name (which starts with `@`) @@ -1505,7 +1505,7 @@ annotation = annotation-name [ "(" identifier *( "," identifier ) ")" ] ``` -Go to: _[identifier](#user-content-identifier), [annotation-name](#user-content-annotation-name)_; +Go to: _[annotation-name](#user-content-annotation-name), [identifier](#user-content-identifier)_; A function declaration defines a function. @@ -1522,7 +1522,7 @@ function-declaration = *annotation %s"function" identifier block ``` -Go to: _[block](#user-content-block), [type](#user-content-type), [identifier](#user-content-identifier), [function-parameters](#user-content-function-parameters)_; +Go to: _[block](#user-content-block), [identifier](#user-content-identifier), [function-parameters](#user-content-function-parameters), [type](#user-content-type)_; @@ -1559,21 +1559,12 @@ Go to: _[type](#user-content-type), [identifier](#user-content-identifier)_; A circuit member variable declaration consists of an identifier and a type. A circuit member function declaration consists of a function declaration. - -```abnf -member-declaration = member-variable-declaration - / member-function-declaration -``` - -Go to: _[member-function-declaration](#user-content-member-function-declaration), [member-variable-declaration](#user-content-member-variable-declaration)_; - - ```abnf -member-variable-declaration = identifier ":" type +member-variable-declaration = identifier ":" type ( "," / ";" ) ``` -Go to: _[identifier](#user-content-identifier), [type](#user-content-type)_; +Go to: _[type](#user-content-type), [identifier](#user-content-identifier)_; @@ -1590,10 +1581,10 @@ as consisting of member variables and functions. ```abnf circuit-declaration = *annotation %s"circuit" identifier - "{" member-declaration *( "," member-declaration ) "}" + "{" *member-variable-declaration *member-function-declaration "}" ``` -Go to: _[identifier](#user-content-identifier), [member-declaration](#user-content-member-declaration)_; +Go to: _[identifier](#user-content-identifier)_; An import declaration consists of the `import` keyword @@ -1622,7 +1613,7 @@ package-path = "*" / "(" package-path *( "," package-path ) [","] ")" ``` -Go to: _[identifier](#user-content-identifier), [package-path](#user-content-package-path), [package-name](#user-content-package-name)_; +Go to: _[package-name](#user-content-package-name), [identifier](#user-content-identifier), [package-path](#user-content-package-path)_; Finally, we define a file as a sequence of zero or more declarations. @@ -1635,7 +1626,7 @@ declaration = import-declaration / constant-declaration ``` -Go to: _[function-declaration](#user-content-function-declaration), [import-declaration](#user-content-import-declaration), [circuit-declaration](#user-content-circuit-declaration), [constant-declaration](#user-content-constant-declaration)_; +Go to: _[circuit-declaration](#user-content-circuit-declaration), [function-declaration](#user-content-function-declaration), [constant-declaration](#user-content-constant-declaration), [import-declaration](#user-content-import-declaration)_; diff --git a/grammar/abnf-grammar.txt b/grammar/abnf-grammar.txt index bf2bbc70bc..6de3dfcb43 100644 --- a/grammar/abnf-grammar.txt +++ b/grammar/abnf-grammar.txt @@ -938,10 +938,7 @@ function-input = [ %s"const" ] identifier ":" type ; A circuit member variable declaration consists of an identifier and a type. ; A circuit member function declaration consists of a function declaration. -member-declaration = member-variable-declaration - / member-function-declaration - -member-variable-declaration = identifier ":" type +member-variable-declaration = identifier ":" type ( "," / ";" ) member-function-declaration = function-declaration @@ -949,7 +946,7 @@ member-function-declaration = function-declaration ; as consisting of member variables and functions. circuit-declaration = *annotation %s"circuit" identifier - "{" member-declaration *( "," member-declaration ) "}" + "{" *member-variable-declaration *member-function-declaration "}" ; An import declaration consists of the `import` keyword ; followed by a package path, which may be one of the following: diff --git a/parser/src/parser/file.rs b/parser/src/parser/file.rs index 8dfdfc132a..58fc165b26 100644 --- a/parser/src/parser/file.rs +++ b/parser/src/parser/file.rs @@ -280,18 +280,59 @@ impl ParserContext { /// Returns a [`CircuitMember`] AST node if the next tokens represent a circuit member variable /// or circuit member function. /// - pub fn parse_circuit_member(&mut self) -> SyntaxResult { - let peeked = &self.peek()?.token; - if peeked == &Token::Function || peeked == &Token::At { + pub fn parse_circuit_declaration(&mut self) -> SyntaxResult> { + let mut members = Vec::new(); + while self.eat(Token::RightCurly).is_none() { + let peeked = &self.peek()?.token; + + if !(peeked == &Token::Function || peeked == &Token::At) { + let variable = self.parse_member_variable_declaration()?; + members.push(variable); + } else { + let function = self.parse_member_function_declaration()?; + members.push(function); + } + } + + Ok(members) + } + + /// + /// Returns a [`CircuitMember`] AST node if the next tokens represent a circuit member variable + /// or circuit member function. + /// + pub fn parse_member_variable_declaration(&mut self) -> SyntaxResult { + let name = self.expect_ident()?; + self.expect(Token::Colon)?; + let type_ = self.parse_type()?.0; + + self.expect_oneof(&[Token::Comma, Token::Semicolon])?; + + Ok(CircuitMember::CircuitVariable(name, type_)) + } + + /// + /// Returns a [`CircuitMember`] AST node if the next tokens represent a circuit member variable + /// or circuit member function. + /// + pub fn parse_member_function_declaration(&mut self) -> SyntaxResult { + let peeked = &self.peek()?; + let peeked_token = &peeked.token; + if peeked_token == &Token::Function || peeked_token == &Token::At { let function = self.parse_function_declaration()?; Ok(CircuitMember::CircuitFunction(function.1)) } else { - // circuit variable - let name = self.expect_ident()?; - self.expect(Token::Colon)?; - let type_ = self.parse_type()?.0; - self.eat(Token::Comma); - Ok(CircuitMember::CircuitVariable(name, type_)) + Err(SyntaxError::unexpected( + peeked_token, + &[ + Token::Import, + Token::Circuit, + Token::Function, + Token::Ident("test".into()), + Token::At, + ], + &peeked.span, + )) } } @@ -303,11 +344,8 @@ impl ParserContext { self.expect(Token::Circuit)?; let name = self.expect_ident()?; self.expect(Token::LeftCurly)?; - let mut members = Vec::new(); - while self.eat(Token::RightCurly).is_none() { - let member = self.parse_circuit_member()?; - members.push(member); - } + let members = self.parse_circuit_declaration()?; + Ok((name.clone(), Circuit { circuit_name: name, members, From 282cbb88401fc2b49b82c8f7c46b73f6ac8371cc Mon Sep 17 00:00:00 2001 From: gluax Date: Thu, 29 Apr 2021 14:10:22 -0400 Subject: [PATCH 02/24] optional comma at end of member variables --- grammar/README.md | 60 +++++++++++++++++++-------------------- grammar/abnf-grammar.txt | 2 +- parser/src/parser/file.rs | 39 ++++++++++++++++--------- 3 files changed, 56 insertions(+), 45 deletions(-) diff --git a/grammar/README.md b/grammar/README.md index e2d6ee438c..e7adadb0b2 100644 --- a/grammar/README.md +++ b/grammar/README.md @@ -476,7 +476,7 @@ Line terminators form whitespace, along with spaces and horizontal tabs. whitespace = space / horizontal-tab / newline ``` -Go to: _[horizontal-tab](#user-content-horizontal-tab), [space](#user-content-space), [newline](#user-content-newline)_; +Go to: _[space](#user-content-space), [horizontal-tab](#user-content-horizontal-tab), [newline](#user-content-newline)_; There are two kinds of comments in Leo, as in other languages. @@ -494,7 +494,7 @@ the ones used in the Java language reference. comment = block-comment / end-of-line-comment ``` -Go to: _[block-comment](#user-content-block-comment), [end-of-line-comment](#user-content-end-of-line-comment)_; +Go to: _[end-of-line-comment](#user-content-end-of-line-comment), [block-comment](#user-content-block-comment)_; @@ -511,7 +511,7 @@ rest-of-block-comment = "*" rest-of-block-comment-after-star / not-star rest-of-block-comment ``` -Go to: _[rest-of-block-comment](#user-content-rest-of-block-comment), [not-star](#user-content-not-star), [rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star)_; +Go to: _[rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star), [rest-of-block-comment](#user-content-rest-of-block-comment), [not-star](#user-content-not-star)_; @@ -521,7 +521,7 @@ rest-of-block-comment-after-star = "/" / not-star-or-slash rest-of-block-comment ``` -Go to: _[rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star), [rest-of-block-comment](#user-content-rest-of-block-comment), [not-star-or-slash](#user-content-not-star-or-slash)_; +Go to: _[not-star-or-slash](#user-content-not-star-or-slash), [rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star), [rest-of-block-comment](#user-content-rest-of-block-comment)_; @@ -639,7 +639,7 @@ format-string-element = not-double-quote-or-open-brace / format-string-container ``` -Go to: _[not-double-quote-or-open-brace](#user-content-not-double-quote-or-open-brace), [not-double-quote-or-close-brace](#user-content-not-double-quote-or-close-brace), [format-string-container](#user-content-format-string-container)_; +Go to: _[format-string-container](#user-content-format-string-container), [not-double-quote-or-open-brace](#user-content-not-double-quote-or-open-brace), [not-double-quote-or-close-brace](#user-content-not-double-quote-or-close-brace)_; @@ -764,7 +764,7 @@ atomic-literal = untyped-literal / address-literal ``` -Go to: _[product-group-literal](#user-content-product-group-literal), [address-literal](#user-content-address-literal), [boolean-literal](#user-content-boolean-literal), [unsigned-literal](#user-content-unsigned-literal), [field-literal](#user-content-field-literal), [untyped-literal](#user-content-untyped-literal), [signed-literal](#user-content-signed-literal)_; +Go to: _[signed-literal](#user-content-signed-literal), [untyped-literal](#user-content-untyped-literal), [boolean-literal](#user-content-boolean-literal), [field-literal](#user-content-field-literal), [unsigned-literal](#user-content-unsigned-literal), [product-group-literal](#user-content-product-group-literal), [address-literal](#user-content-address-literal)_; After defining the (mostly) alphanumeric tokens above, @@ -809,7 +809,7 @@ token = keyword / symbol ``` -Go to: _[annotation-name](#user-content-annotation-name), [symbol](#user-content-symbol), [atomic-literal](#user-content-atomic-literal), [identifier](#user-content-identifier), [package-name](#user-content-package-name), [keyword](#user-content-keyword), [format-string](#user-content-format-string)_; +Go to: _[keyword](#user-content-keyword), [format-string](#user-content-format-string), [annotation-name](#user-content-annotation-name), [atomic-literal](#user-content-atomic-literal), [identifier](#user-content-identifier), [package-name](#user-content-package-name), [symbol](#user-content-symbol)_; @@ -866,7 +866,7 @@ group-type = %s"group" arithmetic-type = integer-type / field-type / group-type ``` -Go to: _[group-type](#user-content-group-type), [integer-type](#user-content-integer-type), [field-type](#user-content-field-type)_; +Go to: _[field-type](#user-content-field-type), [integer-type](#user-content-integer-type), [group-type](#user-content-group-type)_; The arithmetic types, along with the boolean and address types, @@ -887,7 +887,7 @@ address-type = %s"address" scalar-type = boolean-type / arithmetic-type / address-type ``` -Go to: _[arithmetic-type](#user-content-arithmetic-type), [address-type](#user-content-address-type), [boolean-type](#user-content-boolean-type)_; +Go to: _[boolean-type](#user-content-boolean-type), [address-type](#user-content-address-type), [arithmetic-type](#user-content-arithmetic-type)_; Circuit types are denoted by identifiers and the keyword `Self`. @@ -927,7 +927,7 @@ or a tuple of one or more dimensions. array-type = "[" type ";" array-dimensions "]" ``` -Go to: _[type](#user-content-type), [array-dimensions](#user-content-array-dimensions)_; +Go to: _[array-dimensions](#user-content-array-dimensions), [type](#user-content-type)_; @@ -948,7 +948,7 @@ i.e. types whose values contain (sub-)values aggregate-type = tuple-type / array-type / circuit-type ``` -Go to: _[array-type](#user-content-array-type), [circuit-type](#user-content-circuit-type), [tuple-type](#user-content-tuple-type)_; +Go to: _[circuit-type](#user-content-circuit-type), [tuple-type](#user-content-tuple-type), [array-type](#user-content-array-type)_; Scalar and aggregate types form all the types. @@ -994,7 +994,7 @@ A literal is either an atomic one or an affine group literal. literal = atomic-literal / affine-group-literal ``` -Go to: _[affine-group-literal](#user-content-affine-group-literal), [atomic-literal](#user-content-atomic-literal)_; +Go to: _[atomic-literal](#user-content-atomic-literal), [affine-group-literal](#user-content-affine-group-literal)_; The following rule is not directly referenced in the rules for expressions @@ -1007,7 +1007,7 @@ a group literal is either a product group literal or an affine group literal. group-literal = product-group-literal / affine-group-literal ``` -Go to: _[affine-group-literal](#user-content-affine-group-literal), [product-group-literal](#user-content-product-group-literal)_; +Go to: _[product-group-literal](#user-content-product-group-literal), [affine-group-literal](#user-content-affine-group-literal)_; As often done in grammatical language syntax specifications, @@ -1036,7 +1036,7 @@ primary-expression = identifier / circuit-expression ``` -Go to: _[array-expression](#user-content-array-expression), [tuple-expression](#user-content-tuple-expression), [circuit-expression](#user-content-circuit-expression), [identifier](#user-content-identifier), [literal](#user-content-literal), [expression](#user-content-expression)_; +Go to: _[identifier](#user-content-identifier), [expression](#user-content-expression), [tuple-expression](#user-content-tuple-expression), [literal](#user-content-literal), [array-expression](#user-content-array-expression), [circuit-expression](#user-content-circuit-expression)_; Tuple expressions construct tuples. @@ -1089,7 +1089,7 @@ Go to: _[expression](#user-content-expression)_; array-repeat-construction = "[" expression ";" array-dimensions "]" ``` -Go to: _[array-dimensions](#user-content-array-dimensions), [expression](#user-content-expression)_; +Go to: _[expression](#user-content-expression), [array-dimensions](#user-content-array-dimensions)_; @@ -1125,7 +1125,7 @@ circuit-construction = circuit-type "{" "}" ``` -Go to: _[circuit-inline-element](#user-content-circuit-inline-element), [circuit-type](#user-content-circuit-type)_; +Go to: _[circuit-type](#user-content-circuit-type), [circuit-inline-element](#user-content-circuit-inline-element)_; @@ -1184,7 +1184,7 @@ postfix-expression = primary-expression / postfix-expression "[" [expression] ".." [expression] "]" ``` -Go to: _[natural](#user-content-natural), [identifier](#user-content-identifier), [postfix-expression](#user-content-postfix-expression), [circuit-type](#user-content-circuit-type), [function-arguments](#user-content-function-arguments), [primary-expression](#user-content-primary-expression), [expression](#user-content-expression)_; +Go to: _[function-arguments](#user-content-function-arguments), [circuit-type](#user-content-circuit-type), [postfix-expression](#user-content-postfix-expression), [primary-expression](#user-content-primary-expression), [identifier](#user-content-identifier), [natural](#user-content-natural), [expression](#user-content-expression)_; Unary operators have the highest operator precedence. @@ -1236,7 +1236,7 @@ additive-expression = multiplicative-expression / additive-expression "-" multiplicative-expression ``` -Go to: _[multiplicative-expression](#user-content-multiplicative-expression), [additive-expression](#user-content-additive-expression)_; +Go to: _[additive-expression](#user-content-additive-expression), [multiplicative-expression](#user-content-multiplicative-expression)_; Next in the precedence order are ordering relations. @@ -1299,7 +1299,7 @@ conditional-expression = disjunctive-expression ":" conditional-expression ``` -Go to: _[disjunctive-expression](#user-content-disjunctive-expression), [conditional-expression](#user-content-conditional-expression), [expression](#user-content-expression)_; +Go to: _[expression](#user-content-expression), [disjunctive-expression](#user-content-disjunctive-expression), [conditional-expression](#user-content-conditional-expression)_; Those above are all the expressions. @@ -1332,7 +1332,7 @@ statement = expression-statement / block ``` -Go to: _[loop-statement](#user-content-loop-statement), [conditional-statement](#user-content-conditional-statement), [constant-declaration](#user-content-constant-declaration), [expression-statement](#user-content-expression-statement), [variable-declaration](#user-content-variable-declaration), [assignment-statement](#user-content-assignment-statement), [console-statement](#user-content-console-statement), [return-statement](#user-content-return-statement), [block](#user-content-block)_; +Go to: _[return-statement](#user-content-return-statement), [variable-declaration](#user-content-variable-declaration), [constant-declaration](#user-content-constant-declaration), [expression-statement](#user-content-expression-statement), [conditional-statement](#user-content-conditional-statement), [console-statement](#user-content-console-statement), [block](#user-content-block), [assignment-statement](#user-content-assignment-statement), [loop-statement](#user-content-loop-statement)_; @@ -1373,7 +1373,7 @@ variable-declaration = %s"let" identifier-or-identifiers [ ":" type ] "=" expres constant-declaration = %s"const" identifier-or-identifiers [ ":" type ] "=" expression ";" ``` -Go to: _[type](#user-content-type), [expression](#user-content-expression), [identifier-or-identifiers](#user-content-identifier-or-identifiers)_; +Go to: _[identifier-or-identifiers](#user-content-identifier-or-identifiers), [type](#user-content-type), [expression](#user-content-expression)_; @@ -1407,7 +1407,7 @@ conditional-statement = branch / branch %s"else" conditional-statement ``` -Go to: _[branch](#user-content-branch), [block](#user-content-block), [conditional-statement](#user-content-conditional-statement)_; +Go to: _[branch](#user-content-branch), [conditional-statement](#user-content-conditional-statement), [block](#user-content-block)_; A loop statement implicitly defines a loop variable @@ -1463,7 +1463,7 @@ console-call = assert-call / print-call ``` -Go to: _[assert-call](#user-content-assert-call), [print-call](#user-content-print-call)_; +Go to: _[print-call](#user-content-print-call), [assert-call](#user-content-assert-call)_; @@ -1522,7 +1522,7 @@ function-declaration = *annotation %s"function" identifier block ``` -Go to: _[block](#user-content-block), [identifier](#user-content-identifier), [function-parameters](#user-content-function-parameters), [type](#user-content-type)_; +Go to: _[identifier](#user-content-identifier), [block](#user-content-block), [type](#user-content-type), [function-parameters](#user-content-function-parameters)_; @@ -1532,7 +1532,7 @@ function-parameters = self-parameter / function-inputs ``` -Go to: _[function-inputs](#user-content-function-inputs), [self-parameter](#user-content-self-parameter)_; +Go to: _[self-parameter](#user-content-self-parameter), [function-inputs](#user-content-function-inputs)_; @@ -1553,7 +1553,7 @@ Go to: _[function-input](#user-content-function-input)_; function-input = [ %s"const" ] identifier ":" type ``` -Go to: _[type](#user-content-type), [identifier](#user-content-identifier)_; +Go to: _[identifier](#user-content-identifier), [type](#user-content-type)_; A circuit member variable declaration consists of an identifier and a type. @@ -1561,10 +1561,10 @@ A circuit member function declaration consists of a function declaration. ```abnf -member-variable-declaration = identifier ":" type ( "," / ";" ) +member-variable-declaration = *(identifier ":" type ( "," / ";" )) identifier ":" type ( [ "," ] / ";" ) ``` -Go to: _[type](#user-content-type), [identifier](#user-content-identifier)_; +Go to: _[identifier](#user-content-identifier), [type](#user-content-type)_; @@ -1613,7 +1613,7 @@ package-path = "*" / "(" package-path *( "," package-path ) [","] ")" ``` -Go to: _[package-name](#user-content-package-name), [identifier](#user-content-identifier), [package-path](#user-content-package-path)_; +Go to: _[identifier](#user-content-identifier), [package-path](#user-content-package-path), [package-name](#user-content-package-name)_; Finally, we define a file as a sequence of zero or more declarations. @@ -1626,7 +1626,7 @@ declaration = import-declaration / constant-declaration ``` -Go to: _[circuit-declaration](#user-content-circuit-declaration), [function-declaration](#user-content-function-declaration), [constant-declaration](#user-content-constant-declaration), [import-declaration](#user-content-import-declaration)_; +Go to: _[import-declaration](#user-content-import-declaration), [constant-declaration](#user-content-constant-declaration), [function-declaration](#user-content-function-declaration), [circuit-declaration](#user-content-circuit-declaration)_; diff --git a/grammar/abnf-grammar.txt b/grammar/abnf-grammar.txt index 6de3dfcb43..d62c2900fd 100644 --- a/grammar/abnf-grammar.txt +++ b/grammar/abnf-grammar.txt @@ -938,7 +938,7 @@ function-input = [ %s"const" ] identifier ":" type ; A circuit member variable declaration consists of an identifier and a type. ; A circuit member function declaration consists of a function declaration. -member-variable-declaration = identifier ":" type ( "," / ";" ) +member-variable-declaration = *(identifier ":" type ( "," / ";" )) identifier ":" type ( [ "," ] / ";" ) member-function-declaration = function-declaration diff --git a/parser/src/parser/file.rs b/parser/src/parser/file.rs index 58fc165b26..586d94a6bb 100644 --- a/parser/src/parser/file.rs +++ b/parser/src/parser/file.rs @@ -282,12 +282,24 @@ impl ParserContext { /// pub fn parse_circuit_declaration(&mut self) -> SyntaxResult> { let mut members = Vec::new(); + let peeked = &self.peek()?.token; + let mut last_variable = peeked == &Token::Function || peeked == &Token::At; while self.eat(Token::RightCurly).is_none() { - let peeked = &self.peek()?.token; - - if !(peeked == &Token::Function || peeked == &Token::At) { - let variable = self.parse_member_variable_declaration()?; + if !last_variable { + let (variable, last) = self.parse_member_variable_declaration()?; members.push(variable); + + if !last { + self.expect_oneof(&[Token::Comma, Token::Semicolon])?; + } else { + last_variable = last; + let peeked = &self.peek()?.token; + if peeked == &Token::Semicolon { + self.expect(Token::Semicolon)?; + } else { + self.eat(Token::Comma); + } + } } else { let function = self.parse_member_function_declaration()?; members.push(function); @@ -301,14 +313,19 @@ impl ParserContext { /// Returns a [`CircuitMember`] AST node if the next tokens represent a circuit member variable /// or circuit member function. /// - pub fn parse_member_variable_declaration(&mut self) -> SyntaxResult { + pub fn parse_member_variable_declaration(&mut self) -> SyntaxResult<(CircuitMember, bool)> { let name = self.expect_ident()?; self.expect(Token::Colon)?; let type_ = self.parse_type()?.0; - self.expect_oneof(&[Token::Comma, Token::Semicolon])?; + let peeked = &self.peek()?; + let peeked_token = &peeked.token; - Ok(CircuitMember::CircuitVariable(name, type_)) + if peeked_token == &Token::Function || peeked_token == &Token::At || peeked_token == &Token::RightCurly { + return Ok((CircuitMember::CircuitVariable(name, type_), true)); + } + + Ok((CircuitMember::CircuitVariable(name, type_), false)) } /// @@ -324,13 +341,7 @@ impl ParserContext { } else { Err(SyntaxError::unexpected( peeked_token, - &[ - Token::Import, - Token::Circuit, - Token::Function, - Token::Ident("test".into()), - Token::At, - ], + &[Token::Function, Token::At], &peeked.span, )) } From e0cf9882614aef1ba346a24ed632998380353d02 Mon Sep 17 00:00:00 2001 From: gluax Date: Thu, 29 Apr 2021 15:22:17 -0400 Subject: [PATCH 03/24] hacky, but optional comma only allowed on last member variable --- asg/tests/fail/circuits/inline_fail.leo | 2 +- .../fail/circuits/member_variable_fail.leo | 2 +- asg/tests/fail/circuits/mut_function_fail.leo | 2 +- .../fail/circuits/mut_self_function_fail.leo | 2 +- .../mut_self_static_function_fail.leo | 2 +- .../fail/circuits/mut_self_variable_fail.leo | 2 +- asg/tests/fail/circuits/mut_variable_fail.leo | 2 +- .../fail/circuits/self_member_invalid.leo | 2 +- asg/tests/fail/mutability/circuit.leo | 2 +- ...define_circuit_inside_circuit_function.leo | 2 +- asg/tests/pass/circuits/inline.leo | 2 +- .../pass/circuits/member_function_nested.leo | 2 +- asg/tests/pass/circuits/member_variable.leo | 2 +- .../circuits/member_variable_and_function.leo | 2 +- asg/tests/pass/circuits/mut_self_variable.leo | 2 +- .../mut_self_variable_conditional.leo | 2 +- asg/tests/pass/circuits/mut_variable.leo | 2 +- asg/tests/pass/circuits/pedersen_mock.leo | 2 +- asg/tests/pass/circuits/self_member.leo | 2 +- asg/tests/pass/form_ast.rs | 4 +- .../pass/import/imports/bar/src/bat/bat.leo | 2 +- asg/tests/pass/import/imports/bar/src/baz.leo | 4 +- asg/tests/pass/import/imports/bar/src/lib.leo | 2 +- asg/tests/pass/import/imports/car/src/lib.leo | 2 +- asg/tests/pass/import/src/test-import.leo | 4 +- asg/tests/pass/mutability/circuit_mut.leo | 2 +- .../pass/mutability/circuit_variable_mut.leo | 2 +- .../big_self_in_circuit_replacement.leo | 2 +- .../big_self_outside_circuit_fail.leo | 2 +- .../canonicalization/compound_assignment.leo | 4 +- .../tests/circuits/const_self_variable.leo | 2 +- .../circuits/const_self_variable_fail.leo | 2 +- ...define_circuit_inside_circuit_function.leo | 2 +- .../tests/circuits/duplicate_name_context.leo | 2 +- compiler/tests/circuits/inline.leo | 2 +- compiler/tests/circuits/inline_fail.leo | 2 +- .../tests/circuits/inline_member_fail.leo | 2 +- .../tests/circuits/inline_member_pass.leo | 2 +- compiler/tests/circuits/member_function.leo | 2 +- .../tests/circuits/member_function_nested.leo | 2 +- compiler/tests/circuits/member_variable.leo | 2 +- .../circuits/member_variable_and_function.leo | 2 +- .../tests/circuits/member_variable_fail.leo | 2 +- compiler/tests/circuits/mut_function_fail.leo | 2 +- .../tests/circuits/mut_self_function_fail.leo | 2 +- .../mut_self_static_function_fail.leo | 2 +- compiler/tests/circuits/mut_self_variable.leo | 2 +- .../circuits/mut_self_variable_branch.leo | 2 +- .../mut_self_variable_conditional.leo | 2 +- .../tests/circuits/mut_self_variable_fail.leo | 2 +- compiler/tests/circuits/mut_variable.leo | 2 +- compiler/tests/circuits/mut_variable_fail.leo | 2 +- .../mutable_call_immutable_context.leo | 2 +- compiler/tests/circuits/pedersen_mock.leo | 2 +- compiler/tests/circuits/self_member.leo | 2 +- .../tests/circuits/self_member_invalid.leo | 2 +- .../global_consts/global_const_types.leo | 4 +- .../tests/import/imports/bar/src/bat/bat.leo | 2 +- compiler/tests/import/imports/bar/src/baz.leo | 4 +- compiler/tests/import/imports/bar/src/lib.leo | 2 +- compiler/tests/import/imports/car/src/lib.leo | 2 +- compiler/tests/import/src/test-import.leo | 4 +- compiler/tests/mutability/circuit.leo | 2 +- compiler/tests/mutability/circuit_mut.leo | 2 +- .../tests/mutability/circuit_variable_mut.leo | 2 +- examples/pedersen-hash/src/main.leo | 2 +- examples/silly-sudoku/src/lib.leo | 2 +- grammar/README.md | 74 +-- grammar/abnf-grammar.txt | 2 +- parser/benches/big_circuit.leo | 512 +++++++++--------- parser/src/parser/context.rs | 7 + parser/src/parser/file.rs | 17 +- .../parser/parser/circuits/big_self.leo.out | 1 + .../parser/parser/circuits/empty.leo.out | 1 + .../circuits/field_and_functions.leo.out | 3 +- .../parser/parser/circuits/fields.leo.out | 5 +- .../parser/circuits/fields_fail.leo.out | 5 + .../parser/parser/circuits/functions.leo.out | 1 + .../parser/parser/circuits/mut_self.leo.out | 1 + .../parser/parser/circuits/self.leo.out | 1 + .../parser/parser/functions/annotated.leo.out | 1 + .../parser/functions/annotated_param.leo.out | 1 + .../parser/functions/annotated_twice.leo.out | 1 + .../parser/functions/const_param.leo.out | 1 + .../parser/functions/const_self_bad.leo.out | 1 + .../parser/parser/functions/empty.leo.out | 1 + .../parser/parser/functions/empty2.leo.out | 1 + .../parser/functions/param_array.leo.out | 1 + .../parser/functions/param_circuit.leo.out | 1 + .../parser/functions/param_tuple.leo.out | 1 + .../parser/parser/functions/params.leo.out | 1 + .../parser/functions/params_return.leo.out | 1 + .../parser/parser/functions/return.leo.out | 1 + .../parser/functions/return_tuple.leo.out | 1 + .../parser/parser/import/alias.leo.out | 1 + .../parser/parser/import/basic.leo.out | 1 + .../parser/parser/import/many_import.leo.out | 1 + .../parser/import/many_import_star.leo.out | 1 + .../parser/parser/import/names.leo.out | 1 + .../parser/import/names_underscore.leo.out | 1 + .../parser/parser/import/star.leo.out | 1 + tests/parser/circuits/field_and_functions.leo | 2 +- tests/parser/circuits/fields.leo | 4 +- tests/parser/circuits/fields_fail.leo | 9 + 104 files changed, 432 insertions(+), 382 deletions(-) create mode 100644 tests/expectations/parser/parser/circuits/fields_fail.leo.out create mode 100644 tests/parser/circuits/fields_fail.leo diff --git a/asg/tests/fail/circuits/inline_fail.leo b/asg/tests/fail/circuits/inline_fail.leo index 01597005fb..302c84298a 100644 --- a/asg/tests/fail/circuits/inline_fail.leo +++ b/asg/tests/fail/circuits/inline_fail.leo @@ -1,5 +1,5 @@ circuit Foo { - x: u32 + x: u32; } function main() { diff --git a/asg/tests/fail/circuits/member_variable_fail.leo b/asg/tests/fail/circuits/member_variable_fail.leo index fdf42068d5..a0a9823486 100644 --- a/asg/tests/fail/circuits/member_variable_fail.leo +++ b/asg/tests/fail/circuits/member_variable_fail.leo @@ -1,5 +1,5 @@ circuit Foo { - x: u32 + x: u32; } function main() { diff --git a/asg/tests/fail/circuits/mut_function_fail.leo b/asg/tests/fail/circuits/mut_function_fail.leo index 1b87e2bfb1..d66edac76b 100644 --- a/asg/tests/fail/circuits/mut_function_fail.leo +++ b/asg/tests/fail/circuits/mut_function_fail.leo @@ -1,5 +1,5 @@ circuit Foo { - a: u8, + a: u8; function bar() {} } diff --git a/asg/tests/fail/circuits/mut_self_function_fail.leo b/asg/tests/fail/circuits/mut_self_function_fail.leo index 58c8088ba1..dde5133a00 100644 --- a/asg/tests/fail/circuits/mut_self_function_fail.leo +++ b/asg/tests/fail/circuits/mut_self_function_fail.leo @@ -1,5 +1,5 @@ circuit Foo { - a: u8, + a: u8; function bar() {} diff --git a/asg/tests/fail/circuits/mut_self_static_function_fail.leo b/asg/tests/fail/circuits/mut_self_static_function_fail.leo index 58c8088ba1..dde5133a00 100644 --- a/asg/tests/fail/circuits/mut_self_static_function_fail.leo +++ b/asg/tests/fail/circuits/mut_self_static_function_fail.leo @@ -1,5 +1,5 @@ circuit Foo { - a: u8, + a: u8; function bar() {} diff --git a/asg/tests/fail/circuits/mut_self_variable_fail.leo b/asg/tests/fail/circuits/mut_self_variable_fail.leo index 4db62a4d3e..50edbc11f1 100644 --- a/asg/tests/fail/circuits/mut_self_variable_fail.leo +++ b/asg/tests/fail/circuits/mut_self_variable_fail.leo @@ -1,5 +1,5 @@ circuit Foo { - a: u8, + a: u8; function set_a(self, new: u8) { self.a = new; diff --git a/asg/tests/fail/circuits/mut_variable_fail.leo b/asg/tests/fail/circuits/mut_variable_fail.leo index 7ba4193074..4b741ed07f 100644 --- a/asg/tests/fail/circuits/mut_variable_fail.leo +++ b/asg/tests/fail/circuits/mut_variable_fail.leo @@ -1,5 +1,5 @@ circuit Foo { - a: u8, + a: u8; } function main() { diff --git a/asg/tests/fail/circuits/self_member_invalid.leo b/asg/tests/fail/circuits/self_member_invalid.leo index 7283b3260a..51ba9b53df 100644 --- a/asg/tests/fail/circuits/self_member_invalid.leo +++ b/asg/tests/fail/circuits/self_member_invalid.leo @@ -1,5 +1,5 @@ circuit Foo { - f: u32, + f: u32; function bar() -> u32 { return f; diff --git a/asg/tests/fail/mutability/circuit.leo b/asg/tests/fail/mutability/circuit.leo index 508595ef16..29f2096a03 100644 --- a/asg/tests/fail/mutability/circuit.leo +++ b/asg/tests/fail/mutability/circuit.leo @@ -1,6 +1,6 @@ // Circuits are immutable by default. circuit Foo { - x: u32 + x: u32; } function main() { diff --git a/asg/tests/pass/circuits/define_circuit_inside_circuit_function.leo b/asg/tests/pass/circuits/define_circuit_inside_circuit_function.leo index cedabf2185..a15259b1d4 100644 --- a/asg/tests/pass/circuits/define_circuit_inside_circuit_function.leo +++ b/asg/tests/pass/circuits/define_circuit_inside_circuit_function.leo @@ -1,5 +1,5 @@ circuit Foo { - a: u32, + a: u32; } circuit Bar { diff --git a/asg/tests/pass/circuits/inline.leo b/asg/tests/pass/circuits/inline.leo index 9ba06f4191..19f3d5cfb2 100644 --- a/asg/tests/pass/circuits/inline.leo +++ b/asg/tests/pass/circuits/inline.leo @@ -1,5 +1,5 @@ circuit Foo { - x: u32 + x: u32; } function main() { diff --git a/asg/tests/pass/circuits/member_function_nested.leo b/asg/tests/pass/circuits/member_function_nested.leo index b8bf172947..77b0d83bb9 100644 --- a/asg/tests/pass/circuits/member_function_nested.leo +++ b/asg/tests/pass/circuits/member_function_nested.leo @@ -1,5 +1,5 @@ circuit Foo { - x: u32, + x: u32; function add_x(self, y: u32) -> u32 { return self.x + y; diff --git a/asg/tests/pass/circuits/member_variable.leo b/asg/tests/pass/circuits/member_variable.leo index a3f3fbe7e6..c1f5812dce 100644 --- a/asg/tests/pass/circuits/member_variable.leo +++ b/asg/tests/pass/circuits/member_variable.leo @@ -1,5 +1,5 @@ circuit Foo { - x: u32, + x: u32; } function main() { diff --git a/asg/tests/pass/circuits/member_variable_and_function.leo b/asg/tests/pass/circuits/member_variable_and_function.leo index f90cdca072..d579f3fbf5 100644 --- a/asg/tests/pass/circuits/member_variable_and_function.leo +++ b/asg/tests/pass/circuits/member_variable_and_function.leo @@ -1,5 +1,5 @@ circuit Foo { - foo: u32, + foo: u32; function bar() -> u32 { return 1u32; diff --git a/asg/tests/pass/circuits/mut_self_variable.leo b/asg/tests/pass/circuits/mut_self_variable.leo index 92bcca0050..cfe7e10ef5 100644 --- a/asg/tests/pass/circuits/mut_self_variable.leo +++ b/asg/tests/pass/circuits/mut_self_variable.leo @@ -1,5 +1,5 @@ circuit Foo { - a: u8, + a: u8; function set_a(mut self, new: u8) { self.a = new; diff --git a/asg/tests/pass/circuits/mut_self_variable_conditional.leo b/asg/tests/pass/circuits/mut_self_variable_conditional.leo index 61a5e354dc..fec92fef93 100644 --- a/asg/tests/pass/circuits/mut_self_variable_conditional.leo +++ b/asg/tests/pass/circuits/mut_self_variable_conditional.leo @@ -5,7 +5,7 @@ function main() { } circuit Foo { - a: u32 + a: u32; function bar(mut self) { if true { diff --git a/asg/tests/pass/circuits/mut_variable.leo b/asg/tests/pass/circuits/mut_variable.leo index 151babb1cd..a8cb60d989 100644 --- a/asg/tests/pass/circuits/mut_variable.leo +++ b/asg/tests/pass/circuits/mut_variable.leo @@ -1,5 +1,5 @@ circuit Foo { - a: u8, + a: u8; } function main() { diff --git a/asg/tests/pass/circuits/pedersen_mock.leo b/asg/tests/pass/circuits/pedersen_mock.leo index 0fc6752f2f..fb154aa7c1 100644 --- a/asg/tests/pass/circuits/pedersen_mock.leo +++ b/asg/tests/pass/circuits/pedersen_mock.leo @@ -1,5 +1,5 @@ circuit PedersenHash { - parameters: [u32; 512] + parameters: [u32; 512]; function new(parameters: [u32; 512]) -> Self { return Self { parameters: parameters }; diff --git a/asg/tests/pass/circuits/self_member.leo b/asg/tests/pass/circuits/self_member.leo index 237baac9de..a21fbfc5cf 100644 --- a/asg/tests/pass/circuits/self_member.leo +++ b/asg/tests/pass/circuits/self_member.leo @@ -1,5 +1,5 @@ circuit Foo { - f: u32, + f: u32; function bar(self) -> u32 { return self.f; diff --git a/asg/tests/pass/form_ast.rs b/asg/tests/pass/form_ast.rs index dfb72639b9..6c4a28a645 100644 --- a/asg/tests/pass/form_ast.rs +++ b/asg/tests/pass/form_ast.rs @@ -58,8 +58,8 @@ fn test_imports() { let mut imports = crate::mocked_resolver(&context); let test_import = r#" circuit Point { - x: u32 - y: u32 + x: u32; + y: u32; } function foo() -> u32 { diff --git a/asg/tests/pass/import/imports/bar/src/bat/bat.leo b/asg/tests/pass/import/imports/bar/src/bat/bat.leo index a7d2fc83d4..f76edfe54e 100755 --- a/asg/tests/pass/import/imports/bar/src/bat/bat.leo +++ b/asg/tests/pass/import/imports/bar/src/bat/bat.leo @@ -1,3 +1,3 @@ circuit Bat { - t: u32 + t: u32; } \ No newline at end of file diff --git a/asg/tests/pass/import/imports/bar/src/baz.leo b/asg/tests/pass/import/imports/bar/src/baz.leo index 1bb268a84c..74fa3f281f 100755 --- a/asg/tests/pass/import/imports/bar/src/baz.leo +++ b/asg/tests/pass/import/imports/bar/src/baz.leo @@ -1,7 +1,7 @@ circuit Baz { - z: u32 + z: u32; } circuit Bazzar { - a: u32 + a: u32; } \ No newline at end of file diff --git a/asg/tests/pass/import/imports/bar/src/lib.leo b/asg/tests/pass/import/imports/bar/src/lib.leo index c169f5935e..845b6e5fd3 100755 --- a/asg/tests/pass/import/imports/bar/src/lib.leo +++ b/asg/tests/pass/import/imports/bar/src/lib.leo @@ -1,3 +1,3 @@ circuit Bar { - r: u32 + r: u32; } \ No newline at end of file diff --git a/asg/tests/pass/import/imports/car/src/lib.leo b/asg/tests/pass/import/imports/car/src/lib.leo index b1e037fd38..58a10e4067 100755 --- a/asg/tests/pass/import/imports/car/src/lib.leo +++ b/asg/tests/pass/import/imports/car/src/lib.leo @@ -1,3 +1,3 @@ circuit Car { - c: u32 + c: u32; } \ No newline at end of file diff --git a/asg/tests/pass/import/src/test-import.leo b/asg/tests/pass/import/src/test-import.leo index 9a57d433f4..e75fdd2fb1 100644 --- a/asg/tests/pass/import/src/test-import.leo +++ b/asg/tests/pass/import/src/test-import.leo @@ -1,6 +1,6 @@ circuit Point { - x: u32 - y: u32 + x: u32; + y: u32; } function foo() -> u32 { diff --git a/asg/tests/pass/mutability/circuit_mut.leo b/asg/tests/pass/mutability/circuit_mut.leo index f7067db11e..4ce2ea7c54 100644 --- a/asg/tests/pass/mutability/circuit_mut.leo +++ b/asg/tests/pass/mutability/circuit_mut.leo @@ -1,6 +1,6 @@ // Adding the `mut` keyword makes a circuit variable mutable. circuit Foo { - x: u32 + x: u32; } function main() { diff --git a/asg/tests/pass/mutability/circuit_variable_mut.leo b/asg/tests/pass/mutability/circuit_variable_mut.leo index f7067db11e..4ce2ea7c54 100644 --- a/asg/tests/pass/mutability/circuit_variable_mut.leo +++ b/asg/tests/pass/mutability/circuit_variable_mut.leo @@ -1,6 +1,6 @@ // Adding the `mut` keyword makes a circuit variable mutable. circuit Foo { - x: u32 + x: u32; } function main() { diff --git a/compiler/tests/canonicalization/big_self_in_circuit_replacement.leo b/compiler/tests/canonicalization/big_self_in_circuit_replacement.leo index 4081e46cbf..dfbefd0022 100644 --- a/compiler/tests/canonicalization/big_self_in_circuit_replacement.leo +++ b/compiler/tests/canonicalization/big_self_in_circuit_replacement.leo @@ -1,5 +1,5 @@ circuit Foo { - x: u32 + x: u32; function new() -> Self { let new: Self = Self { diff --git a/compiler/tests/canonicalization/big_self_outside_circuit_fail.leo b/compiler/tests/canonicalization/big_self_outside_circuit_fail.leo index 6f5100adde..e070486a4b 100644 --- a/compiler/tests/canonicalization/big_self_outside_circuit_fail.leo +++ b/compiler/tests/canonicalization/big_self_outside_circuit_fail.leo @@ -1,5 +1,5 @@ circuit Foo { - x: u32 + x: u32; function new() -> Self { let new: Self = Self { diff --git a/compiler/tests/canonicalization/compound_assignment.leo b/compiler/tests/canonicalization/compound_assignment.leo index 1a6f2171fe..cd1e7f030a 100644 --- a/compiler/tests/canonicalization/compound_assignment.leo +++ b/compiler/tests/canonicalization/compound_assignment.leo @@ -1,6 +1,6 @@ circuit Foo { - f: u8, - y: (u8, u8), + f: u8; + y: (u8, u8); function z (mut self) -> u16 { self.y.0 += 1u8; diff --git a/compiler/tests/circuits/const_self_variable.leo b/compiler/tests/circuits/const_self_variable.leo index 8ba32ba0df..f9794c72cc 100644 --- a/compiler/tests/circuits/const_self_variable.leo +++ b/compiler/tests/circuits/const_self_variable.leo @@ -1,5 +1,5 @@ circuit Foo { - a: u8, + a: u8; function use_a(const self) -> u8 { return self.a + 1; diff --git a/compiler/tests/circuits/const_self_variable_fail.leo b/compiler/tests/circuits/const_self_variable_fail.leo index fca9620946..8dda67dd1f 100644 --- a/compiler/tests/circuits/const_self_variable_fail.leo +++ b/compiler/tests/circuits/const_self_variable_fail.leo @@ -1,5 +1,5 @@ circuit Foo { - a: u8, + a: u8; function set_a(const self, new: u8) { self.a = new; diff --git a/compiler/tests/circuits/define_circuit_inside_circuit_function.leo b/compiler/tests/circuits/define_circuit_inside_circuit_function.leo index cedabf2185..a15259b1d4 100644 --- a/compiler/tests/circuits/define_circuit_inside_circuit_function.leo +++ b/compiler/tests/circuits/define_circuit_inside_circuit_function.leo @@ -1,5 +1,5 @@ circuit Foo { - a: u32, + a: u32; } circuit Bar { diff --git a/compiler/tests/circuits/duplicate_name_context.leo b/compiler/tests/circuits/duplicate_name_context.leo index 8644d27fcb..95431a18e3 100644 --- a/compiler/tests/circuits/duplicate_name_context.leo +++ b/compiler/tests/circuits/duplicate_name_context.leo @@ -1,5 +1,5 @@ circuit Bar { - b2: u32 + b2: u32; function add_five(z:u32) -> u32 { return z+5u32; diff --git a/compiler/tests/circuits/inline.leo b/compiler/tests/circuits/inline.leo index 9ba06f4191..19f3d5cfb2 100644 --- a/compiler/tests/circuits/inline.leo +++ b/compiler/tests/circuits/inline.leo @@ -1,5 +1,5 @@ circuit Foo { - x: u32 + x: u32; } function main() { diff --git a/compiler/tests/circuits/inline_fail.leo b/compiler/tests/circuits/inline_fail.leo index 01597005fb..302c84298a 100644 --- a/compiler/tests/circuits/inline_fail.leo +++ b/compiler/tests/circuits/inline_fail.leo @@ -1,5 +1,5 @@ circuit Foo { - x: u32 + x: u32; } function main() { diff --git a/compiler/tests/circuits/inline_member_fail.leo b/compiler/tests/circuits/inline_member_fail.leo index 59f6d7992b..7bc178a4e6 100644 --- a/compiler/tests/circuits/inline_member_fail.leo +++ b/compiler/tests/circuits/inline_member_fail.leo @@ -1,5 +1,5 @@ circuit Foo { - x: u8 + x: u8; } function main() { diff --git a/compiler/tests/circuits/inline_member_pass.leo b/compiler/tests/circuits/inline_member_pass.leo index 6fd7f7dff7..d9b4a930e3 100644 --- a/compiler/tests/circuits/inline_member_pass.leo +++ b/compiler/tests/circuits/inline_member_pass.leo @@ -1,5 +1,5 @@ circuit Foo { - x: u8 + x: u8; function new(x: u8) -> Self { return Self { x }; diff --git a/compiler/tests/circuits/member_function.leo b/compiler/tests/circuits/member_function.leo index eee44be448..c2e541b2cd 100644 --- a/compiler/tests/circuits/member_function.leo +++ b/compiler/tests/circuits/member_function.leo @@ -1,5 +1,5 @@ circuit Foo { - x: u32, + x: u32; function echo(self) -> u32 { return self.x; diff --git a/compiler/tests/circuits/member_function_nested.leo b/compiler/tests/circuits/member_function_nested.leo index b8bf172947..77b0d83bb9 100644 --- a/compiler/tests/circuits/member_function_nested.leo +++ b/compiler/tests/circuits/member_function_nested.leo @@ -1,5 +1,5 @@ circuit Foo { - x: u32, + x: u32; function add_x(self, y: u32) -> u32 { return self.x + y; diff --git a/compiler/tests/circuits/member_variable.leo b/compiler/tests/circuits/member_variable.leo index a3f3fbe7e6..c1f5812dce 100644 --- a/compiler/tests/circuits/member_variable.leo +++ b/compiler/tests/circuits/member_variable.leo @@ -1,5 +1,5 @@ circuit Foo { - x: u32, + x: u32; } function main() { diff --git a/compiler/tests/circuits/member_variable_and_function.leo b/compiler/tests/circuits/member_variable_and_function.leo index f90cdca072..d579f3fbf5 100644 --- a/compiler/tests/circuits/member_variable_and_function.leo +++ b/compiler/tests/circuits/member_variable_and_function.leo @@ -1,5 +1,5 @@ circuit Foo { - foo: u32, + foo: u32; function bar() -> u32 { return 1u32; diff --git a/compiler/tests/circuits/member_variable_fail.leo b/compiler/tests/circuits/member_variable_fail.leo index fdf42068d5..a0a9823486 100644 --- a/compiler/tests/circuits/member_variable_fail.leo +++ b/compiler/tests/circuits/member_variable_fail.leo @@ -1,5 +1,5 @@ circuit Foo { - x: u32 + x: u32; } function main() { diff --git a/compiler/tests/circuits/mut_function_fail.leo b/compiler/tests/circuits/mut_function_fail.leo index 44583810dd..049d7143b0 100644 --- a/compiler/tests/circuits/mut_function_fail.leo +++ b/compiler/tests/circuits/mut_function_fail.leo @@ -1,5 +1,5 @@ circuit Foo { - a: u8, + a: u8; function bar() {} } diff --git a/compiler/tests/circuits/mut_self_function_fail.leo b/compiler/tests/circuits/mut_self_function_fail.leo index b81b18e743..d29c7ad2a4 100644 --- a/compiler/tests/circuits/mut_self_function_fail.leo +++ b/compiler/tests/circuits/mut_self_function_fail.leo @@ -1,5 +1,5 @@ circuit Foo { - a: u8, + a: u8; function bar() {} diff --git a/compiler/tests/circuits/mut_self_static_function_fail.leo b/compiler/tests/circuits/mut_self_static_function_fail.leo index b81b18e743..d29c7ad2a4 100644 --- a/compiler/tests/circuits/mut_self_static_function_fail.leo +++ b/compiler/tests/circuits/mut_self_static_function_fail.leo @@ -1,5 +1,5 @@ circuit Foo { - a: u8, + a: u8; function bar() {} diff --git a/compiler/tests/circuits/mut_self_variable.leo b/compiler/tests/circuits/mut_self_variable.leo index dc2047d872..1c41bc3090 100644 --- a/compiler/tests/circuits/mut_self_variable.leo +++ b/compiler/tests/circuits/mut_self_variable.leo @@ -1,5 +1,5 @@ circuit Foo { - a: u8, + a: u8; function set_a(mut self, new: u8) { self.a = new; diff --git a/compiler/tests/circuits/mut_self_variable_branch.leo b/compiler/tests/circuits/mut_self_variable_branch.leo index 1c2f126f08..7999f600dd 100644 --- a/compiler/tests/circuits/mut_self_variable_branch.leo +++ b/compiler/tests/circuits/mut_self_variable_branch.leo @@ -1,5 +1,5 @@ circuit Foo { - a: u8, + a: u8; function set_a(mut self, condition: bool, new: u8) { if condition { diff --git a/compiler/tests/circuits/mut_self_variable_conditional.leo b/compiler/tests/circuits/mut_self_variable_conditional.leo index 61a5e354dc..fec92fef93 100644 --- a/compiler/tests/circuits/mut_self_variable_conditional.leo +++ b/compiler/tests/circuits/mut_self_variable_conditional.leo @@ -5,7 +5,7 @@ function main() { } circuit Foo { - a: u32 + a: u32; function bar(mut self) { if true { diff --git a/compiler/tests/circuits/mut_self_variable_fail.leo b/compiler/tests/circuits/mut_self_variable_fail.leo index 4db62a4d3e..50edbc11f1 100644 --- a/compiler/tests/circuits/mut_self_variable_fail.leo +++ b/compiler/tests/circuits/mut_self_variable_fail.leo @@ -1,5 +1,5 @@ circuit Foo { - a: u8, + a: u8; function set_a(self, new: u8) { self.a = new; diff --git a/compiler/tests/circuits/mut_variable.leo b/compiler/tests/circuits/mut_variable.leo index ddc7412038..9dddc0510f 100644 --- a/compiler/tests/circuits/mut_variable.leo +++ b/compiler/tests/circuits/mut_variable.leo @@ -1,5 +1,5 @@ circuit Foo { - a: u8, + a: u8; } function main() { diff --git a/compiler/tests/circuits/mut_variable_fail.leo b/compiler/tests/circuits/mut_variable_fail.leo index e116b33d5c..60bb19a5c6 100644 --- a/compiler/tests/circuits/mut_variable_fail.leo +++ b/compiler/tests/circuits/mut_variable_fail.leo @@ -1,5 +1,5 @@ circuit Foo { - a: u8, + a: u8; } function main() { diff --git a/compiler/tests/circuits/mutable_call_immutable_context.leo b/compiler/tests/circuits/mutable_call_immutable_context.leo index d235d11cb7..ab4e23ad2c 100644 --- a/compiler/tests/circuits/mutable_call_immutable_context.leo +++ b/compiler/tests/circuits/mutable_call_immutable_context.leo @@ -1,5 +1,5 @@ circuit TestMe { - x: u8, + x: u8; function test_me(mut self) -> u8 { self.x += 1; diff --git a/compiler/tests/circuits/pedersen_mock.leo b/compiler/tests/circuits/pedersen_mock.leo index 0fc6752f2f..fb154aa7c1 100644 --- a/compiler/tests/circuits/pedersen_mock.leo +++ b/compiler/tests/circuits/pedersen_mock.leo @@ -1,5 +1,5 @@ circuit PedersenHash { - parameters: [u32; 512] + parameters: [u32; 512]; function new(parameters: [u32; 512]) -> Self { return Self { parameters: parameters }; diff --git a/compiler/tests/circuits/self_member.leo b/compiler/tests/circuits/self_member.leo index 237baac9de..a21fbfc5cf 100644 --- a/compiler/tests/circuits/self_member.leo +++ b/compiler/tests/circuits/self_member.leo @@ -1,5 +1,5 @@ circuit Foo { - f: u32, + f: u32; function bar(self) -> u32 { return self.f; diff --git a/compiler/tests/circuits/self_member_invalid.leo b/compiler/tests/circuits/self_member_invalid.leo index 7283b3260a..51ba9b53df 100644 --- a/compiler/tests/circuits/self_member_invalid.leo +++ b/compiler/tests/circuits/self_member_invalid.leo @@ -1,5 +1,5 @@ circuit Foo { - f: u32, + f: u32; function bar() -> u32 { return f; diff --git a/compiler/tests/global_consts/global_const_types.leo b/compiler/tests/global_consts/global_const_types.leo index 8819e55662..38e4493ae8 100644 --- a/compiler/tests/global_consts/global_const_types.leo +++ b/compiler/tests/global_consts/global_const_types.leo @@ -10,8 +10,8 @@ const foo = Foo { width: 10, height: 20 }; const uno = uno(); circuit Foo { - width: u32, - height: u32, + width: u32; + height: u32; } function uno() -> u32 { diff --git a/compiler/tests/import/imports/bar/src/bat/bat.leo b/compiler/tests/import/imports/bar/src/bat/bat.leo index a7d2fc83d4..f76edfe54e 100755 --- a/compiler/tests/import/imports/bar/src/bat/bat.leo +++ b/compiler/tests/import/imports/bar/src/bat/bat.leo @@ -1,3 +1,3 @@ circuit Bat { - t: u32 + t: u32; } \ No newline at end of file diff --git a/compiler/tests/import/imports/bar/src/baz.leo b/compiler/tests/import/imports/bar/src/baz.leo index 25fee7f3e5..3050653fae 100755 --- a/compiler/tests/import/imports/bar/src/baz.leo +++ b/compiler/tests/import/imports/bar/src/baz.leo @@ -1,9 +1,9 @@ circuit Baz { - z: u32 + z: u32; } circuit Bazzar { - a: u32 + a: u32; } const ONE: u8 = 1; \ No newline at end of file diff --git a/compiler/tests/import/imports/bar/src/lib.leo b/compiler/tests/import/imports/bar/src/lib.leo index c169f5935e..845b6e5fd3 100755 --- a/compiler/tests/import/imports/bar/src/lib.leo +++ b/compiler/tests/import/imports/bar/src/lib.leo @@ -1,3 +1,3 @@ circuit Bar { - r: u32 + r: u32; } \ No newline at end of file diff --git a/compiler/tests/import/imports/car/src/lib.leo b/compiler/tests/import/imports/car/src/lib.leo index b1e037fd38..58a10e4067 100755 --- a/compiler/tests/import/imports/car/src/lib.leo +++ b/compiler/tests/import/imports/car/src/lib.leo @@ -1,3 +1,3 @@ circuit Car { - c: u32 + c: u32; } \ No newline at end of file diff --git a/compiler/tests/import/src/test-import.leo b/compiler/tests/import/src/test-import.leo index 9a57d433f4..e75fdd2fb1 100644 --- a/compiler/tests/import/src/test-import.leo +++ b/compiler/tests/import/src/test-import.leo @@ -1,6 +1,6 @@ circuit Point { - x: u32 - y: u32 + x: u32; + y: u32; } function foo() -> u32 { diff --git a/compiler/tests/mutability/circuit.leo b/compiler/tests/mutability/circuit.leo index 508595ef16..29f2096a03 100644 --- a/compiler/tests/mutability/circuit.leo +++ b/compiler/tests/mutability/circuit.leo @@ -1,6 +1,6 @@ // Circuits are immutable by default. circuit Foo { - x: u32 + x: u32; } function main() { diff --git a/compiler/tests/mutability/circuit_mut.leo b/compiler/tests/mutability/circuit_mut.leo index f7067db11e..4ce2ea7c54 100644 --- a/compiler/tests/mutability/circuit_mut.leo +++ b/compiler/tests/mutability/circuit_mut.leo @@ -1,6 +1,6 @@ // Adding the `mut` keyword makes a circuit variable mutable. circuit Foo { - x: u32 + x: u32; } function main() { diff --git a/compiler/tests/mutability/circuit_variable_mut.leo b/compiler/tests/mutability/circuit_variable_mut.leo index f7067db11e..4ce2ea7c54 100644 --- a/compiler/tests/mutability/circuit_variable_mut.leo +++ b/compiler/tests/mutability/circuit_variable_mut.leo @@ -1,6 +1,6 @@ // Adding the `mut` keyword makes a circuit variable mutable. circuit Foo { - x: u32 + x: u32; } function main() { diff --git a/examples/pedersen-hash/src/main.leo b/examples/pedersen-hash/src/main.leo index 030dc0bcb8..ab6474c4e4 100644 --- a/examples/pedersen-hash/src/main.leo +++ b/examples/pedersen-hash/src/main.leo @@ -1,5 +1,5 @@ circuit PedersenHash { - parameters: [group; 256], + parameters: [group; 256]; // Instantiates a Pedersen hash circuit function new(parameters: [group; 256]) -> Self { diff --git a/examples/silly-sudoku/src/lib.leo b/examples/silly-sudoku/src/lib.leo index c1e4922461..c005af2934 100644 --- a/examples/silly-sudoku/src/lib.leo +++ b/examples/silly-sudoku/src/lib.leo @@ -16,7 +16,7 @@ circuit SillySudoku { // The starting grid values for the Sudoku puzzle. // Unset cells on the puzzle grid are set to 0. - puzzle_grid: [u8; (3, 3)], + puzzle_grid: [u8; (3, 3)]; /** * Returns true if a given Sudoku answer is correct. diff --git a/grammar/README.md b/grammar/README.md index e7adadb0b2..20ba80c890 100644 --- a/grammar/README.md +++ b/grammar/README.md @@ -476,7 +476,7 @@ Line terminators form whitespace, along with spaces and horizontal tabs. whitespace = space / horizontal-tab / newline ``` -Go to: _[space](#user-content-space), [horizontal-tab](#user-content-horizontal-tab), [newline](#user-content-newline)_; +Go to: _[newline](#user-content-newline), [horizontal-tab](#user-content-horizontal-tab), [space](#user-content-space)_; There are two kinds of comments in Leo, as in other languages. @@ -494,7 +494,7 @@ the ones used in the Java language reference. comment = block-comment / end-of-line-comment ``` -Go to: _[end-of-line-comment](#user-content-end-of-line-comment), [block-comment](#user-content-block-comment)_; +Go to: _[block-comment](#user-content-block-comment), [end-of-line-comment](#user-content-end-of-line-comment)_; @@ -511,7 +511,7 @@ rest-of-block-comment = "*" rest-of-block-comment-after-star / not-star rest-of-block-comment ``` -Go to: _[rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star), [rest-of-block-comment](#user-content-rest-of-block-comment), [not-star](#user-content-not-star)_; +Go to: _[rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star), [not-star](#user-content-not-star), [rest-of-block-comment](#user-content-rest-of-block-comment)_; @@ -521,7 +521,7 @@ rest-of-block-comment-after-star = "/" / not-star-or-slash rest-of-block-comment ``` -Go to: _[not-star-or-slash](#user-content-not-star-or-slash), [rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star), [rest-of-block-comment](#user-content-rest-of-block-comment)_; +Go to: _[rest-of-block-comment](#user-content-rest-of-block-comment), [rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star), [not-star-or-slash](#user-content-not-star-or-slash)_; @@ -596,7 +596,7 @@ lowercase-letter = %x61-7A ; a-z letter = uppercase-letter / lowercase-letter ``` -Go to: _[uppercase-letter](#user-content-uppercase-letter), [lowercase-letter](#user-content-lowercase-letter)_; +Go to: _[lowercase-letter](#user-content-lowercase-letter), [uppercase-letter](#user-content-uppercase-letter)_; An identifier is a non-empty sequence of letters, digits, and underscores, @@ -639,7 +639,7 @@ format-string-element = not-double-quote-or-open-brace / format-string-container ``` -Go to: _[format-string-container](#user-content-format-string-container), [not-double-quote-or-open-brace](#user-content-not-double-quote-or-open-brace), [not-double-quote-or-close-brace](#user-content-not-double-quote-or-close-brace)_; +Go to: _[not-double-quote-or-close-brace](#user-content-not-double-quote-or-close-brace), [not-double-quote-or-open-brace](#user-content-not-double-quote-or-open-brace), [format-string-container](#user-content-format-string-container)_; @@ -764,7 +764,7 @@ atomic-literal = untyped-literal / address-literal ``` -Go to: _[signed-literal](#user-content-signed-literal), [untyped-literal](#user-content-untyped-literal), [boolean-literal](#user-content-boolean-literal), [field-literal](#user-content-field-literal), [unsigned-literal](#user-content-unsigned-literal), [product-group-literal](#user-content-product-group-literal), [address-literal](#user-content-address-literal)_; +Go to: _[product-group-literal](#user-content-product-group-literal), [signed-literal](#user-content-signed-literal), [field-literal](#user-content-field-literal), [address-literal](#user-content-address-literal), [boolean-literal](#user-content-boolean-literal), [untyped-literal](#user-content-untyped-literal), [unsigned-literal](#user-content-unsigned-literal)_; After defining the (mostly) alphanumeric tokens above, @@ -809,7 +809,7 @@ token = keyword / symbol ``` -Go to: _[keyword](#user-content-keyword), [format-string](#user-content-format-string), [annotation-name](#user-content-annotation-name), [atomic-literal](#user-content-atomic-literal), [identifier](#user-content-identifier), [package-name](#user-content-package-name), [symbol](#user-content-symbol)_; +Go to: _[symbol](#user-content-symbol), [package-name](#user-content-package-name), [format-string](#user-content-format-string), [annotation-name](#user-content-annotation-name), [identifier](#user-content-identifier), [keyword](#user-content-keyword), [atomic-literal](#user-content-atomic-literal)_; @@ -845,7 +845,7 @@ signed-type = %s"i8" / %s"i16" / %s"i32" / %s"i64" / %s"i128" integer-type = unsigned-type / signed-type ``` -Go to: _[signed-type](#user-content-signed-type), [unsigned-type](#user-content-unsigned-type)_; +Go to: _[unsigned-type](#user-content-unsigned-type), [signed-type](#user-content-signed-type)_; The integer types, along with the field and group types, @@ -866,7 +866,7 @@ group-type = %s"group" arithmetic-type = integer-type / field-type / group-type ``` -Go to: _[field-type](#user-content-field-type), [integer-type](#user-content-integer-type), [group-type](#user-content-group-type)_; +Go to: _[group-type](#user-content-group-type), [integer-type](#user-content-integer-type), [field-type](#user-content-field-type)_; The arithmetic types, along with the boolean and address types, @@ -887,7 +887,7 @@ address-type = %s"address" scalar-type = boolean-type / arithmetic-type / address-type ``` -Go to: _[boolean-type](#user-content-boolean-type), [address-type](#user-content-address-type), [arithmetic-type](#user-content-arithmetic-type)_; +Go to: _[boolean-type](#user-content-boolean-type), [arithmetic-type](#user-content-arithmetic-type), [address-type](#user-content-address-type)_; Circuit types are denoted by identifiers and the keyword `Self`. @@ -927,7 +927,7 @@ or a tuple of one or more dimensions. array-type = "[" type ";" array-dimensions "]" ``` -Go to: _[array-dimensions](#user-content-array-dimensions), [type](#user-content-type)_; +Go to: _[type](#user-content-type), [array-dimensions](#user-content-array-dimensions)_; @@ -948,7 +948,7 @@ i.e. types whose values contain (sub-)values aggregate-type = tuple-type / array-type / circuit-type ``` -Go to: _[circuit-type](#user-content-circuit-type), [tuple-type](#user-content-tuple-type), [array-type](#user-content-array-type)_; +Go to: _[array-type](#user-content-array-type), [tuple-type](#user-content-tuple-type), [circuit-type](#user-content-circuit-type)_; Scalar and aggregate types form all the types. @@ -994,7 +994,7 @@ A literal is either an atomic one or an affine group literal. literal = atomic-literal / affine-group-literal ``` -Go to: _[atomic-literal](#user-content-atomic-literal), [affine-group-literal](#user-content-affine-group-literal)_; +Go to: _[affine-group-literal](#user-content-affine-group-literal), [atomic-literal](#user-content-atomic-literal)_; The following rule is not directly referenced in the rules for expressions @@ -1036,7 +1036,7 @@ primary-expression = identifier / circuit-expression ``` -Go to: _[identifier](#user-content-identifier), [expression](#user-content-expression), [tuple-expression](#user-content-tuple-expression), [literal](#user-content-literal), [array-expression](#user-content-array-expression), [circuit-expression](#user-content-circuit-expression)_; +Go to: _[literal](#user-content-literal), [expression](#user-content-expression), [tuple-expression](#user-content-tuple-expression), [identifier](#user-content-identifier), [array-expression](#user-content-array-expression), [circuit-expression](#user-content-circuit-expression)_; Tuple expressions construct tuples. @@ -1089,7 +1089,7 @@ Go to: _[expression](#user-content-expression)_; array-repeat-construction = "[" expression ";" array-dimensions "]" ``` -Go to: _[expression](#user-content-expression), [array-dimensions](#user-content-array-dimensions)_; +Go to: _[array-dimensions](#user-content-array-dimensions), [expression](#user-content-expression)_; @@ -1097,7 +1097,7 @@ Go to: _[expression](#user-content-expression), [array-dimensions](#user-content array-construction = array-inline-construction / array-repeat-construction ``` -Go to: _[array-repeat-construction](#user-content-array-repeat-construction), [array-inline-construction](#user-content-array-inline-construction)_; +Go to: _[array-inline-construction](#user-content-array-inline-construction), [array-repeat-construction](#user-content-array-repeat-construction)_; @@ -1184,7 +1184,7 @@ postfix-expression = primary-expression / postfix-expression "[" [expression] ".." [expression] "]" ``` -Go to: _[function-arguments](#user-content-function-arguments), [circuit-type](#user-content-circuit-type), [postfix-expression](#user-content-postfix-expression), [primary-expression](#user-content-primary-expression), [identifier](#user-content-identifier), [natural](#user-content-natural), [expression](#user-content-expression)_; +Go to: _[identifier](#user-content-identifier), [expression](#user-content-expression), [primary-expression](#user-content-primary-expression), [function-arguments](#user-content-function-arguments), [natural](#user-content-natural), [postfix-expression](#user-content-postfix-expression), [circuit-type](#user-content-circuit-type)_; Unary operators have the highest operator precedence. @@ -1224,7 +1224,7 @@ multiplicative-expression = exponential-expression / multiplicative-expression "/" exponential-expression ``` -Go to: _[multiplicative-expression](#user-content-multiplicative-expression), [exponential-expression](#user-content-exponential-expression)_; +Go to: _[exponential-expression](#user-content-exponential-expression), [multiplicative-expression](#user-content-multiplicative-expression)_; Then there are addition and subtraction, both left-assocative. @@ -1236,7 +1236,7 @@ additive-expression = multiplicative-expression / additive-expression "-" multiplicative-expression ``` -Go to: _[additive-expression](#user-content-additive-expression), [multiplicative-expression](#user-content-multiplicative-expression)_; +Go to: _[multiplicative-expression](#user-content-multiplicative-expression), [additive-expression](#user-content-additive-expression)_; Next in the precedence order are ordering relations. @@ -1275,7 +1275,7 @@ conjunctive-expression = equality-expression / conjunctive-expression "&&" equality-expression ``` -Go to: _[conjunctive-expression](#user-content-conjunctive-expression), [equality-expression](#user-content-equality-expression)_; +Go to: _[equality-expression](#user-content-equality-expression), [conjunctive-expression](#user-content-conjunctive-expression)_; Next come disjunctive expressions, left-associative. @@ -1286,7 +1286,7 @@ disjunctive-expression = conjunctive-expression / disjunctive-expression "||" conjunctive-expression ``` -Go to: _[conjunctive-expression](#user-content-conjunctive-expression), [disjunctive-expression](#user-content-disjunctive-expression)_; +Go to: _[disjunctive-expression](#user-content-disjunctive-expression), [conjunctive-expression](#user-content-conjunctive-expression)_; Finally we have conditional expressions. @@ -1299,7 +1299,7 @@ conditional-expression = disjunctive-expression ":" conditional-expression ``` -Go to: _[expression](#user-content-expression), [disjunctive-expression](#user-content-disjunctive-expression), [conditional-expression](#user-content-conditional-expression)_; +Go to: _[disjunctive-expression](#user-content-disjunctive-expression), [conditional-expression](#user-content-conditional-expression), [expression](#user-content-expression)_; Those above are all the expressions. @@ -1332,7 +1332,7 @@ statement = expression-statement / block ``` -Go to: _[return-statement](#user-content-return-statement), [variable-declaration](#user-content-variable-declaration), [constant-declaration](#user-content-constant-declaration), [expression-statement](#user-content-expression-statement), [conditional-statement](#user-content-conditional-statement), [console-statement](#user-content-console-statement), [block](#user-content-block), [assignment-statement](#user-content-assignment-statement), [loop-statement](#user-content-loop-statement)_; +Go to: _[expression-statement](#user-content-expression-statement), [console-statement](#user-content-console-statement), [return-statement](#user-content-return-statement), [variable-declaration](#user-content-variable-declaration), [loop-statement](#user-content-loop-statement), [constant-declaration](#user-content-constant-declaration), [assignment-statement](#user-content-assignment-statement), [conditional-statement](#user-content-conditional-statement), [block](#user-content-block)_; @@ -1373,7 +1373,7 @@ variable-declaration = %s"let" identifier-or-identifiers [ ":" type ] "=" expres constant-declaration = %s"const" identifier-or-identifiers [ ":" type ] "=" expression ";" ``` -Go to: _[identifier-or-identifiers](#user-content-identifier-or-identifiers), [type](#user-content-type), [expression](#user-content-expression)_; +Go to: _[expression](#user-content-expression), [identifier-or-identifiers](#user-content-identifier-or-identifiers), [type](#user-content-type)_; @@ -1397,7 +1397,7 @@ Note that blocks are required in all branches, not merely statements. branch = %s"if" expression block ``` -Go to: _[expression](#user-content-expression), [block](#user-content-block)_; +Go to: _[block](#user-content-block), [expression](#user-content-expression)_; @@ -1407,7 +1407,7 @@ conditional-statement = branch / branch %s"else" conditional-statement ``` -Go to: _[branch](#user-content-branch), [conditional-statement](#user-content-conditional-statement), [block](#user-content-block)_; +Go to: _[branch](#user-content-branch), [block](#user-content-block), [conditional-statement](#user-content-conditional-statement)_; A loop statement implicitly defines a loop variable @@ -1419,7 +1419,7 @@ The body is a block. loop-statement = %s"for" identifier %s"in" expression ".." expression block ``` -Go to: _[identifier](#user-content-identifier), [expression](#user-content-expression), [block](#user-content-block)_; +Go to: _[block](#user-content-block), [identifier](#user-content-identifier), [expression](#user-content-expression)_; An assignment statement is straightforward. @@ -1436,7 +1436,7 @@ assignment-operator = "=" / "+=" / "-=" / "*=" / "/=" / "**=" assignment-statement = expression assignment-operator expression ";" ``` -Go to: _[expression](#user-content-expression), [assignment-operator](#user-content-assignment-operator)_; +Go to: _[assignment-operator](#user-content-assignment-operator), [expression](#user-content-expression)_; Console statements start with the `console` keyword, @@ -1492,7 +1492,7 @@ Go to: _[format-string](#user-content-format-string)_; print-call = print-function print-arguments ``` -Go to: _[print-arguments](#user-content-print-arguments), [print-function](#user-content-print-function)_; +Go to: _[print-function](#user-content-print-function), [print-arguments](#user-content-print-arguments)_; An annotation consists of an annotation name (which starts with `@`) @@ -1505,7 +1505,7 @@ annotation = annotation-name [ "(" identifier *( "," identifier ) ")" ] ``` -Go to: _[annotation-name](#user-content-annotation-name), [identifier](#user-content-identifier)_; +Go to: _[identifier](#user-content-identifier), [annotation-name](#user-content-annotation-name)_; A function declaration defines a function. @@ -1522,7 +1522,7 @@ function-declaration = *annotation %s"function" identifier block ``` -Go to: _[identifier](#user-content-identifier), [block](#user-content-block), [type](#user-content-type), [function-parameters](#user-content-function-parameters)_; +Go to: _[function-parameters](#user-content-function-parameters), [type](#user-content-type), [block](#user-content-block), [identifier](#user-content-identifier)_; @@ -1532,7 +1532,7 @@ function-parameters = self-parameter / function-inputs ``` -Go to: _[self-parameter](#user-content-self-parameter), [function-inputs](#user-content-function-inputs)_; +Go to: _[function-inputs](#user-content-function-inputs), [self-parameter](#user-content-self-parameter)_; @@ -1581,10 +1581,10 @@ as consisting of member variables and functions. ```abnf circuit-declaration = *annotation %s"circuit" identifier - "{" *member-variable-declaration *member-function-declaration "}" + "{" [ member-variable-declaration ] *member-function-declaration "}" ``` -Go to: _[identifier](#user-content-identifier)_; +Go to: _[identifier](#user-content-identifier), [member-variable-declaration](#user-content-member-variable-declaration)_; An import declaration consists of the `import` keyword @@ -1613,7 +1613,7 @@ package-path = "*" / "(" package-path *( "," package-path ) [","] ")" ``` -Go to: _[identifier](#user-content-identifier), [package-path](#user-content-package-path), [package-name](#user-content-package-name)_; +Go to: _[identifier](#user-content-identifier), [package-name](#user-content-package-name), [package-path](#user-content-package-path)_; Finally, we define a file as a sequence of zero or more declarations. @@ -1626,7 +1626,7 @@ declaration = import-declaration / constant-declaration ``` -Go to: _[import-declaration](#user-content-import-declaration), [constant-declaration](#user-content-constant-declaration), [function-declaration](#user-content-function-declaration), [circuit-declaration](#user-content-circuit-declaration)_; +Go to: _[import-declaration](#user-content-import-declaration), [function-declaration](#user-content-function-declaration), [constant-declaration](#user-content-constant-declaration), [circuit-declaration](#user-content-circuit-declaration)_; diff --git a/grammar/abnf-grammar.txt b/grammar/abnf-grammar.txt index d62c2900fd..4388a549f7 100644 --- a/grammar/abnf-grammar.txt +++ b/grammar/abnf-grammar.txt @@ -946,7 +946,7 @@ member-function-declaration = function-declaration ; as consisting of member variables and functions. circuit-declaration = *annotation %s"circuit" identifier - "{" *member-variable-declaration *member-function-declaration "}" + "{" [ member-variable-declaration ] *member-function-declaration "}" ; An import declaration consists of the `import` keyword ; followed by a package path, which may be one of the following: diff --git a/parser/benches/big_circuit.leo b/parser/benches/big_circuit.leo index 5d2242581c..a693788f11 100644 --- a/parser/benches/big_circuit.leo +++ b/parser/benches/big_circuit.leo @@ -6,260 +6,260 @@ function main() { } circuit Foo { - x0: u8, - x1: u8, - x2: u8, - x3: u8, - x4: u8, - x5: u8, - x6: u8, - x7: u8, - x8: u8, - x9: u8, - x10: u8, - x11: u8, - x12: u8, - x13: u8, - x14: u8, - x15: u8, - x16: u8, - x17: u8, - x18: u8, - x19: u8, - x20: u8, - x21: u8, - x22: u8, - x23: u8, - x24: u8, - x25: u8, - x26: u8, - x27: u8, - x28: u8, - x29: u8, - x30: u8, - x31: u8, - x32: u8, - x33: u8, - x34: u8, - x35: u8, - x36: u8, - x37: u8, - x38: u8, - x39: u8, - x40: u8, - x41: u8, - x42: u8, - x43: u8, - x44: u8, - x45: u8, - x46: u8, - x47: u8, - x48: u8, - x49: u8, - x50: u8, - x51: u8, - x52: u8, - x53: u8, - x54: u8, - x55: u8, - x56: u8, - x57: u8, - x58: u8, - x59: u8, - x60: u8, - x61: u8, - x62: u8, - x63: u8, - x64: u8, - x65: u8, - x66: u8, - x67: u8, - x68: u8, - x69: u8, - x70: u8, - x71: u8, - x72: u8, - x73: u8, - x74: u8, - x75: u8, - x76: u8, - x77: u8, - x78: u8, - x79: u8, - x80: u8, - x81: u8, - x82: u8, - x83: u8, - x84: u8, - x85: u8, - x86: u8, - x87: u8, - x88: u8, - x89: u8, - x90: u8, - x91: u8, - x92: u8, - x93: u8, - x94: u8, - x95: u8, - x96: u8, - x97: u8, - x98: u8, - x99: u8, - x100: u8, - x101: u8, - x102: u8, - x103: u8, - x104: u8, - x105: u8, - x106: u8, - x107: u8, - x108: u8, - x109: u8, - x110: u8, - x111: u8, - x112: u8, - x113: u8, - x114: u8, - x115: u8, - x116: u8, - x117: u8, - x118: u8, - x119: u8, - x120: u8, - x121: u8, - x122: u8, - x123: u8, - x124: u8, - x125: u8, - x126: u8, - x127: u8, - x128: u8, - x129: u8, - x130: u8, - x131: u8, - x132: u8, - x133: u8, - x134: u8, - x135: u8, - x136: u8, - x137: u8, - x138: u8, - x139: u8, - x140: u8, - x141: u8, - x142: u8, - x143: u8, - x144: u8, - x145: u8, - x146: u8, - x147: u8, - x148: u8, - x149: u8, - x150: u8, - x151: u8, - x152: u8, - x153: u8, - x154: u8, - x155: u8, - x156: u8, - x157: u8, - x158: u8, - x159: u8, - x160: u8, - x161: u8, - x162: u8, - x163: u8, - x164: u8, - x165: u8, - x166: u8, - x167: u8, - x168: u8, - x169: u8, - x170: u8, - x171: u8, - x172: u8, - x173: u8, - x174: u8, - x175: u8, - x176: u8, - x177: u8, - x178: u8, - x179: u8, - x180: u8, - x181: u8, - x182: u8, - x183: u8, - x184: u8, - x185: u8, - x186: u8, - x187: u8, - x188: u8, - x189: u8, - x190: u8, - x191: u8, - x192: u8, - x193: u8, - x194: u8, - x195: u8, - x196: u8, - x197: u8, - x198: u8, - x199: u8, - x200: u8, - x201: u8, - x202: u8, - x203: u8, - x204: u8, - x205: u8, - x206: u8, - x207: u8, - x208: u8, - x209: u8, - x210: u8, - x211: u8, - x212: u8, - x213: u8, - x214: u8, - x215: u8, - x216: u8, - x217: u8, - x218: u8, - x219: u8, - x220: u8, - x221: u8, - x222: u8, - x223: u8, - x224: u8, - x225: u8, - x226: u8, - x227: u8, - x228: u8, - x229: u8, - x230: u8, - x231: u8, - x232: u8, - x233: u8, - x234: u8, - x235: u8, - x236: u8, - x237: u8, - x238: u8, - x239: u8, - x240: u8, - x241: u8, - x242: u8, - x243: u8, - x244: u8, - x245: u8, - x246: u8, - x247: u8, - x248: u8, - x249: u8, - x250: u8, - x251: u8, - x252: u8, - x253: u8, - x254: u8, - x255: u8 + x0: u8; + x1: u8; + x2: u8; + x3: u8; + x4: u8; + x5: u8; + x6: u8; + x7: u8; + x8: u8; + x9: u8; + x10: u8; + x11: u8; + x12: u8; + x13: u8; + x14: u8; + x15: u8; + x16: u8; + x17: u8; + x18: u8; + x19: u8; + x20: u8; + x21: u8; + x22: u8; + x23: u8; + x24: u8; + x25: u8; + x26: u8; + x27: u8; + x28: u8; + x29: u8; + x30: u8; + x31: u8; + x32: u8; + x33: u8; + x34: u8; + x35: u8; + x36: u8; + x37: u8; + x38: u8; + x39: u8; + x40: u8; + x41: u8; + x42: u8; + x43: u8; + x44: u8; + x45: u8; + x46: u8; + x47: u8; + x48: u8; + x49: u8; + x50: u8; + x51: u8; + x52: u8; + x53: u8; + x54: u8; + x55: u8; + x56: u8; + x57: u8; + x58: u8; + x59: u8; + x60: u8; + x61: u8; + x62: u8; + x63: u8; + x64: u8; + x65: u8; + x66: u8; + x67: u8; + x68: u8; + x69: u8; + x70: u8; + x71: u8; + x72: u8; + x73: u8; + x74: u8; + x75: u8; + x76: u8; + x77: u8; + x78: u8; + x79: u8; + x80: u8; + x81: u8; + x82: u8; + x83: u8; + x84: u8; + x85: u8; + x86: u8; + x87: u8; + x88: u8; + x89: u8; + x90: u8; + x91: u8; + x92: u8; + x93: u8; + x94: u8; + x95: u8; + x96: u8; + x97: u8; + x98: u8; + x99: u8; + x100: u8; + x101: u8; + x102: u8; + x103: u8; + x104: u8; + x105: u8; + x106: u8; + x107: u8; + x108: u8; + x109: u8; + x110: u8; + x111: u8; + x112: u8; + x113: u8; + x114: u8; + x115: u8; + x116: u8; + x117: u8; + x118: u8; + x119: u8; + x120: u8; + x121: u8; + x122: u8; + x123: u8; + x124: u8; + x125: u8; + x126: u8; + x127: u8; + x128: u8; + x129: u8; + x130: u8; + x131: u8; + x132: u8; + x133: u8; + x134: u8; + x135: u8; + x136: u8; + x137: u8; + x138: u8; + x139: u8; + x140: u8; + x141: u8; + x142: u8; + x143: u8; + x144: u8; + x145: u8; + x146: u8; + x147: u8; + x148: u8; + x149: u8; + x150: u8; + x151: u8; + x152: u8; + x153: u8; + x154: u8; + x155: u8; + x156: u8; + x157: u8; + x158: u8; + x159: u8; + x160: u8; + x161: u8; + x162: u8; + x163: u8; + x164: u8; + x165: u8; + x166: u8; + x167: u8; + x168: u8; + x169: u8; + x170: u8; + x171: u8; + x172: u8; + x173: u8; + x174: u8; + x175: u8; + x176: u8; + x177: u8; + x178: u8; + x179: u8; + x180: u8; + x181: u8; + x182: u8; + x183: u8; + x184: u8; + x185: u8; + x186: u8; + x187: u8; + x188: u8; + x189: u8; + x190: u8; + x191: u8; + x192: u8; + x193: u8; + x194: u8; + x195: u8; + x196: u8; + x197: u8; + x198: u8; + x199: u8; + x200: u8; + x201: u8; + x202: u8; + x203: u8; + x204: u8; + x205: u8; + x206: u8; + x207: u8; + x208: u8; + x209: u8; + x210: u8; + x211: u8; + x212: u8; + x213: u8; + x214: u8; + x215: u8; + x216: u8; + x217: u8; + x218: u8; + x219: u8; + x220: u8; + x221: u8; + x222: u8; + x223: u8; + x224: u8; + x225: u8; + x226: u8; + x227: u8; + x228: u8; + x229: u8; + x230: u8; + x231: u8; + x232: u8; + x233: u8; + x234: u8; + x235: u8; + x236: u8; + x237: u8; + x238: u8; + x239: u8; + x240: u8; + x241: u8; + x242: u8; + x243: u8; + x244: u8; + x245: u8; + x246: u8; + x247: u8; + x248: u8; + x249: u8; + x250: u8; + x251: u8; + x252: u8; + x253: u8; + x254: u8; + x255: u8; } \ No newline at end of file diff --git a/parser/src/parser/context.rs b/parser/src/parser/context.rs index 1f4a15c490..c83cf2a4dd 100644 --- a/parser/src/parser/context.rs +++ b/parser/src/parser/context.rs @@ -66,6 +66,13 @@ impl ParserContext { SyntaxError::unexpected_eof(&self.end_span) } + /// + /// Returns a reference to the next next token or error if it does not exist. + /// + pub fn peek_next(&self) -> SyntaxResult<&SpannedToken> { + self.tokens.get(self.tokens.len() - 2).ok_or_else(|| self.eof()) + } + /// /// Returns a reference to the next token or error if it does not exist. /// diff --git a/parser/src/parser/file.rs b/parser/src/parser/file.rs index 586d94a6bb..4585a7981a 100644 --- a/parser/src/parser/file.rs +++ b/parser/src/parser/file.rs @@ -310,27 +310,28 @@ impl ParserContext { } /// - /// Returns a [`CircuitMember`] AST node if the next tokens represent a circuit member variable - /// or circuit member function. + /// Returns a [`CircuitMember`] AST node if the next tokens represent a circuit member variable. /// pub fn parse_member_variable_declaration(&mut self) -> SyntaxResult<(CircuitMember, bool)> { let name = self.expect_ident()?; self.expect(Token::Colon)?; let type_ = self.parse_type()?.0; - let peeked = &self.peek()?; - let peeked_token = &peeked.token; - - if peeked_token == &Token::Function || peeked_token == &Token::At || peeked_token == &Token::RightCurly { + let peeked = &self.peek()?.token; + if peeked == &Token::Function || peeked == &Token::At || peeked == &Token::RightCurly { return Ok((CircuitMember::CircuitVariable(name, type_), true)); + } else if peeked == &Token::Comma || peeked == &Token::Semicolon { + let peeked = &self.peek_next()?.token; + if peeked == &Token::Function || peeked == &Token::At || peeked == &Token::RightCurly { + return Ok((CircuitMember::CircuitVariable(name, type_), true)); + } } Ok((CircuitMember::CircuitVariable(name, type_), false)) } /// - /// Returns a [`CircuitMember`] AST node if the next tokens represent a circuit member variable - /// or circuit member function. + /// Returns a [`CircuitMember`] AST node if the next tokens represent a circuit member function. /// pub fn parse_member_function_declaration(&mut self) -> SyntaxResult { let peeked = &self.peek()?; diff --git a/tests/expectations/parser/parser/circuits/big_self.leo.out b/tests/expectations/parser/parser/circuits/big_self.leo.out index ee647ea625..abdced08ca 100644 --- a/tests/expectations/parser/parser/circuits/big_self.leo.out +++ b/tests/expectations/parser/parser/circuits/big_self.leo.out @@ -49,4 +49,5 @@ outputs: col_stop: 6 path: test content: " function x() -> Self {\n...\n }" + global_consts: {} functions: {} diff --git a/tests/expectations/parser/parser/circuits/empty.leo.out b/tests/expectations/parser/parser/circuits/empty.leo.out index 0fa7fe2114..e826c4097d 100644 --- a/tests/expectations/parser/parser/circuits/empty.leo.out +++ b/tests/expectations/parser/parser/circuits/empty.leo.out @@ -9,4 +9,5 @@ outputs: "{\"name\":\"X\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":9,\\\"col_stop\\\":10,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"circuit X {\\\"}\"}": circuit_name: "{\"name\":\"X\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":9,\\\"col_stop\\\":10,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"circuit X {\\\"}\"}" members: [] + global_consts: {} functions: {} diff --git a/tests/expectations/parser/parser/circuits/field_and_functions.leo.out b/tests/expectations/parser/parser/circuits/field_and_functions.leo.out index 02b64f582e..a13e5be7fb 100644 --- a/tests/expectations/parser/parser/circuits/field_and_functions.leo.out +++ b/tests/expectations/parser/parser/circuits/field_and_functions.leo.out @@ -13,7 +13,7 @@ outputs: - "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":4,\\\"line_stop\\\":4,\\\"col_start\\\":5,\\\"col_stop\\\":6,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\" x: u32,\\\"}\"}" - IntegerType: U32 - CircuitVariable: - - "{\"name\":\"y\",\"span\":\"{\\\"line_start\\\":5,\\\"line_stop\\\":5,\\\"col_start\\\":5,\\\"col_stop\\\":6,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\" y: u32,\\\"}\"}" + - "{\"name\":\"y\",\"span\":\"{\\\"line_start\\\":5,\\\"line_stop\\\":5,\\\"col_start\\\":5,\\\"col_stop\\\":6,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\" y: u32\\\"}\"}" - IntegerType: U32 - CircuitFunction: annotations: [] @@ -93,4 +93,5 @@ outputs: col_stop: 6 path: test content: " function y() {\n...\n }" + global_consts: {} functions: {} diff --git a/tests/expectations/parser/parser/circuits/fields.leo.out b/tests/expectations/parser/parser/circuits/fields.leo.out index 354a6892bc..2292d44b23 100644 --- a/tests/expectations/parser/parser/circuits/fields.leo.out +++ b/tests/expectations/parser/parser/circuits/fields.leo.out @@ -10,9 +10,10 @@ outputs: circuit_name: "{\"name\":\"X\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":9,\\\"col_stop\\\":10,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"circuit X {\\\"}\"}" members: - CircuitVariable: - - "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":4,\\\"line_stop\\\":4,\\\"col_start\\\":5,\\\"col_stop\\\":6,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\" x: u32,\\\"}\"}" + - "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":4,\\\"line_stop\\\":4,\\\"col_start\\\":5,\\\"col_stop\\\":6,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\" x: u32;\\\"}\"}" - IntegerType: U32 - CircuitVariable: - - "{\"name\":\"y\",\"span\":\"{\\\"line_start\\\":5,\\\"line_stop\\\":5,\\\"col_start\\\":5,\\\"col_stop\\\":6,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\" y: u32,\\\"}\"}" + - "{\"name\":\"y\",\"span\":\"{\\\"line_start\\\":5,\\\"line_stop\\\":5,\\\"col_start\\\":5,\\\"col_stop\\\":6,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\" y: u32\\\"}\"}" - IntegerType: U32 + global_consts: {} functions: {} diff --git a/tests/expectations/parser/parser/circuits/fields_fail.leo.out b/tests/expectations/parser/parser/circuits/fields_fail.leo.out new file mode 100644 index 0000000000..c43ce7b104 --- /dev/null +++ b/tests/expectations/parser/parser/circuits/fields_fail.leo.out @@ -0,0 +1,5 @@ +--- +namespace: Parse +expectation: Fail +outputs: + - " --> test:5:5\n |\n 5 | y: u32\n | ^\n |\n = expected ',', ';' -- got 'y'" diff --git a/tests/expectations/parser/parser/circuits/functions.leo.out b/tests/expectations/parser/parser/circuits/functions.leo.out index 71b4a7a2bb..aebda6c4e5 100644 --- a/tests/expectations/parser/parser/circuits/functions.leo.out +++ b/tests/expectations/parser/parser/circuits/functions.leo.out @@ -87,4 +87,5 @@ outputs: col_stop: 6 path: test content: " function y() {\n...\n }" + global_consts: {} functions: {} diff --git a/tests/expectations/parser/parser/circuits/mut_self.leo.out b/tests/expectations/parser/parser/circuits/mut_self.leo.out index 54800e5ed7..03997801dc 100644 --- a/tests/expectations/parser/parser/circuits/mut_self.leo.out +++ b/tests/expectations/parser/parser/circuits/mut_self.leo.out @@ -49,4 +49,5 @@ outputs: col_stop: 6 path: test content: " function x(mut self) {\n...\n }" + global_consts: {} functions: {} diff --git a/tests/expectations/parser/parser/circuits/self.leo.out b/tests/expectations/parser/parser/circuits/self.leo.out index 6f1445d071..65785a36b6 100644 --- a/tests/expectations/parser/parser/circuits/self.leo.out +++ b/tests/expectations/parser/parser/circuits/self.leo.out @@ -49,4 +49,5 @@ outputs: col_stop: 6 path: test content: " function x(self) {\n...\n }" + global_consts: {} functions: {} diff --git a/tests/expectations/parser/parser/functions/annotated.leo.out b/tests/expectations/parser/parser/functions/annotated.leo.out index c0e6dab6fb..29612e265a 100644 --- a/tests/expectations/parser/parser/functions/annotated.leo.out +++ b/tests/expectations/parser/parser/functions/annotated.leo.out @@ -6,6 +6,7 @@ outputs: expected_input: [] imports: [] circuits: {} + global_consts: {} functions: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":4,\\\"line_stop\\\":4,\\\"col_start\\\":10,\\\"col_stop\\\":11,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"function x() {\\\"}\"}": annotations: diff --git a/tests/expectations/parser/parser/functions/annotated_param.leo.out b/tests/expectations/parser/parser/functions/annotated_param.leo.out index 99ca4119f9..72ca72549e 100644 --- a/tests/expectations/parser/parser/functions/annotated_param.leo.out +++ b/tests/expectations/parser/parser/functions/annotated_param.leo.out @@ -6,6 +6,7 @@ outputs: expected_input: [] imports: [] circuits: {} + global_consts: {} functions: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":4,\\\"line_stop\\\":4,\\\"col_start\\\":10,\\\"col_stop\\\":11,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"function x() {\\\"}\"}": annotations: diff --git a/tests/expectations/parser/parser/functions/annotated_twice.leo.out b/tests/expectations/parser/parser/functions/annotated_twice.leo.out index 2a4220983e..a83199ec50 100644 --- a/tests/expectations/parser/parser/functions/annotated_twice.leo.out +++ b/tests/expectations/parser/parser/functions/annotated_twice.leo.out @@ -6,6 +6,7 @@ outputs: expected_input: [] imports: [] circuits: {} + global_consts: {} functions: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":4,\\\"line_stop\\\":4,\\\"col_start\\\":10,\\\"col_stop\\\":11,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"function x() {\\\"}\"}": annotations: diff --git a/tests/expectations/parser/parser/functions/const_param.leo.out b/tests/expectations/parser/parser/functions/const_param.leo.out index 28916f76c8..609a83247f 100644 --- a/tests/expectations/parser/parser/functions/const_param.leo.out +++ b/tests/expectations/parser/parser/functions/const_param.leo.out @@ -6,6 +6,7 @@ outputs: expected_input: [] imports: [] circuits: {} + global_consts: {} functions: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":10,\\\"col_stop\\\":11,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"function x(x: u32, const y: i32) {\\\"}\"}": annotations: [] diff --git a/tests/expectations/parser/parser/functions/const_self_bad.leo.out b/tests/expectations/parser/parser/functions/const_self_bad.leo.out index 68248c8693..3b6e210cef 100644 --- a/tests/expectations/parser/parser/functions/const_self_bad.leo.out +++ b/tests/expectations/parser/parser/functions/const_self_bad.leo.out @@ -6,6 +6,7 @@ outputs: expected_input: [] imports: [] circuits: {} + global_consts: {} functions: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":10,\\\"col_stop\\\":11,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"function x(const self) {\\\"}\"}": annotations: [] diff --git a/tests/expectations/parser/parser/functions/empty.leo.out b/tests/expectations/parser/parser/functions/empty.leo.out index 03ff79d359..5ead848ab3 100644 --- a/tests/expectations/parser/parser/functions/empty.leo.out +++ b/tests/expectations/parser/parser/functions/empty.leo.out @@ -6,6 +6,7 @@ outputs: expected_input: [] imports: [] circuits: {} + global_consts: {} functions: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":10,\\\"col_stop\\\":11,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"function x() {\\\"}\"}": annotations: [] diff --git a/tests/expectations/parser/parser/functions/empty2.leo.out b/tests/expectations/parser/parser/functions/empty2.leo.out index ba7212db42..16574b1dc3 100644 --- a/tests/expectations/parser/parser/functions/empty2.leo.out +++ b/tests/expectations/parser/parser/functions/empty2.leo.out @@ -6,6 +6,7 @@ outputs: expected_input: [] imports: [] circuits: {} + global_consts: {} functions: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":10,\\\"col_stop\\\":11,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"function x() {}\\\"}\"}": annotations: [] diff --git a/tests/expectations/parser/parser/functions/param_array.leo.out b/tests/expectations/parser/parser/functions/param_array.leo.out index 6854e088a5..c9b3cc79cd 100644 --- a/tests/expectations/parser/parser/functions/param_array.leo.out +++ b/tests/expectations/parser/parser/functions/param_array.leo.out @@ -6,6 +6,7 @@ outputs: expected_input: [] imports: [] circuits: {} + global_consts: {} functions: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":10,\\\"col_stop\\\":11,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"function x(x: [u8; 12]) {\\\"}\"}": annotations: [] diff --git a/tests/expectations/parser/parser/functions/param_circuit.leo.out b/tests/expectations/parser/parser/functions/param_circuit.leo.out index a43143a6cb..e998fe7f92 100644 --- a/tests/expectations/parser/parser/functions/param_circuit.leo.out +++ b/tests/expectations/parser/parser/functions/param_circuit.leo.out @@ -6,6 +6,7 @@ outputs: expected_input: [] imports: [] circuits: {} + global_consts: {} functions: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":10,\\\"col_stop\\\":11,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"function x(x: MyCircuit) {\\\"}\"}": annotations: [] diff --git a/tests/expectations/parser/parser/functions/param_tuple.leo.out b/tests/expectations/parser/parser/functions/param_tuple.leo.out index 520d664450..9597b18cb3 100644 --- a/tests/expectations/parser/parser/functions/param_tuple.leo.out +++ b/tests/expectations/parser/parser/functions/param_tuple.leo.out @@ -6,6 +6,7 @@ outputs: expected_input: [] imports: [] circuits: {} + global_consts: {} functions: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":10,\\\"col_stop\\\":11,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"function x(x: (u32, i32)) {\\\"}\"}": annotations: [] diff --git a/tests/expectations/parser/parser/functions/params.leo.out b/tests/expectations/parser/parser/functions/params.leo.out index 6549ea1ca2..9c74dafafd 100644 --- a/tests/expectations/parser/parser/functions/params.leo.out +++ b/tests/expectations/parser/parser/functions/params.leo.out @@ -6,6 +6,7 @@ outputs: expected_input: [] imports: [] circuits: {} + global_consts: {} functions: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":10,\\\"col_stop\\\":11,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"function x(x: u32, y: i32) {\\\"}\"}": annotations: [] diff --git a/tests/expectations/parser/parser/functions/params_return.leo.out b/tests/expectations/parser/parser/functions/params_return.leo.out index 1ec8867568..6b1980e238 100644 --- a/tests/expectations/parser/parser/functions/params_return.leo.out +++ b/tests/expectations/parser/parser/functions/params_return.leo.out @@ -6,6 +6,7 @@ outputs: expected_input: [] imports: [] circuits: {} + global_consts: {} functions: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":10,\\\"col_stop\\\":11,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"function x(x: u32, y: i32) -> u32 {\\\"}\"}": annotations: [] diff --git a/tests/expectations/parser/parser/functions/return.leo.out b/tests/expectations/parser/parser/functions/return.leo.out index 0f87e02968..3baa2a2e79 100644 --- a/tests/expectations/parser/parser/functions/return.leo.out +++ b/tests/expectations/parser/parser/functions/return.leo.out @@ -6,6 +6,7 @@ outputs: expected_input: [] imports: [] circuits: {} + global_consts: {} functions: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":10,\\\"col_stop\\\":11,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"function x() -> u32 {\\\"}\"}": annotations: [] diff --git a/tests/expectations/parser/parser/functions/return_tuple.leo.out b/tests/expectations/parser/parser/functions/return_tuple.leo.out index 16b4bd1c45..aa853f04df 100644 --- a/tests/expectations/parser/parser/functions/return_tuple.leo.out +++ b/tests/expectations/parser/parser/functions/return_tuple.leo.out @@ -6,6 +6,7 @@ outputs: expected_input: [] imports: [] circuits: {} + global_consts: {} functions: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":3,\\\"line_stop\\\":3,\\\"col_start\\\":10,\\\"col_stop\\\":11,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"function x() -> (u32, u32) {\\\"}\"}": annotations: [] diff --git a/tests/expectations/parser/parser/import/alias.leo.out b/tests/expectations/parser/parser/import/alias.leo.out index 654fbcefc6..e0c181f3d7 100644 --- a/tests/expectations/parser/parser/import/alias.leo.out +++ b/tests/expectations/parser/parser/import/alias.leo.out @@ -34,4 +34,5 @@ outputs: path: test content: import a.b as bar; circuits: {} + global_consts: {} functions: {} diff --git a/tests/expectations/parser/parser/import/basic.leo.out b/tests/expectations/parser/parser/import/basic.leo.out index 6467c45999..7293ccb78e 100644 --- a/tests/expectations/parser/parser/import/basic.leo.out +++ b/tests/expectations/parser/parser/import/basic.leo.out @@ -34,4 +34,5 @@ outputs: path: test content: import a.b; circuits: {} + global_consts: {} functions: {} diff --git a/tests/expectations/parser/parser/import/many_import.leo.out b/tests/expectations/parser/parser/import/many_import.leo.out index 27e4abedd1..c8bf9349c8 100644 --- a/tests/expectations/parser/parser/import/many_import.leo.out +++ b/tests/expectations/parser/parser/import/many_import.leo.out @@ -132,4 +132,5 @@ outputs: path: test content: "import bar.( // imports directory import\n...\n bat.bat.Bat," circuits: {} + global_consts: {} functions: {} diff --git a/tests/expectations/parser/parser/import/many_import_star.leo.out b/tests/expectations/parser/parser/import/many_import_star.leo.out index d72655988c..9a04d35a1c 100644 --- a/tests/expectations/parser/parser/import/many_import_star.leo.out +++ b/tests/expectations/parser/parser/import/many_import_star.leo.out @@ -161,4 +161,5 @@ outputs: path: test content: import car.*; // imports directory import circuits: {} + global_consts: {} functions: {} diff --git a/tests/expectations/parser/parser/import/names.leo.out b/tests/expectations/parser/parser/import/names.leo.out index 0ea33ddad3..9bc9319577 100644 --- a/tests/expectations/parser/parser/import/names.leo.out +++ b/tests/expectations/parser/parser/import/names.leo.out @@ -90,4 +90,5 @@ outputs: path: test content: import hello-world.hello; circuits: {} + global_consts: {} functions: {} diff --git a/tests/expectations/parser/parser/import/names_underscore.leo.out b/tests/expectations/parser/parser/import/names_underscore.leo.out index 1dcd68015c..952c5c0ac7 100644 --- a/tests/expectations/parser/parser/import/names_underscore.leo.out +++ b/tests/expectations/parser/parser/import/names_underscore.leo.out @@ -34,4 +34,5 @@ outputs: path: test content: import hello_world.foo; circuits: {} + global_consts: {} functions: {} diff --git a/tests/expectations/parser/parser/import/star.leo.out b/tests/expectations/parser/parser/import/star.leo.out index 59d6e5c5b9..5bdc771258 100644 --- a/tests/expectations/parser/parser/import/star.leo.out +++ b/tests/expectations/parser/parser/import/star.leo.out @@ -31,4 +31,5 @@ outputs: path: test content: import test-import.*; circuits: {} + global_consts: {} functions: {} diff --git a/tests/parser/circuits/field_and_functions.leo b/tests/parser/circuits/field_and_functions.leo index 01f4d3e636..51d09324ec 100644 --- a/tests/parser/circuits/field_and_functions.leo +++ b/tests/parser/circuits/field_and_functions.leo @@ -5,7 +5,7 @@ expectation: Pass circuit X { x: u32, - y: u32, + y: u32 function x() { return (); } diff --git a/tests/parser/circuits/fields.leo b/tests/parser/circuits/fields.leo index 34c7f5cf8f..19f8ee214b 100644 --- a/tests/parser/circuits/fields.leo +++ b/tests/parser/circuits/fields.leo @@ -4,6 +4,6 @@ expectation: Pass */ circuit X { - x: u32, - y: u32, + x: u32; + y: u32 } \ No newline at end of file diff --git a/tests/parser/circuits/fields_fail.leo b/tests/parser/circuits/fields_fail.leo new file mode 100644 index 0000000000..3d357f412d --- /dev/null +++ b/tests/parser/circuits/fields_fail.leo @@ -0,0 +1,9 @@ +/* +namespace: Parse +expectation: Fail +*/ + +circuit X { + x: u32 + y: u32 +} \ No newline at end of file From c8f1d9913cd95ab68f63db312f51bebea840bb81 Mon Sep 17 00:00:00 2001 From: gluax Date: Fri, 30 Apr 2021 12:07:35 -0400 Subject: [PATCH 04/24] rename grammar rule as suggested --- grammar/README.md | 62 ++++++++++++++++++++-------------------- grammar/abnf-grammar.txt | 4 +-- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/grammar/README.md b/grammar/README.md index 20ba80c890..d6cb39c588 100644 --- a/grammar/README.md +++ b/grammar/README.md @@ -476,7 +476,7 @@ Line terminators form whitespace, along with spaces and horizontal tabs. whitespace = space / horizontal-tab / newline ``` -Go to: _[newline](#user-content-newline), [horizontal-tab](#user-content-horizontal-tab), [space](#user-content-space)_; +Go to: _[newline](#user-content-newline), [space](#user-content-space), [horizontal-tab](#user-content-horizontal-tab)_; There are two kinds of comments in Leo, as in other languages. @@ -494,7 +494,7 @@ the ones used in the Java language reference. comment = block-comment / end-of-line-comment ``` -Go to: _[block-comment](#user-content-block-comment), [end-of-line-comment](#user-content-end-of-line-comment)_; +Go to: _[end-of-line-comment](#user-content-end-of-line-comment), [block-comment](#user-content-block-comment)_; @@ -596,7 +596,7 @@ lowercase-letter = %x61-7A ; a-z letter = uppercase-letter / lowercase-letter ``` -Go to: _[lowercase-letter](#user-content-lowercase-letter), [uppercase-letter](#user-content-uppercase-letter)_; +Go to: _[uppercase-letter](#user-content-uppercase-letter), [lowercase-letter](#user-content-lowercase-letter)_; An identifier is a non-empty sequence of letters, digits, and underscores, @@ -764,7 +764,7 @@ atomic-literal = untyped-literal / address-literal ``` -Go to: _[product-group-literal](#user-content-product-group-literal), [signed-literal](#user-content-signed-literal), [field-literal](#user-content-field-literal), [address-literal](#user-content-address-literal), [boolean-literal](#user-content-boolean-literal), [untyped-literal](#user-content-untyped-literal), [unsigned-literal](#user-content-unsigned-literal)_; +Go to: _[address-literal](#user-content-address-literal), [untyped-literal](#user-content-untyped-literal), [unsigned-literal](#user-content-unsigned-literal), [signed-literal](#user-content-signed-literal), [field-literal](#user-content-field-literal), [boolean-literal](#user-content-boolean-literal), [product-group-literal](#user-content-product-group-literal)_; After defining the (mostly) alphanumeric tokens above, @@ -809,7 +809,7 @@ token = keyword / symbol ``` -Go to: _[symbol](#user-content-symbol), [package-name](#user-content-package-name), [format-string](#user-content-format-string), [annotation-name](#user-content-annotation-name), [identifier](#user-content-identifier), [keyword](#user-content-keyword), [atomic-literal](#user-content-atomic-literal)_; +Go to: _[format-string](#user-content-format-string), [annotation-name](#user-content-annotation-name), [symbol](#user-content-symbol), [keyword](#user-content-keyword), [atomic-literal](#user-content-atomic-literal), [package-name](#user-content-package-name), [identifier](#user-content-identifier)_; @@ -866,7 +866,7 @@ group-type = %s"group" arithmetic-type = integer-type / field-type / group-type ``` -Go to: _[group-type](#user-content-group-type), [integer-type](#user-content-integer-type), [field-type](#user-content-field-type)_; +Go to: _[field-type](#user-content-field-type), [integer-type](#user-content-integer-type), [group-type](#user-content-group-type)_; The arithmetic types, along with the boolean and address types, @@ -887,7 +887,7 @@ address-type = %s"address" scalar-type = boolean-type / arithmetic-type / address-type ``` -Go to: _[boolean-type](#user-content-boolean-type), [arithmetic-type](#user-content-arithmetic-type), [address-type](#user-content-address-type)_; +Go to: _[arithmetic-type](#user-content-arithmetic-type), [boolean-type](#user-content-boolean-type), [address-type](#user-content-address-type)_; Circuit types are denoted by identifiers and the keyword `Self`. @@ -904,7 +904,7 @@ self-type = %s"Self" circuit-type = identifier / self-type ``` -Go to: _[identifier](#user-content-identifier), [self-type](#user-content-self-type)_; +Go to: _[self-type](#user-content-self-type), [identifier](#user-content-identifier)_; A tuple type consists of zero, two, or more component types. @@ -948,7 +948,7 @@ i.e. types whose values contain (sub-)values aggregate-type = tuple-type / array-type / circuit-type ``` -Go to: _[array-type](#user-content-array-type), [tuple-type](#user-content-tuple-type), [circuit-type](#user-content-circuit-type)_; +Go to: _[tuple-type](#user-content-tuple-type), [circuit-type](#user-content-circuit-type), [array-type](#user-content-array-type)_; Scalar and aggregate types form all the types. @@ -958,7 +958,7 @@ Scalar and aggregate types form all the types. type = scalar-type / aggregate-type ``` -Go to: _[aggregate-type](#user-content-aggregate-type), [scalar-type](#user-content-scalar-type)_; +Go to: _[scalar-type](#user-content-scalar-type), [aggregate-type](#user-content-aggregate-type)_; The lexical grammar given earlier defines product group literals. @@ -994,7 +994,7 @@ A literal is either an atomic one or an affine group literal. literal = atomic-literal / affine-group-literal ``` -Go to: _[affine-group-literal](#user-content-affine-group-literal), [atomic-literal](#user-content-atomic-literal)_; +Go to: _[atomic-literal](#user-content-atomic-literal), [affine-group-literal](#user-content-affine-group-literal)_; The following rule is not directly referenced in the rules for expressions @@ -1036,7 +1036,7 @@ primary-expression = identifier / circuit-expression ``` -Go to: _[literal](#user-content-literal), [expression](#user-content-expression), [tuple-expression](#user-content-tuple-expression), [identifier](#user-content-identifier), [array-expression](#user-content-array-expression), [circuit-expression](#user-content-circuit-expression)_; +Go to: _[tuple-expression](#user-content-tuple-expression), [expression](#user-content-expression), [array-expression](#user-content-array-expression), [circuit-expression](#user-content-circuit-expression), [literal](#user-content-literal), [identifier](#user-content-identifier)_; Tuple expressions construct tuples. @@ -1089,7 +1089,7 @@ Go to: _[expression](#user-content-expression)_; array-repeat-construction = "[" expression ";" array-dimensions "]" ``` -Go to: _[array-dimensions](#user-content-array-dimensions), [expression](#user-content-expression)_; +Go to: _[expression](#user-content-expression), [array-dimensions](#user-content-array-dimensions)_; @@ -1133,7 +1133,7 @@ Go to: _[circuit-type](#user-content-circuit-type), [circuit-inline-element](#us circuit-inline-element = identifier ":" expression / identifier ``` -Go to: _[identifier](#user-content-identifier), [expression](#user-content-expression)_; +Go to: _[expression](#user-content-expression), [identifier](#user-content-identifier)_; @@ -1184,7 +1184,7 @@ postfix-expression = primary-expression / postfix-expression "[" [expression] ".." [expression] "]" ``` -Go to: _[identifier](#user-content-identifier), [expression](#user-content-expression), [primary-expression](#user-content-primary-expression), [function-arguments](#user-content-function-arguments), [natural](#user-content-natural), [postfix-expression](#user-content-postfix-expression), [circuit-type](#user-content-circuit-type)_; +Go to: _[natural](#user-content-natural), [function-arguments](#user-content-function-arguments), [postfix-expression](#user-content-postfix-expression), [circuit-type](#user-content-circuit-type), [identifier](#user-content-identifier), [expression](#user-content-expression), [primary-expression](#user-content-primary-expression)_; Unary operators have the highest operator precedence. @@ -1212,7 +1212,7 @@ exponential-expression = unary-expression / unary-expression "**" exponential-expression ``` -Go to: _[exponential-expression](#user-content-exponential-expression), [unary-expression](#user-content-unary-expression)_; +Go to: _[unary-expression](#user-content-unary-expression), [exponential-expression](#user-content-exponential-expression)_; Next in precedence come multiplication and division, both left-associative. @@ -1236,7 +1236,7 @@ additive-expression = multiplicative-expression / additive-expression "-" multiplicative-expression ``` -Go to: _[multiplicative-expression](#user-content-multiplicative-expression), [additive-expression](#user-content-additive-expression)_; +Go to: _[additive-expression](#user-content-additive-expression), [multiplicative-expression](#user-content-multiplicative-expression)_; Next in the precedence order are ordering relations. @@ -1299,7 +1299,7 @@ conditional-expression = disjunctive-expression ":" conditional-expression ``` -Go to: _[disjunctive-expression](#user-content-disjunctive-expression), [conditional-expression](#user-content-conditional-expression), [expression](#user-content-expression)_; +Go to: _[expression](#user-content-expression), [disjunctive-expression](#user-content-disjunctive-expression), [conditional-expression](#user-content-conditional-expression)_; Those above are all the expressions. @@ -1332,7 +1332,7 @@ statement = expression-statement / block ``` -Go to: _[expression-statement](#user-content-expression-statement), [console-statement](#user-content-console-statement), [return-statement](#user-content-return-statement), [variable-declaration](#user-content-variable-declaration), [loop-statement](#user-content-loop-statement), [constant-declaration](#user-content-constant-declaration), [assignment-statement](#user-content-assignment-statement), [conditional-statement](#user-content-conditional-statement), [block](#user-content-block)_; +Go to: _[conditional-statement](#user-content-conditional-statement), [console-statement](#user-content-console-statement), [variable-declaration](#user-content-variable-declaration), [expression-statement](#user-content-expression-statement), [assignment-statement](#user-content-assignment-statement), [block](#user-content-block), [loop-statement](#user-content-loop-statement), [return-statement](#user-content-return-statement), [constant-declaration](#user-content-constant-declaration)_; @@ -1373,7 +1373,7 @@ variable-declaration = %s"let" identifier-or-identifiers [ ":" type ] "=" expres constant-declaration = %s"const" identifier-or-identifiers [ ":" type ] "=" expression ";" ``` -Go to: _[expression](#user-content-expression), [identifier-or-identifiers](#user-content-identifier-or-identifiers), [type](#user-content-type)_; +Go to: _[type](#user-content-type), [expression](#user-content-expression), [identifier-or-identifiers](#user-content-identifier-or-identifiers)_; @@ -1397,7 +1397,7 @@ Note that blocks are required in all branches, not merely statements. branch = %s"if" expression block ``` -Go to: _[block](#user-content-block), [expression](#user-content-expression)_; +Go to: _[expression](#user-content-expression), [block](#user-content-block)_; @@ -1407,7 +1407,7 @@ conditional-statement = branch / branch %s"else" conditional-statement ``` -Go to: _[branch](#user-content-branch), [block](#user-content-block), [conditional-statement](#user-content-conditional-statement)_; +Go to: _[conditional-statement](#user-content-conditional-statement), [branch](#user-content-branch), [block](#user-content-block)_; A loop statement implicitly defines a loop variable @@ -1419,7 +1419,7 @@ The body is a block. loop-statement = %s"for" identifier %s"in" expression ".." expression block ``` -Go to: _[block](#user-content-block), [identifier](#user-content-identifier), [expression](#user-content-expression)_; +Go to: _[identifier](#user-content-identifier), [expression](#user-content-expression), [block](#user-content-block)_; An assignment statement is straightforward. @@ -1436,7 +1436,7 @@ assignment-operator = "=" / "+=" / "-=" / "*=" / "/=" / "**=" assignment-statement = expression assignment-operator expression ";" ``` -Go to: _[assignment-operator](#user-content-assignment-operator), [expression](#user-content-expression)_; +Go to: _[expression](#user-content-expression), [assignment-operator](#user-content-assignment-operator)_; Console statements start with the `console` keyword, @@ -1522,7 +1522,7 @@ function-declaration = *annotation %s"function" identifier block ``` -Go to: _[function-parameters](#user-content-function-parameters), [type](#user-content-type), [block](#user-content-block), [identifier](#user-content-identifier)_; +Go to: _[function-parameters](#user-content-function-parameters), [type](#user-content-type), [identifier](#user-content-identifier), [block](#user-content-block)_; @@ -1559,9 +1559,9 @@ Go to: _[identifier](#user-content-identifier), [type](#user-content-type)_; A circuit member variable declaration consists of an identifier and a type. A circuit member function declaration consists of a function declaration. - + ```abnf -member-variable-declaration = *(identifier ":" type ( "," / ";" )) identifier ":" type ( [ "," ] / ";" ) +member-variable-declarations = *(identifier ":" type ( "," / ";" )) identifier ":" type ( [ "," ] / ";" ) ``` Go to: _[identifier](#user-content-identifier), [type](#user-content-type)_; @@ -1581,10 +1581,10 @@ as consisting of member variables and functions. ```abnf circuit-declaration = *annotation %s"circuit" identifier - "{" [ member-variable-declaration ] *member-function-declaration "}" + "{" [ member-variable-declarations ] *member-function-declaration "}" ``` -Go to: _[identifier](#user-content-identifier), [member-variable-declaration](#user-content-member-variable-declaration)_; +Go to: _[member-variable-declarations](#user-content-member-variable-declarations), [identifier](#user-content-identifier)_; An import declaration consists of the `import` keyword @@ -1613,7 +1613,7 @@ package-path = "*" / "(" package-path *( "," package-path ) [","] ")" ``` -Go to: _[identifier](#user-content-identifier), [package-name](#user-content-package-name), [package-path](#user-content-package-path)_; +Go to: _[identifier](#user-content-identifier), [package-path](#user-content-package-path), [package-name](#user-content-package-name)_; Finally, we define a file as a sequence of zero or more declarations. @@ -1626,7 +1626,7 @@ declaration = import-declaration / constant-declaration ``` -Go to: _[import-declaration](#user-content-import-declaration), [function-declaration](#user-content-function-declaration), [constant-declaration](#user-content-constant-declaration), [circuit-declaration](#user-content-circuit-declaration)_; +Go to: _[circuit-declaration](#user-content-circuit-declaration), [constant-declaration](#user-content-constant-declaration), [import-declaration](#user-content-import-declaration), [function-declaration](#user-content-function-declaration)_; diff --git a/grammar/abnf-grammar.txt b/grammar/abnf-grammar.txt index 4388a549f7..8bcf93399e 100644 --- a/grammar/abnf-grammar.txt +++ b/grammar/abnf-grammar.txt @@ -938,7 +938,7 @@ function-input = [ %s"const" ] identifier ":" type ; A circuit member variable declaration consists of an identifier and a type. ; A circuit member function declaration consists of a function declaration. -member-variable-declaration = *(identifier ":" type ( "," / ";" )) identifier ":" type ( [ "," ] / ";" ) +member-variable-declarations = *(identifier ":" type ( "," / ";" )) identifier ":" type ( [ "," ] / ";" ) member-function-declaration = function-declaration @@ -946,7 +946,7 @@ member-function-declaration = function-declaration ; as consisting of member variables and functions. circuit-declaration = *annotation %s"circuit" identifier - "{" [ member-variable-declaration ] *member-function-declaration "}" + "{" [ member-variable-declarations ] *member-function-declaration "}" ; An import declaration consists of the `import` keyword ; followed by a package path, which may be one of the following: From f5b494477e3a9d8f1864d0ee96506e3d5e9c0991 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 3 May 2021 10:23:28 +0000 Subject: [PATCH 05/24] Bump tracing from 0.1.25 to 0.1.26 Bumps [tracing](https://github.com/tokio-rs/tracing) from 0.1.25 to 0.1.26. - [Release notes](https://github.com/tokio-rs/tracing/releases) - [Commits](https://github.com/tokio-rs/tracing/compare/tracing-0.1.25...tracing-0.1.26) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6d5aed8919..e132c55cde 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3131,9 +3131,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" [[package]] name = "tracing" -version = "0.1.25" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f" +checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" dependencies = [ "cfg-if 1.0.0", "pin-project-lite", @@ -3154,9 +3154,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f" +checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052" dependencies = [ "lazy_static", ] From 9418278736fce941f20c3f6349678f455cc8dc83 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 3 May 2021 10:23:51 +0000 Subject: [PATCH 06/24] Bump tracing-subscriber from 0.2.17 to 0.2.18 Bumps [tracing-subscriber](https://github.com/tokio-rs/tracing) from 0.2.17 to 0.2.18. - [Release notes](https://github.com/tokio-rs/tracing/releases) - [Commits](https://github.com/tokio-rs/tracing/compare/tracing-subscriber-0.2.17...tracing-subscriber-0.2.18) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6d5aed8919..107a0e0ac2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3194,9 +3194,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "705096c6f83bf68ea5d357a6aa01829ddbdac531b357b45abeca842938085baa" +checksum = "aa5553bf0883ba7c9cbe493b085c29926bd41b66afc31ff72cf17ff4fb60dcd5" dependencies = [ "ansi_term 0.12.1", "chrono", From 5587d8dd8dc5eacd7086d553c61a95ab3c470229 Mon Sep 17 00:00:00 2001 From: gluax Date: Wed, 5 May 2021 14:53:46 -0400 Subject: [PATCH 07/24] don't allow mixing of semi-colons and commas --- parser/src/errors/syntax.rs | 7 +++++ parser/src/parser/file.rs | 29 +++++++++++++------ .../parser/parser/circuits/fields.leo.out | 2 +- .../parser/circuits/fields_fail.leo.out | 2 +- tests/parser/circuits/fields.leo | 2 +- tests/parser/circuits/fields_fail.leo | 5 ++++ 6 files changed, 35 insertions(+), 12 deletions(-) diff --git a/parser/src/errors/syntax.rs b/parser/src/errors/syntax.rs index a5850ee9b5..24071708a4 100644 --- a/parser/src/errors/syntax.rs +++ b/parser/src/errors/syntax.rs @@ -74,6 +74,13 @@ impl SyntaxError { ) } + pub fn mixed_commas_and_semicolons(span: &Span) -> Self { + Self::new_from_span( + "Cannot mix use of commas and semi-colons for circuit member variable declarations.".to_string(), + span, + ) + } + pub fn unexpected_ident(got: &str, expected: &[&str], span: &Span) -> Self { Self::new_from_span( format!( diff --git a/parser/src/parser/file.rs b/parser/src/parser/file.rs index 4585a7981a..193df2b3b0 100644 --- a/parser/src/parser/file.rs +++ b/parser/src/parser/file.rs @@ -284,21 +284,32 @@ impl ParserContext { let mut members = Vec::new(); let peeked = &self.peek()?.token; let mut last_variable = peeked == &Token::Function || peeked == &Token::At; + let (mut semi_colons, mut commas) = (false, false); while self.eat(Token::RightCurly).is_none() { if !last_variable { let (variable, last) = self.parse_member_variable_declaration()?; + members.push(variable); - if !last { - self.expect_oneof(&[Token::Comma, Token::Semicolon])?; - } else { - last_variable = last; - let peeked = &self.peek()?.token; - if peeked == &Token::Semicolon { - self.expect(Token::Semicolon)?; - } else { - self.eat(Token::Comma); + let peeked = &self.peek()?; + if &peeked.token == &Token::Semicolon { + if commas { + return Err(SyntaxError::mixed_commas_and_semicolons(&peeked.span)); } + + semi_colons = true; + self.expect(Token::Semicolon)?; + } else { + if semi_colons { + return Err(SyntaxError::mixed_commas_and_semicolons(&peeked.span)); + } + + commas = true; + self.eat(Token::Comma); + } + + if last { + last_variable = last; } } else { let function = self.parse_member_function_declaration()?; diff --git a/tests/expectations/parser/parser/circuits/fields.leo.out b/tests/expectations/parser/parser/circuits/fields.leo.out index 2292d44b23..041cc13554 100644 --- a/tests/expectations/parser/parser/circuits/fields.leo.out +++ b/tests/expectations/parser/parser/circuits/fields.leo.out @@ -13,7 +13,7 @@ outputs: - "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":4,\\\"line_stop\\\":4,\\\"col_start\\\":5,\\\"col_stop\\\":6,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\" x: u32;\\\"}\"}" - IntegerType: U32 - CircuitVariable: - - "{\"name\":\"y\",\"span\":\"{\\\"line_start\\\":5,\\\"line_stop\\\":5,\\\"col_start\\\":5,\\\"col_stop\\\":6,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\" y: u32\\\"}\"}" + - "{\"name\":\"y\",\"span\":\"{\\\"line_start\\\":5,\\\"line_stop\\\":5,\\\"col_start\\\":5,\\\"col_stop\\\":6,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\" y: u32;\\\"}\"}" - IntegerType: U32 global_consts: {} functions: {} diff --git a/tests/expectations/parser/parser/circuits/fields_fail.leo.out b/tests/expectations/parser/parser/circuits/fields_fail.leo.out index c43ce7b104..006159e9d5 100644 --- a/tests/expectations/parser/parser/circuits/fields_fail.leo.out +++ b/tests/expectations/parser/parser/circuits/fields_fail.leo.out @@ -2,4 +2,4 @@ namespace: Parse expectation: Fail outputs: - - " --> test:5:5\n |\n 5 | y: u32\n | ^\n |\n = expected ',', ';' -- got 'y'" + - " --> test:10:11\n |\n 10 | y: u32;\n | ^\n |\n = Cannot mix use of commas and semi-colons for circuit member variable declarations." diff --git a/tests/parser/circuits/fields.leo b/tests/parser/circuits/fields.leo index 19f8ee214b..1369166472 100644 --- a/tests/parser/circuits/fields.leo +++ b/tests/parser/circuits/fields.leo @@ -5,5 +5,5 @@ expectation: Pass circuit X { x: u32; - y: u32 + y: u32; } \ No newline at end of file diff --git a/tests/parser/circuits/fields_fail.leo b/tests/parser/circuits/fields_fail.leo index 3d357f412d..a56bdb1a6e 100644 --- a/tests/parser/circuits/fields_fail.leo +++ b/tests/parser/circuits/fields_fail.leo @@ -6,4 +6,9 @@ expectation: Fail circuit X { x: u32 y: u32 +} + +circuit X { + x: u32, + y: u32; } \ No newline at end of file From c063200d44cb261a6ab2f44528298ee95c476182 Mon Sep 17 00:00:00 2001 From: gluax Date: Wed, 5 May 2021 14:57:48 -0400 Subject: [PATCH 08/24] clippy fix --- parser/src/parser/file.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parser/src/parser/file.rs b/parser/src/parser/file.rs index 193df2b3b0..a9c460d9bb 100644 --- a/parser/src/parser/file.rs +++ b/parser/src/parser/file.rs @@ -292,7 +292,7 @@ impl ParserContext { members.push(variable); let peeked = &self.peek()?; - if &peeked.token == &Token::Semicolon { + if peeked.token == Token::Semicolon { if commas { return Err(SyntaxError::mixed_commas_and_semicolons(&peeked.span)); } From 29ca0d9a1249b0520c63764e82f83baecae713d5 Mon Sep 17 00:00:00 2001 From: gluax Date: Wed, 5 May 2021 16:10:51 -0400 Subject: [PATCH 09/24] no empty import lists, star is a span, grammar fix --- asg/src/program/mod.rs | 4 +- ast/src/imports/package_access.rs | 8 ++-- grammar/README.md | 64 +++++++++++++++---------------- grammar/abnf-grammar.txt | 2 +- parser/src/errors/syntax.rs | 4 ++ parser/src/parser/file.rs | 11 ++++-- 6 files changed, 51 insertions(+), 42 deletions(-) diff --git a/asg/src/program/mod.rs b/asg/src/program/mod.rs index ebeb75eb7c..d6c00ef7e3 100644 --- a/asg/src/program/mod.rs +++ b/asg/src/program/mod.rs @@ -105,7 +105,7 @@ fn resolve_import_package_access( package: &PackageAccess, ) { match package { - PackageAccess::Star(span) => { + PackageAccess::Star { span } => { output.push((package_segments, ImportSymbol::All, span.clone())); } PackageAccess::SubPackage(subpackage) => { @@ -414,7 +414,7 @@ pub fn reform_ast<'a>(program: &Program<'a>) -> leo_ast::Program { .map(|(module, _)| leo_ast::ImportStatement { package_or_packages: leo_ast::PackageOrPackages::Package(leo_ast::Package { name: Identifier::new(module.clone().into()), - access: leo_ast::PackageAccess::Star(Span::default()), + access: leo_ast::PackageAccess::Star { span: Span::default() }, span: Default::default(), }), span: Span::default(), diff --git a/ast/src/imports/package_access.rs b/ast/src/imports/package_access.rs index 7245f900af..3935d71598 100644 --- a/ast/src/imports/package_access.rs +++ b/ast/src/imports/package_access.rs @@ -21,7 +21,7 @@ use std::fmt; #[derive(Clone, Eq, Hash, PartialEq, Serialize, Deserialize)] pub enum PackageAccess { - Star(Span), + Star { span: Span }, SubPackage(Box), Symbol(ImportSymbol), Multiple(Packages), @@ -30,7 +30,7 @@ pub enum PackageAccess { impl Node for PackageAccess { fn span(&self) -> &Span { match self { - PackageAccess::Star(span) => span, + PackageAccess::Star { span } => span, PackageAccess::SubPackage(package) => &package.span, PackageAccess::Symbol(package) => &package.span, PackageAccess::Multiple(package) => &package.span, @@ -39,7 +39,7 @@ impl Node for PackageAccess { fn set_span(&mut self, span: Span) { match self { - PackageAccess::Star(package) => *package = span, + PackageAccess::Star { span } => *span = span.clone(), PackageAccess::SubPackage(package) => package.span = span, PackageAccess::Symbol(package) => package.span = span, PackageAccess::Multiple(package) => package.span = span, @@ -50,7 +50,7 @@ impl Node for PackageAccess { impl PackageAccess { fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - PackageAccess::Star(ref _span) => write!(f, "*"), + PackageAccess::Star { .. } => write!(f, "*"), PackageAccess::SubPackage(ref package) => write!(f, "{}", package), PackageAccess::Symbol(ref symbol) => write!(f, "{}", symbol), PackageAccess::Multiple(ref packages) => { diff --git a/grammar/README.md b/grammar/README.md index b227bccb13..0829e1cd02 100644 --- a/grammar/README.md +++ b/grammar/README.md @@ -494,7 +494,7 @@ the ones used in the Java language reference. comment = block-comment / end-of-line-comment ``` -Go to: _[block-comment](#user-content-block-comment), [end-of-line-comment](#user-content-end-of-line-comment)_; +Go to: _[end-of-line-comment](#user-content-end-of-line-comment), [block-comment](#user-content-block-comment)_; @@ -511,7 +511,7 @@ rest-of-block-comment = "*" rest-of-block-comment-after-star / not-star rest-of-block-comment ``` -Go to: _[rest-of-block-comment](#user-content-rest-of-block-comment), [rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star), [not-star](#user-content-not-star)_; +Go to: _[rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star), [not-star](#user-content-not-star), [rest-of-block-comment](#user-content-rest-of-block-comment)_; @@ -521,7 +521,7 @@ rest-of-block-comment-after-star = "/" / not-star-or-slash rest-of-block-comment ``` -Go to: _[rest-of-block-comment](#user-content-rest-of-block-comment), [not-star-or-slash](#user-content-not-star-or-slash), [rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star)_; +Go to: _[not-star-or-slash](#user-content-not-star-or-slash), [rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star), [rest-of-block-comment](#user-content-rest-of-block-comment)_; @@ -596,7 +596,7 @@ lowercase-letter = %x61-7A ; a-z letter = uppercase-letter / lowercase-letter ``` -Go to: _[lowercase-letter](#user-content-lowercase-letter), [uppercase-letter](#user-content-uppercase-letter)_; +Go to: _[uppercase-letter](#user-content-uppercase-letter), [lowercase-letter](#user-content-lowercase-letter)_; An identifier is a non-empty sequence of letters, digits, and underscores, @@ -642,7 +642,7 @@ format-string-element = not-double-quote-or-open-brace / format-string-container ``` -Go to: _[format-string-container](#user-content-format-string-container), [not-double-quote-or-open-brace](#user-content-not-double-quote-or-open-brace), [not-double-quote-or-close-brace](#user-content-not-double-quote-or-close-brace)_; +Go to: _[not-double-quote-or-close-brace](#user-content-not-double-quote-or-close-brace), [format-string-container](#user-content-format-string-container), [not-double-quote-or-open-brace](#user-content-not-double-quote-or-open-brace)_; @@ -767,7 +767,7 @@ atomic-literal = untyped-literal / address-literal ``` -Go to: _[product-group-literal](#user-content-product-group-literal), [signed-literal](#user-content-signed-literal), [unsigned-literal](#user-content-unsigned-literal), [field-literal](#user-content-field-literal), [boolean-literal](#user-content-boolean-literal), [untyped-literal](#user-content-untyped-literal), [address-literal](#user-content-address-literal)_; +Go to: _[product-group-literal](#user-content-product-group-literal), [untyped-literal](#user-content-untyped-literal), [address-literal](#user-content-address-literal), [unsigned-literal](#user-content-unsigned-literal), [boolean-literal](#user-content-boolean-literal), [signed-literal](#user-content-signed-literal), [field-literal](#user-content-field-literal)_; After defining the (mostly) alphanumeric tokens above, @@ -812,7 +812,7 @@ token = keyword / symbol ``` -Go to: _[package-name](#user-content-package-name), [annotation-name](#user-content-annotation-name), [format-string](#user-content-format-string), [keyword](#user-content-keyword), [atomic-literal](#user-content-atomic-literal), [identifier](#user-content-identifier), [symbol](#user-content-symbol)_; +Go to: _[package-name](#user-content-package-name), [format-string](#user-content-format-string), [annotation-name](#user-content-annotation-name), [identifier](#user-content-identifier), [keyword](#user-content-keyword), [symbol](#user-content-symbol), [atomic-literal](#user-content-atomic-literal)_; @@ -869,7 +869,7 @@ group-type = %s"group" arithmetic-type = integer-type / field-type / group-type ``` -Go to: _[integer-type](#user-content-integer-type), [field-type](#user-content-field-type), [group-type](#user-content-group-type)_; +Go to: _[integer-type](#user-content-integer-type), [group-type](#user-content-group-type), [field-type](#user-content-field-type)_; The arithmetic types, along with the boolean and address types, @@ -890,7 +890,7 @@ address-type = %s"address" scalar-type = boolean-type / arithmetic-type / address-type ``` -Go to: _[arithmetic-type](#user-content-arithmetic-type), [address-type](#user-content-address-type), [boolean-type](#user-content-boolean-type)_; +Go to: _[address-type](#user-content-address-type), [arithmetic-type](#user-content-arithmetic-type), [boolean-type](#user-content-boolean-type)_; Circuit types are denoted by identifiers and the keyword `Self`. @@ -951,7 +951,7 @@ i.e. types whose values contain (sub-)values aggregate-type = tuple-type / array-type / circuit-type ``` -Go to: _[tuple-type](#user-content-tuple-type), [array-type](#user-content-array-type), [circuit-type](#user-content-circuit-type)_; +Go to: _[circuit-type](#user-content-circuit-type), [array-type](#user-content-array-type), [tuple-type](#user-content-tuple-type)_; Scalar and aggregate types form all the types. @@ -961,7 +961,7 @@ Scalar and aggregate types form all the types. type = scalar-type / aggregate-type ``` -Go to: _[aggregate-type](#user-content-aggregate-type), [scalar-type](#user-content-scalar-type)_; +Go to: _[scalar-type](#user-content-scalar-type), [aggregate-type](#user-content-aggregate-type)_; The lexical grammar given earlier defines product group literals. @@ -1039,7 +1039,7 @@ primary-expression = identifier / circuit-expression ``` -Go to: _[tuple-expression](#user-content-tuple-expression), [identifier](#user-content-identifier), [expression](#user-content-expression), [array-expression](#user-content-array-expression), [circuit-expression](#user-content-circuit-expression), [literal](#user-content-literal)_; +Go to: _[circuit-expression](#user-content-circuit-expression), [expression](#user-content-expression), [literal](#user-content-literal), [tuple-expression](#user-content-tuple-expression), [identifier](#user-content-identifier), [array-expression](#user-content-array-expression)_; Tuple expressions construct tuples. @@ -1100,7 +1100,7 @@ Go to: _[expression](#user-content-expression), [array-dimensions](#user-content array-construction = array-inline-construction / array-repeat-construction ``` -Go to: _[array-repeat-construction](#user-content-array-repeat-construction), [array-inline-construction](#user-content-array-inline-construction)_; +Go to: _[array-inline-construction](#user-content-array-inline-construction), [array-repeat-construction](#user-content-array-repeat-construction)_; @@ -1128,7 +1128,7 @@ circuit-construction = circuit-type "{" "}" ``` -Go to: _[circuit-inline-element](#user-content-circuit-inline-element), [circuit-type](#user-content-circuit-type)_; +Go to: _[circuit-type](#user-content-circuit-type), [circuit-inline-element](#user-content-circuit-inline-element)_; @@ -1136,7 +1136,7 @@ Go to: _[circuit-inline-element](#user-content-circuit-inline-element), [circuit circuit-inline-element = identifier ":" expression / identifier ``` -Go to: _[expression](#user-content-expression), [identifier](#user-content-identifier)_; +Go to: _[identifier](#user-content-identifier), [expression](#user-content-expression)_; @@ -1187,7 +1187,7 @@ postfix-expression = primary-expression / postfix-expression "[" [expression] ".." [expression] "]" ``` -Go to: _[function-arguments](#user-content-function-arguments), [postfix-expression](#user-content-postfix-expression), [natural](#user-content-natural), [circuit-type](#user-content-circuit-type), [expression](#user-content-expression), [identifier](#user-content-identifier), [primary-expression](#user-content-primary-expression)_; +Go to: _[natural](#user-content-natural), [circuit-type](#user-content-circuit-type), [function-arguments](#user-content-function-arguments), [primary-expression](#user-content-primary-expression), [postfix-expression](#user-content-postfix-expression), [identifier](#user-content-identifier), [expression](#user-content-expression)_; Unary operators have the highest operator precedence. @@ -1239,7 +1239,7 @@ additive-expression = multiplicative-expression / additive-expression "-" multiplicative-expression ``` -Go to: _[multiplicative-expression](#user-content-multiplicative-expression), [additive-expression](#user-content-additive-expression)_; +Go to: _[additive-expression](#user-content-additive-expression), [multiplicative-expression](#user-content-multiplicative-expression)_; Next in the precedence order are ordering relations. @@ -1302,7 +1302,7 @@ conditional-expression = disjunctive-expression ":" conditional-expression ``` -Go to: _[expression](#user-content-expression), [conditional-expression](#user-content-conditional-expression), [disjunctive-expression](#user-content-disjunctive-expression)_; +Go to: _[expression](#user-content-expression), [disjunctive-expression](#user-content-disjunctive-expression), [conditional-expression](#user-content-conditional-expression)_; Those above are all the expressions. @@ -1335,7 +1335,7 @@ statement = expression-statement / block ``` -Go to: _[expression-statement](#user-content-expression-statement), [return-statement](#user-content-return-statement), [assignment-statement](#user-content-assignment-statement), [block](#user-content-block), [loop-statement](#user-content-loop-statement), [constant-declaration](#user-content-constant-declaration), [conditional-statement](#user-content-conditional-statement), [console-statement](#user-content-console-statement), [variable-declaration](#user-content-variable-declaration)_; +Go to: _[return-statement](#user-content-return-statement), [block](#user-content-block), [expression-statement](#user-content-expression-statement), [assignment-statement](#user-content-assignment-statement), [constant-declaration](#user-content-constant-declaration), [conditional-statement](#user-content-conditional-statement), [console-statement](#user-content-console-statement), [variable-declaration](#user-content-variable-declaration), [loop-statement](#user-content-loop-statement)_; @@ -1378,7 +1378,7 @@ variable-declaration = %s"let" identifier-or-identifiers [ ":" type ] "=" expression ";" ``` -Go to: _[type](#user-content-type), [identifier-or-identifiers](#user-content-identifier-or-identifiers), [expression](#user-content-expression)_; +Go to: _[identifier-or-identifiers](#user-content-identifier-or-identifiers), [type](#user-content-type), [expression](#user-content-expression)_; @@ -1387,7 +1387,7 @@ constant-declaration = %s"const" identifier-or-identifiers [ ":" type ] "=" expression ";" ``` -Go to: _[expression](#user-content-expression), [type](#user-content-type), [identifier-or-identifiers](#user-content-identifier-or-identifiers)_; +Go to: _[type](#user-content-type), [expression](#user-content-expression), [identifier-or-identifiers](#user-content-identifier-or-identifiers)_; @@ -1420,7 +1420,7 @@ conditional-statement = branch / branch %s"else" conditional-statement ``` -Go to: _[block](#user-content-block), [branch](#user-content-branch), [conditional-statement](#user-content-conditional-statement)_; +Go to: _[conditional-statement](#user-content-conditional-statement), [block](#user-content-block), [branch](#user-content-branch)_; A loop statement implicitly defines a loop variable @@ -1476,7 +1476,7 @@ console-call = assert-call / print-call ``` -Go to: _[print-call](#user-content-print-call), [assert-call](#user-content-assert-call)_; +Go to: _[assert-call](#user-content-assert-call), [print-call](#user-content-print-call)_; @@ -1505,7 +1505,7 @@ Go to: _[format-string](#user-content-format-string)_; print-call = print-function print-arguments ``` -Go to: _[print-function](#user-content-print-function), [print-arguments](#user-content-print-arguments)_; +Go to: _[print-arguments](#user-content-print-arguments), [print-function](#user-content-print-function)_; An annotation consists of an annotation name (which starts with `@`) @@ -1518,7 +1518,7 @@ annotation = annotation-name [ "(" identifier *( "," identifier ) ")" ] ``` -Go to: _[annotation-name](#user-content-annotation-name), [identifier](#user-content-identifier)_; +Go to: _[identifier](#user-content-identifier), [annotation-name](#user-content-annotation-name)_; A function declaration defines a function. @@ -1566,7 +1566,7 @@ Go to: _[function-input](#user-content-function-input)_; function-input = [ %s"const" ] identifier ":" type ``` -Go to: _[type](#user-content-type), [identifier](#user-content-identifier)_; +Go to: _[identifier](#user-content-identifier), [type](#user-content-type)_; A circuit member variable declaration consists of an identifier and a type. @@ -1586,7 +1586,7 @@ Go to: _[member-function-declaration](#user-content-member-function-declaration) member-variable-declaration = identifier ":" type ``` -Go to: _[identifier](#user-content-identifier), [type](#user-content-type)_; +Go to: _[type](#user-content-type), [identifier](#user-content-identifier)_; @@ -1606,7 +1606,7 @@ circuit-declaration = *annotation %s"circuit" identifier "{" member-declaration *( "," member-declaration ) "}" ``` -Go to: _[identifier](#user-content-identifier), [member-declaration](#user-content-member-declaration)_; +Go to: _[member-declaration](#user-content-member-declaration), [identifier](#user-content-identifier)_; An import declaration consists of the `import` keyword @@ -1621,10 +1621,10 @@ to be followed by a comma, for convenience. ```abnf -import-declaration = %s"import" package-path ";" +import-declaration = %s"import" package-name "." package-path ";" ``` -Go to: _[package-path](#user-content-package-path)_; +Go to: _[package-name](#user-content-package-name), [package-path](#user-content-package-path)_; @@ -1635,7 +1635,7 @@ package-path = "*" / "(" package-path *( "," package-path ) [","] ")" ``` -Go to: _[identifier](#user-content-identifier), [package-path](#user-content-package-path), [package-name](#user-content-package-name)_; +Go to: _[identifier](#user-content-identifier), [package-name](#user-content-package-name), [package-path](#user-content-package-path)_; Finally, we define a file as a sequence of zero or more declarations. @@ -1650,7 +1650,7 @@ declaration = import-declaration / constant-declaration ``` -Go to: _[constant-declaration](#user-content-constant-declaration), [import-declaration](#user-content-import-declaration), [function-declaration](#user-content-function-declaration), [circuit-declaration](#user-content-circuit-declaration)_; +Go to: _[circuit-declaration](#user-content-circuit-declaration), [constant-declaration](#user-content-constant-declaration), [import-declaration](#user-content-import-declaration), [function-declaration](#user-content-function-declaration)_; diff --git a/grammar/abnf-grammar.txt b/grammar/abnf-grammar.txt index 6887198a54..f96b0632c3 100644 --- a/grammar/abnf-grammar.txt +++ b/grammar/abnf-grammar.txt @@ -968,7 +968,7 @@ circuit-declaration = *annotation %s"circuit" identifier ; Note that we allow the last element of the parenthesized list ; to be followed by a comma, for convenience. -import-declaration = %s"import" package-path ";" +import-declaration = %s"import" package-name "." package-path ";" package-path = "*" / identifier [ %s"as" identifier ] diff --git a/parser/src/errors/syntax.rs b/parser/src/errors/syntax.rs index a5850ee9b5..c3ed6db8cc 100644 --- a/parser/src/errors/syntax.rs +++ b/parser/src/errors/syntax.rs @@ -48,6 +48,10 @@ impl SyntaxError { SyntaxError::Error(FormattedError::new_from_span(message, span)) } + pub fn invalid_import_list(span: &Span) -> Self { + Self::new_from_span("Cannot import empty list".to_string(), span) + } + pub fn unexpected_eof(span: &Span) -> Self { Self::new_from_span("unexpected EOF".to_string(), span) } diff --git a/parser/src/parser/file.rs b/parser/src/parser/file.rs index 8dfdfc132a..66329bd1d8 100644 --- a/parser/src/parser/file.rs +++ b/parser/src/parser/file.rs @@ -136,7 +136,7 @@ impl ParserContext { /// Returns a vector of [`PackageAccess`] AST nodes if the next tokens represent package access /// expressions within an import statement. /// - pub fn parse_package_accesses(&mut self) -> SyntaxResult> { + pub fn parse_package_accesses(&mut self, span: &Span) -> SyntaxResult> { let mut out = Vec::new(); self.expect(Token::LeftParen)?; while self.eat(Token::RightParen).is_none() { @@ -147,6 +147,11 @@ impl ParserContext { break; } } + + if out.is_empty() { + return Err(SyntaxError::invalid_import_list(span)); + } + Ok(out) } @@ -156,7 +161,7 @@ impl ParserContext { /// pub fn parse_package_access(&mut self) -> SyntaxResult { if let Some(SpannedToken { span, .. }) = self.eat(Token::Mul) { - Ok(PackageAccess::Star(span)) + Ok(PackageAccess::Star { span }) } else { let name = self.expect_ident()?; if self.peek_token().as_ref() == &Token::Dot { @@ -247,7 +252,7 @@ impl ParserContext { let package_name = self.parse_package_name()?; self.expect(Token::Dot)?; if self.peek()?.token == Token::LeftParen { - let accesses = self.parse_package_accesses()?; + let accesses = self.parse_package_accesses(&package_name.span)?; Ok(PackageOrPackages::Packages(Packages { span: &package_name.span + accesses.last().map(|x| x.span()).unwrap_or(&package_name.span), name: package_name, From d88d57eb1c76b13432973fa27223d1347d73e98c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 6 May 2021 10:44:46 +0000 Subject: [PATCH 10/24] Bump sha2 from 0.9.3 to 0.9.4 Bumps [sha2](https://github.com/RustCrypto/hashes) from 0.9.3 to 0.9.4. - [Release notes](https://github.com/RustCrypto/hashes/releases) - [Commits](https://github.com/RustCrypto/hashes/compare/sha2-v0.9.3...sha2-v0.9.4) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6d5aed8919..31cb4c5aa7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -424,10 +424,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" [[package]] -name = "cpuid-bool" -version = "0.1.2" +name = "cpufeatures" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" +checksum = "5cd5a7748210e7ec1a9696610b1015e6e31fbf58f77a160801f124bd1c36592a" [[package]] name = "crc32fast" @@ -2611,13 +2611,13 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa827a14b29ab7f44778d14a88d3cb76e949c45083f7dbfa507d0cb699dc12de" +checksum = "d8f6b75b17576b792bef0db1bcc4b8b8bcdf9506744cf34b974195487af6cff2" dependencies = [ "block-buffer 0.9.0", "cfg-if 1.0.0", - "cpuid-bool", + "cpufeatures", "digest 0.9.0", "opaque-debug 0.3.0", ] From 6474f3f5ab962c9159426937799ad5e7ed18f28f Mon Sep 17 00:00:00 2001 From: damirka Date: Thu, 6 May 2021 15:28:45 +0300 Subject: [PATCH 11/24] adds 2 code samples to strings RFC --- docs/rfc/001-initial-strings.md | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/docs/rfc/001-initial-strings.md b/docs/rfc/001-initial-strings.md index a65ccbb13c..aa88429861 100644 --- a/docs/rfc/001-initial-strings.md +++ b/docs/rfc/001-initial-strings.md @@ -114,6 +114,25 @@ do we want to provide for `char` values?]_ - [ ] to_digit - Converts the `char` to the given `radix` format. +This code sample illustrates 3 ways of defining characters: character literal, escaped symbol +and unicode escapes as hex. + +```js +function main() -> [char; 5] { + + // using char literals to form an array + const world: [char; 5] = ['w', 'o', 'r', 'l', 'd']; + + // escaped characters + const escaped: [char; 4] = ['\n', '\t', '\\', '\'']; + + // unicode escapes - using emoji character 😊 + const smiling_face: char = '\u{1F60A}'; + + return [smiling_face, ...escaped]; +} +``` + ## Strings In this initial design proposal, we do not introduce any new type for strings. @@ -173,6 +192,23 @@ available with the existing array operations?]_ - [ ] clear - Empties the `string`. - [ ] _[TODO: more?]_ +Following code shows string literal and it's actual transformation into array of +characters as well as possible array-like operations on strings: concatenation and comparison. + +```js +function main() -> bool { + // double quotes create char array from string + let hello: [char; 5] = "hello"; + let world: [char; 5] = ['w','o','r','l','d']; + + // string concatenation can be performed using array syntax + let hello_world: [char; 11] = [...hello, ' ', ...world]; + + // string comparison is also implemented via array type + return hello_world == "hello world"; +} +``` + ## Input and Output of Literal Characters and Strings Since UTF-8 is a standard encoding, it would make sense for From 6f5655f95feb9ae4a2285d17b52cd366622b933d Mon Sep 17 00:00:00 2001 From: Alessandro Coglio Date: Thu, 6 May 2021 20:11:17 -0700 Subject: [PATCH 12/24] [RFC] Minor edits. Fix a few typos, improve some text, streamline some text. --- docs/rfc/001-initial-strings.md | 40 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/docs/rfc/001-initial-strings.md b/docs/rfc/001-initial-strings.md index aa88429861..44b3d00abd 100644 --- a/docs/rfc/001-initial-strings.md +++ b/docs/rfc/001-initial-strings.md @@ -28,7 +28,7 @@ that they should not limit the design of the future features. This proposal adds a new scalar type for characters along with a new kind of literals to denote characters. -A string is then simply as an array of characters, +A string is then simply an array of characters, but this proposal also adds a new kind of literals to denote strings more directly than via character array construction expressions. Along with equality and inequality, which always apply to every Leo type, @@ -54,10 +54,7 @@ _[TODO: Add more use cases if needed.]_ Since strings are sequences of characters, a design for strings inextricably also involves a design for characters. -Thus, we first present a design for characters, then for strings. -After that, we discuss the relation with Leo's existing format strings. -We conclude this design section -with a discussion of possible future extensions. +Thus, we first present a design for both characters and strings. ## Characters @@ -66,7 +63,7 @@ In accord with Leo's strong typing, this new type is separate from all the other scalar types. The set of values of type `char` is isomorphic to -the set of Unicode code points from 0 to 10FFFFh (both inclusive). +the set of Unicode code points from 0 to 10FFFF (both inclusive). That is, we support Unicode characters, more precisely code points (this may include some invalid code points, but it is simpler to allow every code point in that range). @@ -83,13 +80,13 @@ backslashes must be escaped as well, i.e. `'\\'` We allow other backslash escapes for commonly used characters that are not otherwise easily denoted, namely _[TODO: Decide which other escapes we want to allow, e.g. `'\n'`.]_ -* `\n` -* `\r` -* `\t` -* `\0` -* `\'` -* `\"` - +* `\n` for code point 10 (line feed) +* `\r` for code point 13 (carriage return) +* `\t` for core point 9 (horizontal tab) +* `\0` for code point 0 (the null character) +* `\'` for code point 39 (single quote) +* `\"` for code point 34 (double quote) + We also allow Unicode escapes of the form `'\u{X}'`, where `X` is a sequence of one to six hex digits (both uppercase and lowercase letters are allowed) @@ -113,9 +110,8 @@ do we want to provide for `char` values?]_ - [ ] is_whitespace - Returns `true` if the `char` has the `White_Space` property. - [ ] to_digit - Converts the `char` to the given `radix` format. - This code sample illustrates 3 ways of defining characters: character literal, escaped symbol -and unicode escapes as hex. +and Unicode escapes as hex. ```js function main() -> [char; 5] { @@ -192,8 +188,9 @@ available with the existing array operations?]_ - [ ] clear - Empties the `string`. - [ ] _[TODO: more?]_ -Following code shows string literal and it's actual transformation into array of -characters as well as possible array-like operations on strings: concatenation and comparison. +The following code shows a string literal and its actual transformation into an +array of characters as well as possible array-like operations on strings: +concatenation and comparison. ```js function main() -> bool { @@ -245,10 +242,10 @@ This section discusses R1CS compilation considerations for this proposal for characters and strings. Values of type `char` can be represented directly as field elements, -since the prime of the field is (much) larger than 10FFFFh. +since the prime of the field is (much) larger than 10FFFF. This is more efficient than using a bit representation of characters. By construction, field elements that represent `char` values -are never above 10FFFFh. +are never above 10FFFF. Note that `field` and `char` remain separate types in Leo: it is only in the compilation to R1CS that everything is reduced to field elements. @@ -295,17 +292,18 @@ But the need to support characters and strings justifies the extra complexity. With the ability of Leo programs to process strings, it may be useful to have external tools that convert Leo strings to/from common formats, e.g. UTF-8. +See the discussion of input files in the design section. # Alternatives We could avoid the new `char` type altogether, and instead, rely on the existing `u32` to represent Unicode code points, and provide character-oriented operations on `u32` values. -(Note that both `u8` and `u16` are too small for 10FFFFh, +(Note that both `u8` and `u16` are too small for 10FFFF, and that signed integer types include negative integers which are not Unicode code points: this makes `u32` the obvious choice.) -However, many values of type `u32` are above 10FFFFh, +However, many values of type `u32` are above 10FFFF, and many operations on `u32` do not really make sense on code points. We would probably want a notation for character literals anyhow, which could be (arguably mis)used for non-character unsigned integers. From 79fd36570227405cf68abe324375d502035137b6 Mon Sep 17 00:00:00 2001 From: Alessandro Coglio Date: Thu, 6 May 2021 20:19:14 -0700 Subject: [PATCH 13/24] [RFC] Add discussion of conversions with (arrays of) integers. --- docs/rfc/001-initial-strings.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/rfc/001-initial-strings.md b/docs/rfc/001-initial-strings.md index 44b3d00abd..f1fbdb60a6 100644 --- a/docs/rfc/001-initial-strings.md +++ b/docs/rfc/001-initial-strings.md @@ -110,6 +110,13 @@ do we want to provide for `char` values?]_ - [ ] is_whitespace - Returns `true` if the `char` has the `White_Space` property. - [ ] to_digit - Converts the `char` to the given `radix` format. +It seems fairly natural to convert between `char` values +and `u8` or `u16` or `u32` values, under suitable range conditions; +perhaps also between `char` values and +(non-negative) `i8` or `i16` or `i32` values. +This will be accomplished as part of the type casting extension of Leo. +_[TODO: are we okay with deferring these operations to type casting?]_ + This code sample illustrates 3 ways of defining characters: character literal, escaped symbol and Unicode escapes as hex. @@ -188,6 +195,13 @@ available with the existing array operations?]_ - [ ] clear - Empties the `string`. - [ ] _[TODO: more?]_ +Given the natural conversions between `char` values and integer values +discussed earlier, +it may be natural to also support element-wise conversions +between strings and arrays of integers. +This will be accomplished, if desired, +as part of the type casting extensions of Leo. + The following code shows a string literal and its actual transformation into an array of characters as well as possible array-like operations on strings: concatenation and comparison. From bda2dbf92d31db126c19d1da9fb513ae847189b6 Mon Sep 17 00:00:00 2001 From: Alessandro Coglio Date: Thu, 6 May 2021 20:25:03 -0700 Subject: [PATCH 14/24] [RFC] Add TODO about \x.. escapes. --- docs/rfc/001-initial-strings.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/rfc/001-initial-strings.md b/docs/rfc/001-initial-strings.md index f1fbdb60a6..2bdedeb4bf 100644 --- a/docs/rfc/001-initial-strings.md +++ b/docs/rfc/001-initial-strings.md @@ -98,6 +98,8 @@ _[TODO: Do we want a different notation for Unicode escapes? Note that the `{` `}` delimiters are motivated by the fact that there may be a varying number of hex digits in this notation.]_ This notation is supported by both Javascript and Rust. +_[TODO: Do we also want to support, as in Rust, escapes `\xXY` +where `X` is an octal digit and `Y` is a hex digit?]_ _[TODO: Which (initial) built-in or library operations do we want to provide for `char` values?]_ From fd42473b4a7f25be7dc02685c0539a26660ab23f Mon Sep 17 00:00:00 2001 From: Alessandro Coglio Date: Thu, 6 May 2021 20:31:21 -0700 Subject: [PATCH 15/24] [RFC] Add a couple more ops to consider. --- docs/rfc/001-initial-strings.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/rfc/001-initial-strings.md b/docs/rfc/001-initial-strings.md index 2bdedeb4bf..e6681492a1 100644 --- a/docs/rfc/001-initial-strings.md +++ b/docs/rfc/001-initial-strings.md @@ -111,6 +111,8 @@ do we want to provide for `char` values?]_ - [ ] is_uppercase - Returns `true` if the `char` has the `Uppercase` property. - [ ] is_whitespace - Returns `true` if the `char` has the `White_Space` property. - [ ] to_digit - Converts the `char` to the given `radix` format. +- [ ] to_uppercase - Converts lowercase to uppercase, leaving others unchanged. +- [ ] to_lowercaser - Converts uppercase to lowercase, leaving others unchanged. It seems fairly natural to convert between `char` values and `u8` or `u16` or `u32` values, under suitable range conditions; From 9c72b37d4d25ccdc0427a76ed2268148305c7dd4 Mon Sep 17 00:00:00 2001 From: Alessandro Coglio Date: Thu, 6 May 2021 21:03:13 -0700 Subject: [PATCH 16/24] [RFC] Add discussion of ordering operations. This is based on a Slack conversation with Pratyush. --- docs/rfc/001-initial-strings.md | 39 ++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/docs/rfc/001-initial-strings.md b/docs/rfc/001-initial-strings.md index e6681492a1..5439eb5b62 100644 --- a/docs/rfc/001-initial-strings.md +++ b/docs/rfc/001-initial-strings.md @@ -101,6 +101,13 @@ This notation is supported by both Javascript and Rust. _[TODO: Do we also want to support, as in Rust, escapes `\xXY` where `X` is an octal digit and `Y` is a hex digit?]_ +The equality operators `==` and `!=` are automatically available for `char`. +Given that characters are essentially code points, +it may be also natural to support +the ordering operators `<`, `<=`, `>`, and `>=`. +_[TODO: This is useful to check that a character is in a range, for instance. +Another approach is to use conversions to integers and compare the integers.]_ + _[TODO: Which (initial) built-in or library operations do we want to provide for `char` values?]_ - [ ] is_alphabetic - Returns `true` if the `char` has the `Alphabetic` property. @@ -111,8 +118,9 @@ do we want to provide for `char` values?]_ - [ ] is_uppercase - Returns `true` if the `char` has the `Uppercase` property. - [ ] is_whitespace - Returns `true` if the `char` has the `White_Space` property. - [ ] to_digit - Converts the `char` to the given `radix` format. +- [ ] from_digit - Inverse of to_digit. - [ ] to_uppercase - Converts lowercase to uppercase, leaving others unchanged. -- [ ] to_lowercaser - Converts uppercase to lowercase, leaving others unchanged. +- [ ] to_lowercase - Converts uppercase to lowercase, leaving others unchanged. It seems fairly natural to convert between `char` values and `u8` or `u16` or `u32` values, under suitable range conditions; @@ -277,6 +285,35 @@ applies to strings without exception. String literals are just syntactic sugar for suitable array inline construction expressions. +_[TODO: Here we probably need to discuss which R1CS gadgets we need +to compile the operations on characters and strings.]_ + +There are at least two approaches to implementing +ordering operations `<` and `<=` on `char` values. +Recalling that characters are represented as field values +that are (well) below `(p-1)/2` where `p` is the prime, +we can compare two field values `x` and `y`, +both below `(p-1)/2`, via the constraints +``` +(2) (x - y) = (b0 + 2*b1 + 4*b2 + ...) +(b0) (1 - b0) = 0 +(b1) (1 - b1) = 0 +(b2) (1 - b2) = 0 +... +``` +that take the different, double it, and convert to bits. +If `x >= y`, the difference is below `(p-1)/2`, +and doubling results in an even number below `p`, +with therefore `b0 = 0`. +If `x < y`, the difference is above `(p-1)/2` (when reduced modulo `p`), +and doubling results in an odd number when reduced modulo `p`, +with therefore `b0 = 1`. +Note that we need one variable and one constraint for every bit of `p`. +The other approach is to convert the `x` and `y` to bits +and compare them as integers; +in this case we only need 21 bits for each. +We need more analysis to determine which approach is more efficient. + ## Future Extensions As alluded to in the section about design above, From 554cc30c555ff1e99d0c3bdde9b97a32588265b3 Mon Sep 17 00:00:00 2001 From: Alessandro Coglio Date: Thu, 6 May 2021 21:08:44 -0700 Subject: [PATCH 17/24] [RFC] Make a TODO clearer. --- docs/rfc/001-initial-strings.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rfc/001-initial-strings.md b/docs/rfc/001-initial-strings.md index 5439eb5b62..377ac5ca19 100644 --- a/docs/rfc/001-initial-strings.md +++ b/docs/rfc/001-initial-strings.md @@ -285,7 +285,7 @@ applies to strings without exception. String literals are just syntactic sugar for suitable array inline construction expressions. -_[TODO: Here we probably need to discuss which R1CS gadgets we need +_[TODO: We need to discuss which SnarkVM gadgets we need to compile the operations on characters and strings.]_ There are at least two approaches to implementing From 50e6f93a44e03dea85b8c143818a95d98de285ca Mon Sep 17 00:00:00 2001 From: Alessandro Coglio Date: Fri, 7 May 2021 08:56:56 -0700 Subject: [PATCH 18/24] Fix typo found by Eric M. Also auto-remove trailing whitespace. --- docs/rfc/001-initial-strings.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/rfc/001-initial-strings.md b/docs/rfc/001-initial-strings.md index 377ac5ca19..ab319c5984 100644 --- a/docs/rfc/001-initial-strings.md +++ b/docs/rfc/001-initial-strings.md @@ -135,16 +135,16 @@ and Unicode escapes as hex. ```js function main() -> [char; 5] { - // using char literals to form an array + // using char literals to form an array const world: [char; 5] = ['w', 'o', 'r', 'l', 'd']; - + // escaped characters const escaped: [char; 4] = ['\n', '\t', '\\', '\'']; // unicode escapes - using emoji character 😊 const smiling_face: char = '\u{1F60A}'; - return [smiling_face, ...escaped]; + return [smiling_face, ...escaped]; } ``` @@ -221,7 +221,7 @@ concatenation and comparison. ```js function main() -> bool { // double quotes create char array from string - let hello: [char; 5] = "hello"; + let hello: [char; 5] = "hello"; let world: [char; 5] = ['w','o','r','l','d']; // string concatenation can be performed using array syntax @@ -240,8 +240,8 @@ to be automatically converted to UTF-32 by the Leo compiler. However, the size of a string can be confusing since multiple Unicode code points can be composed into a single glyph which then appears to be a single character. If a parameter of type `[char; 10]` -[if that is the syntax we decide on] is passed a literal string -of a different size, the error message should explain that the +[if that is the syntax we decide on] is passed a literal string +of a different size, the error message should explain that the size must be the number of codepoints needed to encode the string. ## Format Strings @@ -301,7 +301,7 @@ both below `(p-1)/2`, via the constraints (b2) (1 - b2) = 0 ... ``` -that take the different, double it, and convert to bits. +that take the difference, double it, and convert to bits. If `x >= y`, the difference is below `(p-1)/2`, and doubling results in an even number below `p`, with therefore `b0 = 0`. From bca2bfcf93b001940b606d6e19893202b2998578 Mon Sep 17 00:00:00 2001 From: Alessandro Coglio Date: Fri, 7 May 2021 16:26:54 -0700 Subject: [PATCH 19/24] [RFC] Update according to today's meeting. --- docs/rfc/001-initial-strings.md | 171 ++++++++++++++++++-------------- 1 file changed, 94 insertions(+), 77 deletions(-) diff --git a/docs/rfc/001-initial-strings.md b/docs/rfc/001-initial-strings.md index ab319c5984..7b810f99cf 100644 --- a/docs/rfc/001-initial-strings.md +++ b/docs/rfc/001-initial-strings.md @@ -21,20 +21,19 @@ DRAFT The purpose of this proposal is to provide initial support for strings in Leo. Since strings are sequences of characters, the proposal inextricably also involves characters. -This proposal is described as 'initial,' +This proposal is described as initial, because it provides some basic features that we may extend in the future; the initial features should be sufficiently simple and conservative that they should not limit the design of the future features. -This proposal adds a new scalar type for characters +This proposal adds a new scalar type for characters, along with a new kind of literals to denote characters. A string is then simply an array of characters, but this proposal also adds a new kind of literals to denote strings more directly than via character array construction expressions. Along with equality and inequality, which always apply to every Leo type, -this proposal also introduces operations for -_[TODO: Summarize initial set of built-in or library operations -on characters and strings.]_. +this proposal also introduces some operations on characters and strings +that can be implemented over time. By not prescribing a new type for strings, this initial proposal leaves the door open @@ -48,7 +47,6 @@ simple ones like URLs and token ticker symbols, and more complex ones like Bech32 encoding, edit distance in strings representing proteins, and zero-knowledge proofs of occurrences or absences of patterns in textual logs. -_[TODO: Add more use cases if needed.]_ # Design @@ -61,6 +59,8 @@ Thus, we first present a design for both characters and strings. We add a new scalar type, `char` for characters. In accord with Leo's strong typing, this new type is separate from all the other scalar types. +Type casts (a future feature of Leo) will be needed +to convert between `char` and other types. The set of values of type `char` is isomorphic to the set of Unicode code points from 0 to 10FFFF (both inclusive). @@ -78,59 +78,57 @@ e.g. `'a'`, `'*'`, and `'"'`. Single quotes must be escaped with a backslash, i.e. `'\''`; backslashes must be escaped as well, i.e. `'\\'` We allow other backslash escapes -for commonly used characters that are not otherwise easily denoted, -namely _[TODO: Decide which other escapes we want to allow, e.g. `'\n'`.]_ +for commonly used characters that are not otherwise easily denoted. +This is the complete list of single-character backslash escapes: +* `\'` for code point 39 (single quote) +* `\"` for code point 34 (double quote) +* `\\` for code point 92 (backslash) * `\n` for code point 10 (line feed) * `\r` for code point 13 (carriage return) * `\t` for core point 9 (horizontal tab) * `\0` for code point 0 (the null character) -* `\'` for code point 39 (single quote) -* `\"` for code point 34 (double quote) + +We also allow ASCII escapes of the form `\xOH`, +where `O` is an octal digit and `H` is a hexadecimal digit +(both uppercase and lowercase are allowed). +These represent ASCII code points, i.e. from 0 to 127 (both inclusive). We also allow Unicode escapes of the form `'\u{X}'`, where `X` is a sequence of one to six hex digits (both uppercase and lowercase letters are allowed) whose value must be between 0 and 10FFFF, inclusive. + Note that the literal character is assembled by the compiler---for creating literals, there is no need for the circuit to know -which codepoints are disallowed. -_[TODO: Do we want a different notation for Unicode escapes? -Note that the `{` `}` delimiters are motivated by the fact that -there may be a varying number of hex digits in this notation.]_ -This notation is supported by both Javascript and Rust. -_[TODO: Do we also want to support, as in Rust, escapes `\xXY` -where `X` is an octal digit and `Y` is a hex digit?]_ +which code points are disallowed. The equality operators `==` and `!=` are automatically available for `char`. Given that characters are essentially code points, -it may be also natural to support -the ordering operators `<`, `<=`, `>`, and `>=`. -_[TODO: This is useful to check that a character is in a range, for instance. -Another approach is to use conversions to integers and compare the integers.]_ +we may also support the ordering operators `<`, `<=`, `>`, and `>=`; +these may be useful to check whether a character is in certain range. -_[TODO: Which (initial) built-in or library operations -do we want to provide for `char` values?]_ -- [ ] is_alphabetic - Returns `true` if the `char` has the `Alphabetic` property. -- [ ] is_ascii - Returns `true` if the `char` is in the `ASCII` range. -- [ ] is_ascii_alphabetic - Returns `true` if the `char` is in the `ASCII Alphabetic` range. -- [ ] is_lowercase - Returns `true` if the `char` has the `Lowercase` property. -- [ ] is_numeric - Returns `true` if the `char` has one of the general categories for numbers. -- [ ] is_uppercase - Returns `true` if the `char` has the `Uppercase` property. -- [ ] is_whitespace - Returns `true` if the `char` has the `White_Space` property. -- [ ] to_digit - Converts the `char` to the given `radix` format. -- [ ] from_digit - Inverse of to_digit. -- [ ] to_uppercase - Converts lowercase to uppercase, leaving others unchanged. -- [ ] to_lowercase - Converts uppercase to lowercase, leaving others unchanged. +Belowis a list of possible operations we could support on characters. +It should be fairly easy to add more. +- [ ] `is_alphabetic` - Returns `true` if the `char` has the `Alphabetic` property. +- [ ] `is_ascii` - Returns `true` if the `char` is in the `ASCII` range. +- [ ] `is_ascii_alphabetic` - Returns `true` if the `char` is in the `ASCII Alphabetic` range. +- [ ] `is_lowercase` - Returns `true` if the `char` has the `Lowercase` property. +- [ ] `is_numeric` - Returns `true` if the `char` has one of the general categories for numbers. +- [ ] `is_uppercase` - Returns `true` if the `char` has the `Uppercase` property. +- [ ] `is_whitespace` - Returns `true` if the `char` has the `White_Space` property. +- [ ] `to_digit` - Converts the `char` to the given `radix` format. +- [ ] `from_digit` - Inverse of to_digit. +- [ ] `to_uppercase` - Converts lowercase to uppercase, leaving others unchanged. +- [ ] `to_lowercase` - Converts uppercase to lowercase, leaving others unchanged. -It seems fairly natural to convert between `char` values +It seems natural to convert between `char` values and `u8` or `u16` or `u32` values, under suitable range conditions; perhaps also between `char` values and (non-negative) `i8` or `i16` or `i32` values. This will be accomplished as part of the type casting extension of Leo. -_[TODO: are we okay with deferring these operations to type casting?]_ -This code sample illustrates 3 ways of defining characters: character literal, escaped symbol -and Unicode escapes as hex. +The following code sample illustrates three ways of defining characters: +character literal, single-character escapes, and Unicode escapes. ```js function main() -> [char; 5] { @@ -167,12 +165,6 @@ Double quotes must be escaped with a backslash, e.g. `"say \"hi\""`; backslashes must be escaped as well, e.g. `"c:\\dir"`. We allow the same backslash escapes allowed for character literals (see the section on characters above). -_[TODO: There is a difference in the treatment of single and double quotes: -the former are allowed in string literals but not character literals, -while the latter are allowed in character literals but not string literals; -this asymmetry is also present in Java. -However, for simplicity, we may want to symmetrically disallow -both single and double quotes in both character and string literals.]_ We also allow the same Unicode escapes allowed in character literals (described in the section on characters above). In any case, the type of a string literal is `[char; N]`, @@ -194,25 +186,37 @@ in a future design iteration, a richer type for strings, as discussed in the section about future extensions below. -_[TODO: Which (initial) built-in or library operations -do we want to provide for `[char; N]` values that are not already -available with the existing array operations?]_ -- [ ] `u8` to `[char; 2]` hexstring, .., `u128` to `[char; 32]` hexstring -- [ ] field element to `[char; 64]` hexstring. (Application can test leading zeros and slice them out if it needs to return, say, a 40-hex-digit string) -- [ ] len - Returns the length of the `string`. -- [ ] is_empty - Returns `true` if the `string` is empty. -- [ ] pop - Pops a `char` to the `string`. -- [ ] push - Pushes a `char` to the `string`. -- [ ] append - Appends a `string` to the `string`. -- [ ] clear - Empties the `string`. -- [ ] _[TODO: more?]_ +Recall that empty arrays are disallowed in Leo. +(The reason is that arrays, +which must have a size known at compile time and are not resizable, +are flattened into their elements when compiling to R1CS; +thus, an empty array would be flattened into nothing.) +Therefore, in this initial design empty strings must be disallowed as well. +A future type of resizable strings will support empty strings. -Given the natural conversions between `char` values and integer values -discussed earlier, -it may be natural to also support element-wise conversions -between strings and arrays of integers. -This will be accomplished, if desired, -as part of the type casting extensions of Leo. +Because array, and therefore string, sizes must be known at compile time, +there is no point to having an operation to return the length of a string. +This operation will be supported for a future type of resizable strings. + +Below are some examples of array operations +that are also common for strings in other programming languages: +* `[...s1, ...s2]` concatenates the strings `s1` and `s2`. +* `[c, ...s]` adds the character `c` in front of the string `s`. +* `s[i]` extracts the `i`-th character from the string `s`. +* `s[1..]` removes the first character from the string `s`. + +Below is a list of possible operations we could support on strings. +It should be fairly easy to add more. +- [ ] `u8` to `[char; 2]` hexstring, .., `u128` to `[char; 32]` hexstring. +- [ ] Field element to `[char; 64]` hexstring. (Application can test leading zeros and slice them out if it needs to return, say, a 40-hex-digit string.) +- [ ] Apply `to_uppercase` (see above) to every character. +- [ ] Apply `to_lowercase` (see above) to every character. + +Note that the latter two could be also realize via simple loops through the string. + +Given the natural conversions between `char` values and integer values discussed earlier, +it may be natural to also support element-wise conversions between strings and arrays of integers. +This may be accomplished as part of the type casting extensions of Leo. The following code shows a string literal and its actual transformation into an array of characters as well as possible array-like operations on strings: @@ -232,18 +236,6 @@ function main() -> bool { } ``` -## Input and Output of Literal Characters and Strings - -Since UTF-8 is a standard encoding, it would make sense for -the literal characters and strings in the `.in` file -to be automatically converted to UTF-32 by the Leo compiler. -However, the size of a string can be confusing since multiple -Unicode code points can be composed into a single glyph which -then appears to be a single character. If a parameter of type `[char; 10]` -[if that is the syntax we decide on] is passed a literal string -of a different size, the error message should explain that the -size must be the number of codepoints needed to encode the string. - ## Format Strings Leo currently supports format strings as their own entity, @@ -256,6 +248,31 @@ which will be interpreted as a format string according to the semantics of console print calls. The internal UTF-32 string will be translated to UTF-8 for output. +## Circuit Types for Character and String Operations + +The operations on characters and lists described earlier, e.g. `is_ascii`, +are provided as static member functions of two new built-in or library circuit types `Char` and `String`. +Thus, an example call is `Char::is_ascii(c)`. +This seems a general good way to organize built-in or library operations, +and supports the use of the same name with different circuit types, +e.g. `Char::to_uppercase` and `String::to_uppercase`. + +These circuit types could also include constants, e.g. for certain ASCII characters. +However, currently Leo does not support constants in circuit types, +so that would have to be added separately first. + +## Input and Output of Literal Characters and Strings + +Since UTF-8 is a standard encoding, it would make sense for +the literal characters and strings in the `.in` file +to be automatically converted to UTF-32 by the Leo compiler. +However, the size of a string can be confusing since multiple +Unicode code points can be composed into a single glyph which +then appears to be a single character. If a parameter of type `[char; 10]` +[if that is the syntax we decide on] is passed a literal string +of a different size, the error message should explain that the +size must be the number of codepoints needed to encode the string. + ## Compilation to R1CS So far, the discussion has been independent from R1CS @@ -285,9 +302,6 @@ applies to strings without exception. String literals are just syntactic sugar for suitable array inline construction expressions. -_[TODO: We need to discuss which SnarkVM gadgets we need -to compile the operations on characters and strings.]_ - There are at least two approaches to implementing ordering operations `<` and `<=` on `char` values. Recalling that characters are represented as field values @@ -314,6 +328,9 @@ and compare them as integers; in this case we only need 21 bits for each. We need more analysis to determine which approach is more efficient. +The details of implementing other character and string operations in R1CS +will be fleshed out as each operation is added. + ## Future Extensions As alluded to in the section about design above, From 7a6384e1180dd3c8ef6bc998238b3a45b1022234 Mon Sep 17 00:00:00 2001 From: Alessandro Coglio Date: Fri, 7 May 2021 17:29:33 -0700 Subject: [PATCH 20/24] Fix typo in error message. --- ast/src/errors/canonicalization.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ast/src/errors/canonicalization.rs b/ast/src/errors/canonicalization.rs index febe7bd0f0..b3f7cb6622 100644 --- a/ast/src/errors/canonicalization.rs +++ b/ast/src/errors/canonicalization.rs @@ -36,7 +36,7 @@ impl CanonicalizeError { } pub fn invalid_array_dimension_size(span: &Span) -> Self { - let message = "recieved dimension size of 0, expected it to be 1 or larger.".to_string(); + let message = "received dimension size of 0, expected it to be 1 or larger.".to_string(); Self::new_from_span(message, span) } From 7ac1de73533633c7a0fffdf55786c609e46fa839 Mon Sep 17 00:00:00 2001 From: Alessandro Coglio Date: Fri, 7 May 2021 21:30:02 -0700 Subject: [PATCH 21/24] [ABNF] Expand some doc and break some lines. Explain the new syntax for circuit member variables. Explain the tighter syntax for import declarations. Keep lines to 80 columns max, so that they fit well in the figures in the LaTeX document. --- grammar/abnf-grammar.txt | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/grammar/abnf-grammar.txt b/grammar/abnf-grammar.txt index f38ddb27b3..8bf54ab731 100644 --- a/grammar/abnf-grammar.txt +++ b/grammar/abnf-grammar.txt @@ -942,18 +942,35 @@ function-inputs = function-input *( "," function-input ) function-input = [ %s"const" ] identifier ":" type -; A circuit member variable declaration consists of an identifier and a type. -; A circuit member function declaration consists of a function declaration. +; A circuit member variable declaration consists of +; an identifier and a type, terminated by semicolon. +; For backward compatibility, +; member variable declarations may be alternatively followed by commas, +; and the last one may not be followed by anything: +; these are deprecated, and will be eventually removed, +; leaving only mandatory semicolons. +; Note that there is no rule for a single `member-variable-declaration`, +; but instead one for a sequence of them; +; see the rule `circuit-declaration`. -member-variable-declarations = *(identifier ":" type ( "," / ";" )) identifier ":" type ( [ "," ] / ";" ) +member-variable-declarations = *( identifier ":" type ( "," / ";" ) ) + identifier ":" type ( [ "," ] / ";" ) + +; A circuit member function declaration consists of a function declaration. member-function-declaration = function-declaration ; A circuit declaration defines a circuit type, ; as consisting of member variables and functions. +; To more simply accommodate the backward compatibility +; described for the rule `member-variable-declarations`, +; all the member variables must precede all the member functions; +; this may be relaxed after the backward compatibility is removed, +; allowing member variables and member functions to be intermixed. circuit-declaration = *annotation %s"circuit" identifier - "{" [ member-variable-declarations ] *member-function-declaration "}" + "{" [ member-variable-declarations ] + *member-function-declaration "}" ; An import declaration consists of the `import` keyword ; followed by a package path, which may be one of the following: @@ -964,6 +981,10 @@ circuit-declaration = *annotation %s"circuit" identifier ; which are "fan out" of the initial path. ; Note that we allow the last element of the parenthesized list ; to be followed by a comma, for convenience. +; The package path in the import declaration must start with a package name +; (e.g. it cannot be a `*`): +; the rule for import declaration expresses this requirement +; by using an explicit package name before the package path. import-declaration = %s"import" package-name "." package-path ";" From b91dc7da4aaa6a114274767988dc5b953b26b999 Mon Sep 17 00:00:00 2001 From: Alessandro Coglio Date: Sun, 9 May 2021 14:23:11 -0700 Subject: [PATCH 22/24] [RFC] Fix typo found by Eric M. --- docs/rfc/001-initial-strings.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rfc/001-initial-strings.md b/docs/rfc/001-initial-strings.md index 7b810f99cf..af11dbe8f3 100644 --- a/docs/rfc/001-initial-strings.md +++ b/docs/rfc/001-initial-strings.md @@ -107,7 +107,7 @@ Given that characters are essentially code points, we may also support the ordering operators `<`, `<=`, `>`, and `>=`; these may be useful to check whether a character is in certain range. -Belowis a list of possible operations we could support on characters. +Below is a list of possible operations we could support on characters. It should be fairly easy to add more. - [ ] `is_alphabetic` - Returns `true` if the `char` has the `Alphabetic` property. - [ ] `is_ascii` - Returns `true` if the `char` is in the `ASCII` range. From 31bb04b3957375ad7d7e49e73881a8a4fc85ee61 Mon Sep 17 00:00:00 2001 From: Alessandro Coglio Date: Mon, 10 May 2021 19:47:34 -0700 Subject: [PATCH 23/24] [RFC] Add a clarification. --- docs/rfc/001-initial-strings.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/rfc/001-initial-strings.md b/docs/rfc/001-initial-strings.md index af11dbe8f3..10f9482ad9 100644 --- a/docs/rfc/001-initial-strings.md +++ b/docs/rfc/001-initial-strings.md @@ -261,6 +261,13 @@ These circuit types could also include constants, e.g. for certain ASCII charact However, currently Leo does not support constants in circuit types, so that would have to be added separately first. +These two circuit types are just meant to collect static member functions for characters and strings. +They are not meant to be the types of characters and strings: +as mentioned previously, `char` is a new scalar (not circuit) type (like `bool`, `address`, `u8`, etc.) +and there is no string type as such for now, but we use character arrays for strings. +In the future we may want all the Leo types to be circuit types of some sort, +but that is a separate feature that would have to be designed and developed independently. + ## Input and Output of Literal Characters and Strings Since UTF-8 is a standard encoding, it would make sense for From 90d247daaf3f1ab60cba5e1e45f37c848732e71f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 11 May 2021 10:50:33 +0000 Subject: [PATCH 24/24] Bump self_update from 0.26.0 to 0.27.0 Bumps [self_update](https://github.com/jaemk/self_update) from 0.26.0 to 0.27.0. - [Release notes](https://github.com/jaemk/self_update/releases) - [Changelog](https://github.com/jaemk/self_update/blob/master/CHANGELOG.md) - [Commits](https://github.com/jaemk/self_update/commits) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6d5aed8919..288a5a84e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2483,9 +2483,9 @@ dependencies = [ [[package]] name = "self_update" -version = "0.26.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9031099ba3962ce8faaff991066bcbe6ec1f7ccb0be12a4b56733028ae090054" +checksum = "6fb85f1802f7b987237b8525c0fde86ea86f31c957c1875467c727d5b921179c" dependencies = [ "hyper", "indicatif", diff --git a/Cargo.toml b/Cargo.toml index a0f4297de0..7f07b95181 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -125,7 +125,7 @@ version = "0.11.3" features = [ "blocking", "json", "multipart" ] [dependencies.self_update] -version = "0.26.0" +version = "0.27.0" features = [ "archive-zip" ] [dependencies.serde]