#+TODO: TODO(t@) TOIMPL(i@) BLOCK(b@) | DONE(d!) #+STARTUP: indent logdone logdrawer content # ------------------------------------------------------ #+NOIR_TEMPLATE_URL: https://github.com/noir-lang/noir/blob/%h/%p#L%lC%c-L%lC%s # ------------------------------------------------------ #+TITLE: Noir Treesitter Grammar #+AUTHOR: Jordan Ellis Coppard #+LANGUAGE: en #+OPTIONS: ^:{} =(org-macro-expand (org-element-context) org-macro-templates)= All notes currently against upstream commit {{{keyword(NOIR_VERSION)}}}. Noir isn't formally specified currently; expected given the language is pre 1.0. So, here are notes and links to compiler infrastructure to ascertain language minutia. * Compiler :noirc: :PROPERTIES: :ID: 9405296D-1F11-4E7E-8306-401487D24999 :END: Noir's compiler frontend performs parsing and lexing at the same time; the parser internally lexes the target file(s). The lexer transforms an iterator of characters into an iterator of ~SpannedToken~; each ~Token~ having a ~Span~ (delimited region in source file). ~Spans~ are owned by AST nodes which forms the (initial) parsing result. Concerning Noir's frontend compiler: - Tag =node= being used as a non-terminal symbol. - Tag =leaf= used as a terminal symbol. Entry: #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser.rs][parse_program()]] :lines 43-43 :src rust ** Lexing TODO: Rename this header, idk? *** Code whitespace Whitespace is not significant in Noir. #+transclude: [[file:noir/compiler/noirc_frontend/src/lexer/lexer.rs][Lexer::eat_whitespace()]] :lines 703-704 :src rust Newline, tab, carriage return, ASCII space. #+transclude: [[file:noir/compiler/noirc_frontend/src/lexer/lexer.rs][Lexer::is_code_whitespace()]] :lines 699-700 :src rust *** Attribute :PROPERTIES: :header-args: :noweb-ref AttributeKeywords :noweb-sep "\n\n" :END: Primary or Secondary; depending on how many can be applied to a function. - Primary: one (alters a functions ACIR output). - Secondary: unlimited. #+transclude: [[file:noir/compiler/noirc_frontend/src/lexer/token.rs][Attribute]] :lines 727-734 :src rust *************** TODO Include tag, inner, and primary/secondary as part of tree-sitter parser or nah? *************** END *************** TODO Attribute splits on ( and ) as sub-tokens? *************** END **** PrimaryAttribute Also called FunctionAttribute. Predefined: #+begin_src js const PRIMARY_ATTRIBUTES = [ 'foreign', 'builtin', 'oracle', 'test', 'recursive', 'fold', 'no_predicates', 'inline_always', 'test', 'field', ] #+end_src #+transclude: [[file:noir/compiler/noirc_frontend/src/lexer/token.rs][FunctionAttribute]] :lines 849-861 :src rust #+transclude: [[file:noir/compiler/noirc_frontend/src/lexer/token.rs][predefined primaries]] :lines 782-812 :src rust **** SecondaryAttribute :PROPERTIES: :CUSTOM_ID: h:175D41E7-445C-45EE-B35D-27448C1A9D5C :END: Include CustomAttribute and InnerAttribute. Predefined: #+begin_src js const SECONDARY_ATTRIBUTES = [ 'deprecated', 'contract_library_method', 'abi', 'export', 'varargs', 'use_callers_scope', 'allow', ] #+end_src #+transclude: [[file:noir/compiler/noirc_frontend/src/lexer/token.rs][predefined secondaries]] :lines 814-842 :src rust **** Lex process 1. Starts with ~#~. #+transclude: [[file:noir/compiler/noirc_frontend/src/lexer/lexer.rs][Lexer::next_token()]] :lines 142-142 :src rust 2. Optionally by ~!~ making it an [[#h:175D41E7-445C-45EE-B35D-27448C1A9D5C][InnerAttribute]]. #+transclude: [[file:noir/compiler/noirc_frontend/src/lexer/lexer.rs][Lexer::eat_attribute()]] :lines 285-285 :src rust 3. Immediately by ~[~. 4. Optionally by ~'~ making the attribute a Tag. 5. Eat everything until ~]~. - =word= is everything between enclosing braces ~[~ and ~]~, and in the case of a tag that excludes the initial ~'~. - =span= includes everything from starting ~#~ to closing ~]~, inclusive. Within =Attribute::lookup_attribute= 6. [@6] Split =word= into segments at ~(~ and ~)~, drop all empty segments. #+transclude: [[file:noir/compiler/noirc_frontend/src/lexer/token.rs][Attribute::lookup_attribute()]] :lines 754-757 :src rust 7. Check all characters in =span= such that they are: - ASCII alphabetic. - Numeric *NOTE* that this does NOT mean ASCII numeric, see [[https://doc.rust-lang.org/std/primitive.char.html#method.is_numeric][rust docs]]. - ASCII punctuation; any of: (see [[https://doc.rust-lang.org/std/primitive.char.html#method.is_ascii_punctuation][rust docs]]) ~! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~~. - Literal ASCII whitespace. #+transclude: [[file:noir/compiler/noirc_frontend/src/lexer/token.rs][Attribute::lookup_attribute()]] :lines 759-770 :src rust If the attribute was marked as a Tag a CustomAttribute within a [[SecondaryAttribute]] is created and returned. #+transclude: [[file:noir/compiler/noirc_frontend/src/lexer/token.rs][Attribute::lookup_attribute()]] :lines 773-777 :src rust *************** TODO Do CustomAttributes concern us from tree-sitter perspective? *************** END 8. [@8] Each of the split =word= segments are matched and validated (as attribute). #+transclude: [[file:noir/compiler/noirc_frontend/src/lexer/token.rs][Attribute::lookup_attribute()]] :lines 781-845 :src rust 9. The created attribute is returned. If the attribute was marked as an [[InnerAttribute]] it cannot match the name of any primary (aka function) attribute. If it doesn't match (good) it's lexed as an [[InnerAttribute]]. Non-inner attributes returned (tokenised) as either primary or secondary. *** next_token TODO: Organise this and where/how we're putting lexing info. ** Structure Noir *Program* contains *Module* which is comprised of [[./noir_grammar.org::#h:C58B2CB4-FF62-49BB-AFFD-1BADF4462B9D][InnerDocComments]] followed by (repeat) [[./noir_grammar.org::#h:8CC1D239-66B1-45A9-BB71-66AF07161479][Item]]. Program: #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser.rs][Parser::parse_program()]] :lines 115-119 :src rust Module: #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser.rs][Parser::parse_module()]] :lines 122-125 :src rust The first list under each /Noir/ heading represents grammar where each element (-) is a logic OR and each element (+) is an ordered item type (also inlined via =by=). So, the following example list reads "(A followed by B) OR (C followed by D followed by E)". : - A by B : - C : + D : + E *** TODO InnerDocComments :PROPERTIES: :CUSTOM_ID: h:C58B2CB4-FF62-49BB-AFFD-1BADF4462B9D :END: Foo *** TODO Item :node: :PROPERTIES: :CUSTOM_ID: h:8CC1D239-66B1-45A9-BB71-66AF07161479 :END: - [[OuterDocComments]] by [[ItemKind]]. - Parsed without separator (~Parser::parse_module_items~). - ~Parser::parse_module_item_in_list~. **** TODO OuterDocComments Foo **** TODO ItemKind :node: - [[InnerAttribute]]. - [[Attributes]] by [[Modifiers]]. TODO: What does (Use | ModOrContract and so forth mean?) TODO: Does this mean that in a list of attributes #[foo] #[bar] #![bing] #[bong] that foo and bar are grouped as attributes, the inner attribute bing breaks that group, and then bong is itself in another group later on? Given that inner attribute makes parse_item_kind return early. maybe: #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/item.rs][Parser::parse_item_kind()]] :lines 97-109 :src rust ***** TODO InnerAttribute No special parse logic, merely checks type of lexed token. TODO: Link to Attribute (lex) subheading Lex process via that star syntax. #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/item.rs][parse InnerAttribute]] :lines 110-112 :src rust Can be any valid [[SecondaryAttribute]] and is purely a syntactical convenience to apply to it's container versus attribute definitions piled at containers definition. See [[https://github.com/noir-lang/noir/issues/5875][issue]] for more. #+transclude: [[file:noir/compiler/noirc_frontend/src/lexer/token.rs][Token::InnerAttribute]] :lines 141-141 :src rust Any valid ~TokenKind::InnerAttribute~ parsed as InnerAttribute. #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/attributes.rs][Parser::parse_inner_attribute]] :lines 11-15 :src rust ***** TODO Attributes Multiple attributes are parsed and collected within =Parser::parse_item_kind()= via call to: #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/attributes.rs][Parser::parse_attributes]] :lines 20-30 :src rust ***** TODO Modifiers ****** Treesitter :grammar: #+begin_src js :noweb-ref Modifiers // Modifiers except for visibility (in order). const MODIFIERS = { Unconstrained: 'unconstrained', Comptime: 'comptime', Mut: 'mut', } #+end_src ****** Noir - ItemVisibility. - (opt) =unconstrained=. - (opt) =comptime=. - (opt) =mut=. #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/modifiers.rs][Parser::parse_modifiers()]] :lines 17-21 :src rust Remaining keywords consumed as their literal selves. #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/modifiers.rs][unconstrained, comptime, mut]] :lines 32-48 :src rust *************** TODO Verify that the Noir compiler will error if modifiers are supplied out of order, with the exception (mentioned in Noir compiler source) of unconstrained being before pub to support that legacy ordering. *************** END *************** TODO Decide on and note that we do not support legacy unconstrained ordering because it complicates things massively. *************** END ****** DONE ItemVisibility :declaration: CLOSED: [2024-11-01 Fri 19:56] :PROPERTIES: :CUSTOM_ID: h:F5A79701-65C9-4FEA-83D8-2413C585A5FA :END: :LOGBOOK: - State "DONE" from "TODO" [2024-11-01 Fri 19:56] :END: ******* Treesitter :grammar: :PROPERTIES: :CUSTOM_ID: h:46B8EF89-89A5-4346-9B5B-04630DAEF262 :END: #+begin_src js visibility_modifier: ($) => seq('pub', optional('(crate)')) #+end_src ******* Noir - =pub=. - =pub(crate)=. - NIL. Missing text (NIL) is a type of visibility in the sense that the default visibility is private if unspecified. Missing text won't affect tree-sitter unless/until qualifying item visibility becomes part of the CST. #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/item_visibility.rs][Parser::parse_item_visibility()]] :lines 9-13 :src rust ***** TODO Use - =use=. - PathKind. - PathNoTurbofish. - UseTree. Only the ItemVisibility modifier is applicable, all others are parse errors. #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/item.rs][parse use callsite]] :lines 121-126 :src rust #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/use_tree.rs][Parser::parse_use_tree]] :lines 12-29 :src rust ****** TODO UseTree - PathNoTurbofish by (opt sublist) + =::=. + ={=. + (opt) UseTreeList. + =}=. ****** TODO UseTreeList - UseTree by (repeat) + =,=. + UseTree. - (opt) =,=. ***** TODO Struct Foo ***** TODO Implementation Foo ***** TODO Trait Foo ***** TODO Global Foo ***** TOIMPL Type :PROPERTIES: :CUSTOM_ID: h:B3490B7C-F387-49C7-BF94-DC9CE8AC3581 :END: :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-16 Sat 18:26] :END: - [[#h:C23E374A-42EF-467D-AE3D-548D880712D8][PrimitiveType]]. - [[#h:39A2690C-319F-4F34-A139-8549D70FCF26][ParenthesesType]]. - [[#h:FAB3845D-97FD-454B-B8C8-09FEEB41FC3D][ArrayOrSliceType]]. - [[#h:C1EF6337-B3F1-44D9-B5E6-FF5A0215FCC5][MutableReferenceType]]. - [[#h:96043AA8-9EC3-4E80-AA5D-CBFFE60A9072][FunctionType]]. - [[#h:08118263-BDC8-4589-8EF9-1F0490B62F34][TraitAsType]]. - [[#h:5B4FDF39-09B2-4C07-A2B5-3A3D6BEDD4B7][AsTraitPathType]]. - [[#h:F2E3D7E1-0978-44DF-A49E-EBE348F9D973][UnresolvedNamedType]]. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_type(&mut self)][parse_type()]] TODO: Look at enum ~UnresolvedTypeData~, read the doc string and look at it's elements. Good stuff. #+transclude: [[file:noir/compiler/noirc_frontend/src/ast/mod.rs][foobar]] :lines 104-106 :src foo TODO: Path from lexer.rs ~next_token()~ to the point where it checks for keywords. TODO: Put lookup_keyword under it's own heading and transclude the contents verbatim When lexing [[file:noir/compiler/noirc_frontend/src/lexer/token.rs::fn lookup_keyword(word: &str)][lookup_keyword()]] determines keyword tokens ~Keyword~ which are later parsed: :callstack: - [-] [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_unresolved_type_data(&mut self)][parse_unresolved_type_data()]] - [ ] [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_str_type(&mut self)][parse_str_type()]] - [ ] [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_fmtstr_type(&mut self)][parse_fmtstr_type()]] - [ ] [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_comptime_type(&mut self)][parse_comptime_type()]] - [ ] [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_resolved_type(&mut self)][parse_resolved_type()]] - [ ] [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_interned_type(&mut self)][parse_interned_type()]] - [ ] [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_parentheses_type(&mut self)][parse_parentheses_type()]] - [ ] [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_array_or_slice_type(&mut self)][parse_array_or_slice_type()]] - [ ] [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parses_mutable_reference_type(&mut self)][parses_mutable_reference_type()]] - [ ] [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_function_type(&mut self)][parse_function_type()]] - [ ] [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_trait_as_type(&mut self)][parse_trait_as_type()]] - [ ] [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_as_trait_path_type(&mut self)][parse_as_trait_path_type()]] - [ ] [[file:noir/compiler/noirc_frontend/src/parser/parser/path.rs::fn parse_path_no_turbofish(&mut self)][parse_path_no_turbofish()]] - [ ] [[file:noir/compiler/noirc_frontend/src/parser/parser/generics.rs::fn parse_generic_type_args(&mut self)][parse_generic_type_args()]] :end: ****** BLOCK PrimitiveType :PROPERTIES: :CUSTOM_ID: h:C23E374A-42EF-467D-AE3D-548D880712D8 :END: :LOGBOOK: - State "BLOCK" from "TODO" [2024-11-15 Fri 19:40] \\ Explored the parsing function for all its subtypes, but there are some non-trivial recursive dependencies (going back to Type) and also some quoted and interned stuff so blocked for now. :END: Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_primitive_type(&mut self)][parse_primitive_type()]] ******* TOIMPL FieldType :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-03 Sun 12:24] :END: + =Field=. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_field_type(&mut self)][parse_field_type()]] ******* TOIMPL IntegerType :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-03 Sun 14:50] :END: + =i= OR =u=. + =1= OR =8= OR =16= OR =32= OR =64=. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_int_type(&mut self)][parse_int_type()]] Both signed and unsigned: 1, 8, 16, 32, and 64 bits. #+transclude: [[file:noir/compiler/noirc_frontend/src/ast/mod.rs::61][IntegerBitSize::allowed_sizes()]] :lines 61-65 :src rust TODO: Is there a bug in this version of Noir that doesn't allow 16-bit integers? See the above transclude missing ~Self::Sixteen~. :callstack: - [X] [[file:noir/compiler/noirc_frontend/src/parser/parser.rs::fn eat_int_type(&mut self)][eat_int_type()]] - nb :: [[file:noir/compiler/noirc_frontend/src/lexer/token.rs::enum IntType][Token::IntType]] from [[#h:B7763FFE-9685-45F5-A414-66F9E47F3E1D][Lexing]]. - [X] [[file:noir/compiler/noirc_frontend/src/ast/mod.rs::fn from_int_token(][UnresolvedTypeData::from_int_token()]] - [X] [[file:noir/compiler/noirc_frontend/src/ast/mod.rs::fn try_from(value: u32)][IntegerBitSize::try_from()]] :end: 1. If [[file:noir/compiler/noirc_frontend/src/ast/mod.rs::fn from_int_token(][UnresolvedTypeData::from_int_token()]]'s call to [[file:noir/compiler/noirc_frontend/src/ast/mod.rs::fn try_from(value: u32)][IntegerBitSize::try_from()]] succeeds an ~UnresolvedTypeData::Integer~ is returned. 2. [[file:noir/compiler/noirc_frontend/src/ast/mod.rs::fn try_from(value: u32)][IntegerBitSize::try_from()]] validates given numeric bit-size component and returns matching ~IntegerBitSize~, otherwise returning invalid bit-size parse error. ******** Lexing :PROPERTIES: :CUSTOM_ID: h:B7763FFE-9685-45F5-A414-66F9E47F3E1D :END: :callstack: - [[file:noir/compiler/noirc_frontend/src/lexer/lexer.rs::fn next_token(&mut self)][Lexer::next_token()]] - [[file:noir/compiler/noirc_frontend/src/lexer/lexer.rs::fn eat_alpha_numeric(&mut self, initial_char: char)][Lexer::eat_alpha_numeric()]] - [[file:noir/compiler/noirc_frontend/src/lexer/lexer.rs::fn eat_word(&mut self, initial_char: char)][Lexer::eat_word()]] - [[file:noir/compiler/noirc_frontend/src/lexer/lexer.rs::fn lookup_word_token(][Lexer::lookup_word_token()]] :end: Parser: [[file:noir/compiler/noirc_frontend/src/lexer/token.rs::fn lookup_int_type(word: &str)][IntType::lookup_int_type()]] 1. Signed or unsigned if ~word~ starts with =i= or =u= respectively. 2. Remaining string ~word~ contents attempt parse into bit-size 32-bit integer. 3. [[file:noir/compiler/noirc_frontend/src/lexer/token.rs::enum IntType][Token::IntType]] created with signedness and bit-size value. ******* TOIMPL BoolType :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-03 Sun 12:21] :END: + =bool=. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_bool_type(&mut self)][parse_bool_type()]] Parses the literal /keyword/ =bool= *and not* literal words =true= or =false=. ******* BLOCK StringType :LOGBOOK: - State "BLOCK" from "TODO" [2024-11-16 Sat 18:26] \\ TypeExpression completion. :END: + =str= (kw). + =<=. + [[#h:0DEF3192-4840-41B3-A941-714798677092][TypeExpression]]. + =>=. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_str_type(&mut self)][parse_str_type()]] *************** TODO How does the first check on eat_less in parse_str_type work? What's going on here specifically when it returns Some(UnresolvedTypeExpression)? Is that important later on? Check `str` syntax with concrete tests in Noir, like is str allowed or does it always have to be str<123>. It looks like it _is_ a parser error so..? *************** END ******* TOIMPL FormatStringType :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-16 Sat 18:24] :END: + =fmtstr= (kw). Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_fmtstr_type(&mut self)][parse_fmtstr_type()]] Return ~AST::UnresolvedTypeData::FormatString~. ******* TOIMPL ComptimeType :PROPERTIES: :CUSTOM_ID: h:98FC5657-8034-42F7-A263-3172EFEEEB23 :END: :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-15 Fri 19:29] :END: - =Expr=. - =Quoted=. - =TopLevelItem=. - =Type=. - =TypedExpr=. - =StructDefinition=. - =TraitConstraint=. - =TraitDefinition=. - =TraitImpl=. - =UnresolvedType=. - =FunctionDefinition=. - =Module=. - =CtString=. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_comptime_type(&mut self)][parse_comptime_type()]] All ComptimeTypes returned as ~AST::UnresolvedTypeData::Quoted(X)~ where ~X~ is [[file:noir/compiler/noirc_frontend/src/hir_def/types.rs::pub enum QuotedType {][QuotedType]]. #+transclude: [[file:noir/compiler/noirc_frontend/src/hir_def/types.rs::282][QuotedType]] :lines 282-296 :src rust *************** TODO This feels strage, are those literal keywords allowed in source? This feels like stuff a preprocessing step would inline or something. If one can literally write these keywords and them be valid then sure. *************** END *************** TODO Check out hir_def/types.rs enum Type, good docs. *************** END ******* BLOCK ResolvedType :PROPERTIES: :CUSTOM_ID: h:87984AE0-613D-4D9A-A64D-D3FD8BD51C98 :END: :LOGBOOK: - State "BLOCK" from "TODO" [2024-11-16 Sat 18:25] \\ Clarity on QuotedType stuff. :END: Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_resolved_type(&mut self)][parse_resolved_type()]] *************** TODO Non-concrete token kinds lookup, so get to this later. i.e. no literal string keyword that lookup_keyword matches. *************** END ******* BLOCK InternedType :PROPERTIES: :CUSTOM_ID: h:21789349-305A-46D0-8D87-D7B8647482CF :END: :LOGBOOK: - State "BLOCK" from "TODO" [2024-11-16 Sat 18:25] \\ Clarity on InternedType stuff. :END: Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::pub(super) fn parse_interned_type(&mut self)][parse_interned_type()]] *************** TODO Non-concrete token kinds lookup, so get to this later. i.e. no literal string keyword that lookup_keyword matches. *************** END ****** BLOCK ParenthesesType :PROPERTIES: :CUSTOM_ID: h:39A2690C-319F-4F34-A139-8549D70FCF26 :END: :LOGBOOK: - State "BLOCK" from "TODO" [2024-11-16 Sat 17:09] \\ Type completion. :END: - [[#h:9653A5E5-2857-4FB4-8698-5D9F6F0E8755][Unit]]. - [[#h:CF9505CB-8110-4FC2-8A6B-5D88A7EB1D06][TupleElement]]. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_parentheses_type(&mut self)][parse_parentheses_type()]] ******* TOIMPL Unit :PROPERTIES: :CUSTOM_ID: h:9653A5E5-2857-4FB4-8698-5D9F6F0E8755 :END: :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-15 Fri 20:24] :END: + =(= by =)=. Parser: /in slice of parent/. ******* TODO TupleElement :PROPERTIES: :CUSTOM_ID: h:CF9505CB-8110-4FC2-8A6B-5D88A7EB1D06 :END: + =(=. + [[#h:B3490B7C-F387-49C7-BF94-DC9CE8AC3581][Type]]. + (rep0 grp) =,= by [[#h:B3490B7C-F387-49C7-BF94-DC9CE8AC3581][Type]]. + (opt) =,=. + =)=. Parser: /in slice of parent/. #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::387][parse_many_return_trailing_separator_if_any()]] :lines 387-397 :src rust If only one Type and no trailing comma return ~AST::UnresolvedTypeData::Parenthesized~, else return ~AST::UnresolvedTypeData::Tuple~. ****** BLOCK ArrayOrSliceType :PROPERTIES: :CUSTOM_ID: h:FAB3845D-97FD-454B-B8C8-09FEEB41FC3D :END: :LOGBOOK: - State "BLOCK" from "TODO" [2024-11-16 Sat 17:09] \\ Type and TypeExpression completion. :END: + =[=. + [[#h:B3490B7C-F387-49C7-BF94-DC9CE8AC3581][Type]] by: - =]= returns ~AST::UnresolvedTypeData::Slice~. - =;= by [[#h:0DEF3192-4840-41B3-A941-714798677092][TypeExpression]] by =]= returns ~AST::UnresolvedTypeData::Array~. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_array_or_slice_type(&mut self)][parse_array_or_slice_type()]] *************** TODO What about slice literal syntax? What about the &[0; 2] syntax for slice literals? This node doesn't appear to do any ampersand parsing? Check higher up the call chain though since there's A LOT of nesting and what not going on currently. *************** END ****** BLOCK MutableReferenceType :PROPERTIES: :CUSTOM_ID: h:C1EF6337-B3F1-44D9-B5E6-FF5A0215FCC5 :END: :LOGBOOK: - State "BLOCK" from "TODO" [2024-11-16 Sat 17:09] \\ Block on Type completion. :END: + =&=. + =mut= (kw). + [[#h:B3490B7C-F387-49C7-BF94-DC9CE8AC3581][Type]]. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parses_mutable_reference_type(&mut self)][parse_mutable_reference_type()]] Return: ~AST::UnresolvedTypeData::MutableReference~, *************** TODO Get all these return types by using rust-analyser or something? Once we know the parsing function (should still do this manually), give that to rust-analyser to inline the return type here instead of manually maintaining it. Assuming it will be accurate. *************** END ****** BLOCK FunctionType :PROPERTIES: :CUSTOM_ID: h:96043AA8-9EC3-4E80-AA5D-CBFFE60A9072 :END: :LOGBOOK: - State "BLOCK" from "TODO" [2024-11-16 Sat 17:37] \\ Type completion. :END: + (opt) =unconstrained= (kw). + =fn= (kw). + (opt) [[#h:4E68CB10-4122-4C09-B99F-DE7F57651E02][CaptureEnvironment]]. + [[#h:FC1E33B7-033B-4F6F-9EFD-2CDC784E572C][Parameter]]. + =->=. + [[#h:B3490B7C-F387-49C7-BF94-DC9CE8AC3581][Type]]. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_function_type(&mut self)][parse_function_type()]] Return: ~AST::UnresolvedTypeData::Function~. *************** TODO So this is specifically NOT a function DECLARATION? It's either an inline function e.g. a lambda, or calling another pre-declared function? Because there's already a function for parsing a function declaration in the compiler frontend as far as I can see and that function does not support environment capture. It's been a while but I believe I have some environment capture stuff in Tikan from old noir, see how that's used and if that pattern is still valid in current Noir (as well as consulting the compiler tests) to determine what is valid now if there's still uncertainty once all frontend paths are documented. *************** END ******* BLOCK CaptureEnvironment :PROPERTIES: :CUSTOM_ID: h:4E68CB10-4122-4C09-B99F-DE7F57651E02 :END: :LOGBOOK: - State "BLOCK" from "TODO" [2024-11-16 Sat 17:34] \\ Type completion. :END: + =[=. + [[#h:B3490B7C-F387-49C7-BF94-DC9CE8AC3581][Type]]. + =]=. Function capture environment syntax, e.g. =fn foo[Env]()= where =[Env]= is the environment specifier valid for the function to be called within. Parser: /within slice of parent/ #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::252][FunctionType CaptureEnvironment]] :lines 252-258 :src rust ******* BLOCK Parameter :PROPERTIES: :CUSTOM_ID: h:FC1E33B7-033B-4F6F-9EFD-2CDC784E572C :END: :LOGBOOK: - State "BLOCK" from "TODO" [2024-11-16 Sat 17:34] \\ Type completion. :END: + =(=. + (rep0 grp) [[#h:B3490B7C-F387-49C7-BF94-DC9CE8AC3581][Type]] by =,=. + =)=. Parser: /within slice of parent/ and [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_parameter(&mut self)][parse_parameter()]] #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::271][parse_many()]] :lines 271-275 :src rust *************** TODO Are parameters here required? Surely not but until all paths explored they might be? Could easily validate with a concrete syntax test however. The documentation for (rep0 grp) here differs from other lsits because in those other cases at least one element was required before the optional repeating, as this TODO states unsure if the "at least one" is required here. *************** END ****** BLOCK TraitAsType :PROPERTIES: :CUSTOM_ID: h:08118263-BDC8-4589-8EF9-1F0490B62F34 :END: :LOGBOOK: - State "BLOCK" from "TODO" [2024-11-16 Sat 17:48] \\ PathNoTurbofish and GenericTypeArgs completion. :END: + =impl= (kw). + [[#h:A051D0D5-7007-4DF8-83B7-FB4EFF9C383E][PathNoTurbofish]]. + [[#h:3267D7A4-7AA4-49FB-91FA-A9601BC6868A][GenericTypeArgs]]. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_trait_as_type(&mut self)][parse_trait_as_type()]] Return: ~AST::UnresolvedTypeData::TraitAsType~. *************** TODO Rename this to just TraitType if that is unused elsewhere in the (relevant) compiler frontend section? *************** END *************** TODO Path is implied optional (as noted elsewhere), is PathNoTurbofish also implied optional? Because here its required that PathNoTurbofish is Some and _not_ None (which IIRC is how/why Path is implied optional elsewhere). *************** END ****** BLOCK AsTraitPathType :PROPERTIES: :CUSTOM_ID: h:5B4FDF39-09B2-4C07-A2B5-3A3D6BEDD4B7 :END: :LOGBOOK: - State "BLOCK" from "TODO" [2024-11-16 Sat 18:10] \\ AsTraitPath completion. :END: + [[#h:348C4ABC-3FC0-46EC-95A0-7F4B238BB86A][AsTraitPath]]. This just wraps AsTraitPath. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::fn parse_as_trait_path_type(&mut self)][parse_as_trait_path_type()]] Return: ~AST::UnresolvedTypeData::AsTraitPath~. ****** BLOCK UnresolvedNamedType :PROPERTIES: :CUSTOM_ID: h:F2E3D7E1-0978-44DF-A49E-EBE348F9D973 :END: :LOGBOOK: - State "BLOCK" from "TODO" [2024-11-16 Sat 18:22] \\ PathNoTurbofish completion. :END: + [[#h:A051D0D5-7007-4DF8-83B7-FB4EFF9C383E][PathNoTurbofish]]. + (opt) [[#h:3267D7A4-7AA4-49FB-91FA-A9601BC6868A][GenericTypeArgs]]. Parser: /within slice of parent/ #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs::58][parent parser slice]] :lines 58-61 :src rust Return: ~AST::UnresolvedTypeData::Named~. #+transclude: [[file:noir/compiler/noirc_frontend/src/ast/mod.rs::121][UnresolvedTypeData::Named doc]] :lines 121-122 :src rust *************** TODO Unsure of the exact syntax here, should be a path (no turbofish) with generics after it per the method calls. Really deep in syntax spaghetti right now, I expect this will be clear when finally some tests are written and what not. Also I named this node since it doesn't appear to canonically have one. I also ASSUME the generic type args are optional (test concretely). *************** END ***** TODO TypeOrTypeExpression :PROPERTIES: :CUSTOM_ID: h:A32A351C-092B-42F1-AB03-DE49862B35D4 :END: - Type. - [[#h:0DEF3192-4840-41B3-A941-714798677092][TypeExpression]]. Compiler: [[file:noir/compiler/noirc_frontend/src/parser/parser/type_expression.rs::196][parse_type_or_type_expression()]] #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/type_expression.rs][TypeOrTypeExpression doc]] :lines 195-195 :src rust Parse logic when entered here attempts to parse any valid non-literal type, before finally calling ~parse_type()~ which /is/ [[#h:B3490B7C-F387-49C7-BF94-DC9CE8AC3581][Type]]. - [ ] ~parse_add_or_subtract_type_or_type_expression()~. - [ ] ~parse_multiply_or_divide_or_modulo_type_or_type_expression()~. - [ ] ~parse_term_type_or_type_expression()~. - [ ] ~parse_atom_type_or_type_expression()~. - [ ] ~parse_parenthesized_type_or_type_expression()~. - [ ] ~parse_type()~. ***** TOIMPL TypeExpression :PROPERTIES: :CUSTOM_ID: h:0DEF3192-4840-41B3-A941-714798677092 :END: :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-16 Sat 20:20] :END: - [[#h:F248EB42-693F-4CB9-A2B2-68AE5ED9A6B0][AddOrSubtractTypeExpression]]. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/type_expression.rs::pub(crate) fn parse_type_expression(][parse_type_expression()]] #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/type_expression.rs::14][TypeExpression doc]] :lines 14-14 :src rust *************** TODO Flatten nesting or binary/unary structure There's A LOT of nesting here. Attempting to flatten this by hand yields satanic syntax but using such nested structures in the treesitter grammar will be no bueno guaranteed. TypeExpressions _might_ need to wait for a little bit since any optimised flatenning here will be a chore and a half to set up (at least for now, maybe I am just tired now as I've already been working on the documentation stuff for like 5 hours non-stop). *************** END ****** TOIMPL AddOrSubtractTypeExpression :PROPERTIES: :CUSTOM_ID: h:F248EB42-693F-4CB9-A2B2-68AE5ED9A6B0 :END: :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-16 Sat 20:20] :END: + [[#h:AE6765C3-A59C-4316-A3D0-1C67B512AA3E][MultiplyOrDivideOrModuloTypeExpression]]. + (rep0 grp): + (grp) =+= OR =-=. + [[#h:AE6765C3-A59C-4316-A3D0-1C67B512AA3E][MultiplyOrDivideOrModuloTypeExpression]]. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/type_expression.rs::fn parse_add_or_subtract_type_expression(&mut self)][parse_add_or_subtract_type_expression()]] #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/type_expression.rs::24][AddOrSubtractTypeExpression doc]] :lines 24-25 :src rust ******* TOIMPL MultiplyOrDivideOrModuloTypeExpression :PROPERTIES: :CUSTOM_ID: h:AE6765C3-A59C-4316-A3D0-1C67B512AA3E :END: :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-16 Sat 20:20] :END: + [[#h:7B5047E4-D6BD-47E0-8AC3-0BD8AB23AAD2][TermTypeExpression]]. + (rep0 grp): + (grp) =*= OR =/= OR =%=. + [[#h:7B5047E4-D6BD-47E0-8AC3-0BD8AB23AAD2][TermTypeExpression]]. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/type_expression.rs::fn parse_multiply_or_divide_or_modulo_type_expression(][parse_multiply_or_divide_or_modulo_type_expression()]] #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/type_expression.rs::65][MultiplyOrDivideOrModuloTypeExpression doc]] :lines 65-66 :src rust ******** TOIMPL TermTypeExpression :PROPERTIES: :CUSTOM_ID: h:7B5047E4-D6BD-47E0-8AC3-0BD8AB23AAD2 :END: :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-16 Sat 20:20] :END: - =-= by [[#h:7B5047E4-D6BD-47E0-8AC3-0BD8AB23AAD2][TermTypeExpression]]. - [[#h:5FA16AAC-EBDB-4764-B3DB-07AF284343E8][AtomTypeExpression]]. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/type_expression.rs::fn parse_term_type_expression(&mut self)][parse_term_type_expression()]] #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/type_expression.rs::111][TermTypeExpression doc]] :lines 111-113 :src rust *************** TODO In-code docs for TermTypeExpression minus missing a closing apostrophe Teeny tiny change, fix if not already done as it seems Noir is now at 0.38.0 so some updating will be required anyway. *************** END ********* TOIMPL AtomTypeExpression :PROPERTIES: :CUSTOM_ID: h:5FA16AAC-EBDB-4764-B3DB-07AF284343E8 :END: :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-16 Sat 20:20] :END: - [[#h:AD4F1A7F-721B-4864-AF9F-1383E974E0B2][ConstantTypeExpression]]. - [[#h:55482566-855D-4631-8E1F-7E540041E536][VariableTypeExpression]]. - [[#h:DA270219-6BFD-42AB-A9B2-4BF9241BAE9E][ParenthesizedTypeExpression]]. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/type_expression.rs::fn parse_atom_type_expression(&mut self)][parse_atom_type_expression()]] #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/type_expression.rs::139][AtomTypeExpression doc]] :lines 139-142 :src rust ********** TOIMPL ConstantTypeExpression :PROPERTIES: :CUSTOM_ID: h:AD4F1A7F-721B-4864-AF9F-1383E974E0B2 :END: :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-16 Sat 20:18] :END: + TERMINAL ~Token::Int~. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/type_expression.rs::fn parse_constant_type_expression(&mut self)][parse_constant_type_expression()]] #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/type_expression.rs::159][ConstantTypeExpression doc]] :lines 159-159 :src rust ********** TOIMPL VariableTypeExpression :PROPERTIES: :CUSTOM_ID: h:55482566-855D-4631-8E1F-7E540041E536 :END: :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-16 Sat 20:20] :END: + [[#h:07167116-EAE4-475B-8C87-DE9075BAF88D][Path]]. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/type_expression.rs::fn parse_variable_type_expression(&mut self)][parse_variable_type_expression()]] #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/type_expression.rs::168][VariableTypeExpression doc]] :lines 168-168 :src rust ********** TOIMPL ParenthesizedTypeExpression :PROPERTIES: :CUSTOM_ID: h:DA270219-6BFD-42AB-A9B2-4BF9241BAE9E :END: :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-16 Sat 20:20] :END: + =(=. + [[#h:0DEF3192-4840-41B3-A941-714798677092][TypeExpression]]. + =)=. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/type_expression.rs::fn parse_parenthesized_type_expression(&mut self)][parse_parenthesized_type_expression()]] #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/type_expression.rs::174][ParenthesizedTypeExpression doc]] :lines 174-174 :src rust ***** TODO Path :PROPERTIES: :CUSTOM_ID: h:07167116-EAE4-475B-8C87-DE9075BAF88D :END: + [[#h:96FCF9AD-3B89-451B-B84D-90A7A625B56D][PathKind]]. + ~Token::Ident~ as identifier. + (opt) [[#h:D0AD78D7-3BF6-4D89-A709-C8CD28968213][Turbofish]]. + (rep0 grp) =::= by ~Token::Ident~ as identifier by (opt) [[#h:D0AD78D7-3BF6-4D89-A709-C8CD28968213][Turbofish]]. In all cases where Path is parsed via mentioned parsers if there are no path segments None is returned; so **Path is implied optional wherever it occurs**. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/path.rs::pub(super) fn parse_path_impl(][parse_path_impl()]] (usually via [[file:noir/compiler/noirc_frontend/src/parser/parser/path.rs::pub(crate) fn parse_path(&mut self)][parse_path()]]) #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/path.rs::29][Path doc]] :lines 29-33 :src rust TODO: Have this generated from an org-mode dynamic block maybe? - [X] parse_path - [X] parse_path_impl - [X] parse_path_kind - [X] parse_optional_path_after_kind - [X] parse_path_after_kind - [X] parse_path_generics #+BEGIN: parser-callstack Path Turbofish PathNoTurbofish PathKind PathGenerics Internals #+END: *************** TODO Are PathNoTurboFish and PathTraitKind seperate Items in the parser (i.e. an Item like Path is an item)? If they are can reduce nesting complexity. *************** END ****** TODO Turbofish :PROPERTIES: :CUSTOM_ID: h:D0AD78D7-3BF6-4D89-A709-C8CD28968213 :FOO: [[file:noir/compiler/noirc_frontend/src/parser/parser/path.rs::pub(super) fn parse_path_impl(][parse_path_impl()]] :END: + =::=. + [[#h:F8EF693C-A6E2-4D57-BE08-103479D4270D][PathGenerics]]. ****** TODO PathNoTurbofish :PROPERTIES: :CUSTOM_ID: h:A051D0D5-7007-4DF8-83B7-FB4EFF9C383E :END: :note: - A /turbofish/ is syntax of the form ~::~. - Parse function called such that **trailing double colons are allowed**. :end: + PathKind. + An ~identifier~. + (rep0 grp) =::= by an ~identifier~. #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/path.rs::56][PathNoTurbofish doc]] :lines 55-55 :src rust - [-] ~Parser::parse_path_impl(false, true)~. - [X] ~Parser::parse_path_kind()~. - [ ] ~Parser::parse_optional_path_after_kind()~. - [ ] ~Parser::parse_path_after_kind()~. ****** BLOCK AsTraitPath :PROPERTIES: :CUSTOM_ID: h:348C4ABC-3FC0-46EC-95A0-7F4B238BB86A :END: :LOGBOOK: - State "BLOCK" from "TODO" [2024-11-16 Sat 18:10] \\ Type and PathNoTurbofish completion. :END: + =<=. + [[#h:B3490B7C-F387-49C7-BF94-DC9CE8AC3581][Type]]. + =as= (kw). + [[#h:A051D0D5-7007-4DF8-83B7-FB4EFF9C383E][PathNoTurbofish]]. + [[#h:3267D7A4-7AA4-49FB-91FA-A9601BC6868A][GenericTypeArgs]]. + =>=. + =::=. + ~Token::Ident~ as identifier. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/path.rs::pub(super) fn parse_as_trait_path(&mut self)][parse_as_trait_path()]] #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/path.rs::195][AsTraitPath doc]] :lines 195-195 :src rust Not to be confused with [[#h:5B4FDF39-09B2-4C07-A2B5-3A3D6BEDD4B7][AsTraitPathType]] which wraps the return in ~AST::UnresolvedType::AsTraitPath~, this node returns a ~AST::Statement::AsTraitPath~. This is the syntax spaghetti =::Bar= stuff. Specifically the =as Trait= part which leads to the associated type. *************** TODO Add or note the docs for AsTraitPath see ast statement.rs line 394 context. *************** END ****** TOIMPL PathKind :PROPERTIES: :CUSTOM_ID: h:96FCF9AD-3B89-451B-B84D-90A7A625B56D :END: :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-13 Wed 18:18] :END: - =crate= by =::=. - =dep= by =::=. - =super= by =::=. - NIL. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/path.rs::pub(super) fn parse_path_kind(&mut self)][parse_path_kind()]] #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/path.rs::174][PathKind doc]] :lines 174-178 :src rust If there is no path kind, i.e. NIL, this is internally represented via ~PathKind::Plain~. ****** TOIMPL PathGenerics :PROPERTIES: :CUSTOM_ID: h:F8EF693C-A6E2-4D57-BE08-103479D4270D :END: :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-13 Wed 19:28] :END: - [[#h:3267D7A4-7AA4-49FB-91FA-A9601BC6868A][GenericTypeArgs]]<[[#h:43662F12-2EC8-47E8-B5B8-DFF8A1226EB2][OrderedTypeArg]]>. Checks current token is ~Token::Less~ (=<=) before continuing. Only OrderedTypeArgs are allowed, any NamedTypeArgs (aka "associated types" are errors). Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/path.rs::pub(super) fn parse_path_generics(][parse_path_generics()]] #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/path.rs::157][PathGenerics doc]] :lines 157-157 :src rust Return ~AST::GenericTypeArg::Ordered~. *************** TODO Document in-code Noir that only OrderedGenerics are allowed. As the parsing function for PathGenerics shows, any NamedArgs will return a parser error. *************** END ****** Internals :noirc: [[file:noir/compiler/noirc_frontend/src/parser/parser/path.rs::pub(super) fn parse_path_after_kind(][parse_path_after_kind()]] Return ~AST::Path~. Make a segments vector and run the following as a loop: 1. Check ~Token::Ident~. 2. Parse generics ([[#h:F8EF693C-A6E2-4D57-BE08-103479D4270D][PathGenerics]]) with [[file:noir/compiler/noirc_frontend/src/parser/parser/path.rs::pub(super) fn parse_path_generics(][parse_path_generics()]] **if**: - Caller allows turbofish, AND - At ~Token::DoubleColon~, AND - Next token is ~Token::Less~ (=<=). 3. Add parsed generics as ~AST::PathSegment~ to segments. 4. Back to (1) if current token (will eat) is =::= and next is ~Token::Ident~, otherwise parser error (missing identifier). Return ~AST::Path~. ***** TODO Function :PROPERTIES: :CUSTOM_ID: h:B3C4609F-307A-42A1-B420-DBBAB6CDE6E5 :END: TODO: Reorganise this subtree since I added :treesit transclusion. ****** Treesitter :grammar: :PROPERTIES: :CUSTOM_ID: h:30A04BE4-E1C5-40E1-B2B2-DA0747C66D48 :END: ******* Definition #+begin_src js :comments noweb :treesit function_definition: ($) => seq( optional($.visibility_modifier), optional($.function_modifiers), 'fn', field('name', $.identifier), // TODO: Generics $.function_parameters, optional(seq('->' /* TODO: Return visibility and type */)), // TODO: Where clause $.block, // TODO: It's block or ';' see Parser::parse_function() ) // Yolo #+end_src ******* Modifiers #+begin_src js :treesit function_modifiers: ($) => repeat1(choice(MODIFIERS.Unconstrained, MODIFIERS.Comptime)) #+end_src ****** Noir + =fn= by ~identifier~ by [[#h:BA1422E4-AB97-4099-8346-5845CA9223A1][Generics]] by [[#h:B635EAF3-0AE1-47E0-8817-7174186912D8][FunctionParameters]]. + (opt group) =->= by ItemVisibility by Type + WhereClause by (group) - Block - =;= #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/function.rs::34][Parser::parse_function()]] :lines 34-34 :src rust TODO: Return visibility is seperate from function visibility. TODO: WhereClause isn't marked optional in Noir compiler, but it is. Mutable modifier =mut= not applicable; presence raises parse error. #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/item.rs::184][parse_item_kind() callsite]] :lines 184-194 :src rust TODO: Callstack and what not for...: TODO: transclude parse_function_definition or whatever is appropriate. TODO: transclude parse_function_definition_with_optional_body ***** TODO FunctionParameters :node: :PROPERTIES: :CUSTOM_ID: h:B635EAF3-0AE1-47E0-8817-7174186912D8 :END: + =(=. + (opt) FunctionParametersList. + =)=. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/function.rs::fn parse_function_parameters(&mut self, allow_self: bool)][parse_function_parameters()]] #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/function.rs][FunctionParameters doc]] :lines 129-133 :src rust TODO: Is ~FunctionParameters~ only used when _DECLARING_ a function or also when calling? If the former then this node can go under ~Function~ i.e. ~function_definition~. #+begin_src js function_parameters: ($) => seq( '(', // TODO: The rest. ')', ) #+end_src #+begin_src js :treesit t const foobar = 'yoloscoped' #+end_src ****** Subtrees also? #+begin_src js :treesit t const foobar = 'HOWDY' #+end_src ****** TODO FunctionParametersList :PROPERTIES: :CUSTOM_ID: h:D94BC382-4224-4FB5-8332-4C5CCF285946 :END: + FunctionParameter. + (rep0 grp) =,= by FunctionParameter. + (opt) =,=. Split by =,= until =)=, each parsed as FunctionParameter. #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/function.rs][parse_many()]] :lines 139-141 :src rust - [ ] [[#h:8E0DC05B-1ED6-47BE-9589-64DC06FAECCA][Parser::parse_many()]] - nb :: split on =,= until =)= encountered. - [ ] ~parse_function_parameter()~. ****** TODO FunctionParameter :PROPERTIES: :CUSTOM_ID: h:9554D746-C88F-4E3D-B065-B1A5C5F9B57B :END: + Visibility. (td: link) + PatternOrSelf. (td: link) + =:=. + Type. (td: link) Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/function.rs::fn parse_function_parameter(&mut self, allow_self: bool)][parse_function_parameter()]] ***** TODO Generics :node: :PROPERTIES: :CUSTOM_ID: h:BA1422E4-AB97-4099-8346-5845CA9223A1 :END: * (opt grp) =<= by (opt) GenericsList by =>=. [[file:noir/compiler/noirc_frontend/src/parser/parser/generics.rs::16][Parser::parse_generics()]]: #+begin_src rust /// Generics = ( '<' GenericsList? '>' )? /// /// GenericsList = Generic ( ',' Generic )* ','? #+end_src - [X] ~Parser:parse_many()~. - nb :: splits on =,= until =>= encountered. - [ ] ~Parser:parse_generic_in_list()~. - [ ] ~Parser::parse_generic()~. ****** TODO GenericsList + Generic. + (rep0 grp) =,= by Generic. + (opt) =,=. ****** TODO Generic - VariableGeneric. - NumericGeneric. - ResolvedGeneric. [[file:noir/compiler/noirc_frontend/src/parser/parser/generics.rs::41][Parser::parse_generic()]]: #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/generics.rs][Generic doc]] :lines 37-40 :src rust ****** TOIMPL VariableGeneric :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-03 Sun 05:25] :END: * An ~identifier~. [[file:noir/compiler/noirc_frontend/src/parser/parser/generics.rs::58][Parser::parse_variable_generic()]]: #+begin_src rust /// VariableGeneric = identifier #+end_src Calls ~Parser::eat_ident()~ and returns that as an ~UnresolvedGeneric::Variable~ enum. *************** TODO Appears to be some wacky macro stuff for enum ~UnresolvedGeneric~, look at way, way later. *************** END ****** TOIMPL NumericGeneric :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-03 Sun 05:26] :END: + =let=. + An ~identifier~. + =:=. + Type. [[file:noir/compiler/noirc_frontend/src/parser/parser/generics.rs::63][Parser::parse_numeric_generic()]]: #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/generics.rs][NumericGeneric doc]] :lines 62-62 :src rust *************** TODO Parse function returns an error if missing a type after =:= (and assumes type is ~u32~) but is this error fatal? *************** END *************** TODO There's some forbidden numeric generic type logic there, look at later. *************** END ****** TODO ResolvedGeneric Foo ****** TOIMPL GenericTypeArgs :node: :PROPERTIES: :CUSTOM_ID: h:3267D7A4-7AA4-49FB-91FA-A9601BC6868A :END: :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-13 Wed 19:10] :END: + (grp) =<= by (opt) [[#h:8C6AF1F0-DBAC-4030-AEFC-8FBF6B069EAD][GenericTypeArgsList]] by =>=. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/generics.rs::pub(super) fn parse_generic_type_args(&mut self)][parse_generic_type_args()]] #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/generics.rs::106][GenericTypeArgs doc]] :lines 106-116 :src rust Return ~AST::GenericTypeArgs()~. ******* TOIMPL GenericTypeArgsList :PROPERTIES: :CUSTOM_ID: h:8C6AF1F0-DBAC-4030-AEFC-8FBF6B069EAD :END: :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-13 Wed 19:09] :END: + [[#h:B2EDBA96-AA93-449F-A8EB-5636CCFC4F1C][GenericTypeArg]]. + (rep0 grp) =,= by [[#h:B2EDBA96-AA93-449F-A8EB-5636CCFC4F1C][GenericTypeArg]]. + (opt) =,=. Split by =,= until =>=, each parsed as [[#h:B2EDBA96-AA93-449F-A8EB-5636CCFC4F1C][GenericTypeArg]]. #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/generics.rs::123][parse_many()]] :lines 123-127 :src rust ******* TOIMPL GenericTypeArg :PROPERTIES: :CUSTOM_ID: h:B2EDBA96-AA93-449F-A8EB-5636CCFC4F1C :END: :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-13 Wed 19:07] :END: - [[#h:8314C368-924E-4B8B-A881-66C9F46D6833][NamedTypeArg]]. - [[#h:43662F12-2EC8-47E8-B5B8-DFF8A1226EB2][OrderedTypeArg]]. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/generics.rs::fn parse_generic_type_arg(&mut self)][parse_generic_type_arg()]] (inline handles child nodes). ******** TOIMPL NamedTypeArg :PROPERTIES: :CUSTOM_ID: h:8314C368-924E-4B8B-A881-66C9F46D6833 :END: :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-13 Wed 18:56] :END: + ~Token::Ident~ as identifier. + ===. + [[#h:B3490B7C-F387-49C7-BF94-DC9CE8AC3581][Type]]. Also called "associated types". Parser: /within slice of parent/ #+transclude: [[file:noir/compiler/noirc_frontend/src/ast/mod.rs::187][NamedTypeArg doc]] :lines 187-188 :src rust Return ~AST::GenericTypeArg::Named()~. Call to Type wrapped in ~parse_type_or_error~. ******** TOIMPL OrderedTypeArg :PROPERTIES: :CUSTOM_ID: h:43662F12-2EC8-47E8-B5B8-DFF8A1226EB2 :END: :LOGBOOK: - State "TOIMPL" from "TODO" [2024-11-13 Wed 18:56] :END: + [[#h:A32A351C-092B-42F1-AB03-DE49862B35D4][TypeOrTypeExpression]]. Parser: /within slice of parent/ #+transclude: [[file:noir/compiler/noirc_frontend/src/ast/mod.rs::184][OrderedTypeArg doc]] :lines 184-184 :src rust Return ~AST::GenericTypeArg::Ordered()~. ***** TODO WhereClause :declaration: Treesitter ~seq~ captures rule ordering, and custom ~sepBy1~ enforces /at least/ one occurrence of our ~$.where_clause_item~ rule so the nesting of the rule definitions from the Noir compiler need *not* be replicated for ~$.where_clause_item~. *************** TODO WhereClause Treesitter :grammar: #+begin_src js where_clause: ($) => seq( 'where', sepBy1($.where_clause_item, ','), optional(',') ) #+end_src *************** END + =where= + (opt) WhereClauseItems #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/where_clause.rs::18][WhereClause doc]] :lines 13-17 :src rust ****** TODO WhereClauseItems *************** TODO WhereClauseItems Treesitter :grammar: #+begin_src js where_clause_item: ($) => seq( $.type, ':', $.trait_bound, ) #+end_src *************** END + WhereClauseItem + (rep0 grp) =,= by WhereClauseItem + (opt) =,= ****** TODO WhereClauseItem + Type + =:= + TraitBounds ****** TODO TraitBounds + TraitBound. + (opt grp) =+= by TraitBound. + (opt) =+=. #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/where_clause.rs::51][TraitBounds doc]] :lines 50-50 :src rust ****** TODO TraitBound *************** TODO TraitBound Treesitter :grammar: #+begin_src js trait_bound: ($) => #+end_src *************** END + PathNoTurbofish + GenericTypeArgs ***** TODO PatternOrSelf :PROPERTIES: :CUSTOM_ID: h:464E9BE0-4EC7-4D73-A1F2-F9C581DFD8E3 :END: - Pattern. - SelfPattern. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::pub(crate) fn parse_pattern_or_self(&mut self)][parse_pattern_or_self()]] #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::43][PatternOrSelf doc]] :lines 43-45 :src rust *************** TODO Where does this Pattern node actually belong hierarchically? It's probably not an ~ItemKind~ as I've temporarily placed it. Locate it elsewhere when appropriate. The top level node (unto itself) here is also ~PatternOrSelf~ and not ~Pattern~ since the former contains all of the latter. Probably a proper technical set or graph theory term for this. *************** END FOR JORDAN: Currently looking at SelfPattern FOR JORDAN: Given we've only reached here via function declaration (SO FAR) the current parent for this entire call stack is ~parse_function_parameter~. I expect this won't be the case when all the frontend is explored so adjust accordingly then. =parse_function_parameter= callstack: - [ ] parse_pattern_or_self and [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::pub(crate) fn parse_pattern(&mut self)][parse_pattern()]] - [ ] [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::pub(crate) fn parse_pattern_after_modifiers(][parse_pattern_after_modifiers()]] - [ ] [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::fn parse_pattern_no_mut(&mut self)][parse_pattern_no_mut()]] /(see: PatternNoMut)/ - [ ] If ~Pattern~ call [[file:noir/compiler/noirc_frontend/src/parser/parser/function.rs::fn pattern_param(&mut self, pattern: Pattern, start_span: Span)][pattern_param()]] - [X] If ~SelfPattern~ call [[file:noir/compiler/noirc_frontend/src/parser/parser/function.rs::fn self_pattern_param(&mut self, self_pattern: SelfPattern)][self_pattern_param()]] - [ ] Parameter parsing entry: ~parse_function_parameter~. =parse_pattern_or_self= TODO: This specific function looks to guarantee only that SelfPattern is =self=, =&self=, or =&mut self=?? So what about =mut self=?? TODO: In-code docs on SelfPattern are wrong, parser logic looks likt it parses =self=, =mut self=, and =&mut self= so what about =&self=? Standard case: 1. Check next token is not =:= /token/, then; 2. Eat current token as a ~Token::Ident~ if its literal text is =self=. :note: Remember when a token is /eaten/ successfully the parser advances to the subsequent token afterwards. :end: PatternOrSelf forms checked in increasing complexity, absent condition checks fall through: - Standard case is checked. - pass :: SelfPattern =self=. #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::49][parse SelfPattern `self`]] :lines 49-54 :src rust - Eat /keyword/ =mut= and then check standard case. - pass :: SelfPattern =mut self=. - fail :: Pattern. #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::56][parse either {Self}Pattern `mut self`]] :lines 56-67 :src rust - Eat /token/ =&= and eat /keyword/ =mut= and then check standard case. - pass :: SelfPattern =&mut self=. - fail :: Pattern. /also pushes parser error ~RefMutCanOnlyBeUsedWithSelf~/. - All other (fall through) cases yield Pattern. In all cases Pattern is further parsed by call to ~parse_pattern_after_modifiers~. TOOD: This isn't the end of the pattern parsing logic though, it goes up elsewhere. It's quite strange. =parse_pattern_after_modifiers= =parse_pattern= Eat keyword =mut= and call parse_pattern_after_modifiers =pattern_param= =self_pattern_param= This function isn't important for deriving treesitter grammar, it concerns AST creation no further parsing (that we care about) is performed. It is (by the author's curiosity) however documented: Constructs a concrete ~AST::Param~ expression from ~SelfPattern~; when constructed this way ~SelfPattern~ is /always/ ~Visibility::Private~. #+transclude: [[file:noir/compiler/noirc_frontend/src/ast/expression.rs::516][Param AST]] :lines 516-521 :src rust TODO: Put the whole schpeel about ~UnresolvedTypeData~ somewhere else? TODO: Document that these structs are being declared inline of the ~UnresolvedTypeData~ enum, it's not like they exist elsewhere and are being referenced. This is a Rust thing. The Noir parser will parse any types (which are enumerants of ~UnresolvedTypeData~) as ~UnresolvedType~ which marks them as requiring name resolution; these are otherwise identical to ~Type~s. #+transclude: [[file:noir/compiler/noirc_frontend/src/ast/mod.rs::104][AST UnresolvedType doc]] :lines 104-106 :src rust #+transclude: [[file:noir/compiler/noirc_frontend/src/ast/mod.rs::161][AST UnresolvedType enum]] :lines 160-163 :src rust #+transclude: [[file:noir/compiler/noirc_frontend/src/ast/mod.rs::109][AST UnresolvedTypeData enumerants]] :lines 109-156 :src rust TODO: Currently on plane, what /exactly/ is Rust's ~Box~ doing? :verbose: 1. Construct an ~AST::UnresolvedType::Named~ with =Self= ~AST::Path~; then box the entire aforementioned into an ~AST::UnresolvedType::MutableReference~ iff given ~SelfPattern~ contained =&= (i.e. a reference). 2. Construct an ~AST::Pattern::Identifier~ with =self= ~AST::Ident~; then box the entire aforementioned into an ~AST::Pattern::Mutable~ iff given ~SelfPattern~ contained =mut= (i.e. mutable). 3. Return ~AST::Param~ which contains (1) and (2). :end: ****** TODO Pattern :PROPERTIES: :CUSTOM_ID: h:D349E307-F033-4D2A-A729-F2EE5B483065 :END: + (opt) =mut=. + [[#h:4A5BB563-4244-4B1F-8084-1116B58FA40F][PatternNoMut]]. TODO: Update Noir in-code docs, mut is actually optional. i.e. literal in-code Noir docs should say ='mut'?= and not ='mut'=. #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::35][Pattern doc]] :lines 35-36 :src rust ******* TODO PatternNoMut :PROPERTIES: :CUSTOM_ID: h:4A5BB563-4244-4B1F-8084-1116B58FA40F :END: - [[#h:BA807BCE-99B0-4D84-BDC5-613C20F4A422][InternedPattern]]. - [[#h:5EC2C25E-781B-4AA1-B01B-D37B761237F8][TupplePattern]]. - [[#h:44A2D194-B244-4E4C-B53E-2FCF3F4165E2][StructPattern]]. - [[#h:CE58024C-51AD-4A68-A57B-CE4E6D5C0552][IdentifierPattern]]. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::fn parse_pattern_no_mut(&mut self)][parse_pattern_no_mut()]] #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::112][PatternNoMut doc]] :lines 112-116 :src rust ******* TODO InternedPattern :PROPERTIES: :CUSTOM_ID: h:BA807BCE-99B0-4D84-BDC5-613C20F4A422 :END: - TERMINAL ~TokenKind::InternedPattern~. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::fn parse_interned_pattern(&mut self)][parse_interned_pattern()]] Eat token ~TokenKind::InternedPattern~ and get it's literal contents. If contents is indexable in ~noirc_arena~ (i.e. its been interned) then return ~AST::Pattern::Interned~. TODO: I spent like 1 hour on the flight to BKK while really tired trying to figure out how the fuck ~TokenKind::InternedPattern~ is assigned and I see no way, maybe it's not even in-use yet or some satanic shit is involved here. Leave it for now I guess. TODO: How does the lexer assign ~TokenKind::InternedPattern~? Once that's known this node is done. TODO: TokenKind::InternedPattern (TODO) ~InteredPattern~ is a reference to an interned ~Pattern~. TODO: So a ~Spanned~ 's ~contents~ are the literal source-code buffers content for the byte region the span defines. TODO: As per the top of node_interner.rs an InternedPattern is one that is encountered specifically at comptime (i.e. in a comptime block?) ******* BLOCK TupplePattern :PROPERTIES: :CUSTOM_ID: h:5EC2C25E-781B-4AA1-B01B-D37B761237F8 :END: :LOGBOOK: - State "BLOCK" from "TODO" [2024-11-13 Wed 02:23] \\ Until Path. :END: + =(=. + (opt) [[#h:3C5C665F-CB91-4C4E-9B39-ACFEE421F5DB][PatternList]]. + =)=. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::fn parse_tuple_pattern(&mut self)][parse_tuple_pattern()]] #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::169][TuplePattern doc]] :lines 169-171 :src rust Return ~AST::Pattern::Tuple()~. ******** BLOCK PatternList :PROPERTIES: :CUSTOM_ID: h:3C5C665F-CB91-4C4E-9B39-ACFEE421F5DB :END: :LOGBOOK: - State "BLOCK" from "TODO" [2024-11-13 Wed 02:22] \\ Until Path. :END: + [[#h:D349E307-F033-4D2A-A729-F2EE5B483065][Pattern]]. + (rep0 grp) =,= by [[#h:D349E307-F033-4D2A-A729-F2EE5B483065][Pattern]]. + (opt) =,=. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::fn parse_tuple_pattern_element(&mut self)][parse_tuple_pattern_element()]] Split by =,= until =)=, each parsed as [[#h:D349E307-F033-4D2A-A729-F2EE5B483065][Pattern]] via *recursive* call to ~parse_pattern~. #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::179][parse_many()]] :lines 179-183 :src rust *************** TODO This can be marked TOIMPL when all others under Pattern are, since this recurses. *************** END ******* BLOCK StructPattern :PROPERTIES: :CUSTOM_ID: h:44A2D194-B244-4E4C-B53E-2FCF3F4165E2 :END: :LOGBOOK: - State "BLOCK" from "TODO" [2024-11-13 Wed 02:22] \\ Until Path is complete. :END: + (opt) [[#h:07167116-EAE4-475B-8C87-DE9075BAF88D][Path]]. + ={=. + (opt) [[#h:AD401294-1A53-405B-9717-6818B89FF22E][StructPatternFields]]. + =}=. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::fn parse_struct_pattern(&mut self, path: Path, start_span: Span)][parse_struct_pattern()]] #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::197][StructPattern doc]] :lines 197-201 :src rust Return ~AST::Pattern::Struct()~. *************** TODO Before parse_struct_pattern is called parser wants to parse an entire path via parse_path, gotta finish paths before considering how that affects this now. I'm on the plane so wicked tired, I don't think it will really since if there's no path the first argument to parse_struct_pattern is None. Idk how it wanting a left brace before calling will affect things UNLESS left braces have never _technically_ been part of paths this entire time, i.e. use foo::bar::{lorem} the path is actually `foo::bar` with the _pattern_ being `{lorem}` even though i (and probably others??) would consider that `foo::bar::{lorem}` is the entire path. *************** END ******** BLOCK StructPatternFields :PROPERTIES: :CUSTOM_ID: h:AD401294-1A53-405B-9717-6818B89FF22E :END: :LOGBOOK: - State "BLOCK" from "TODO" [2024-11-13 Wed 02:21] \\ Requires all of Pattern which itself has a dependency on Path which is TODO. :END: + [[#h:E4A5FB8F-3DEF-4AA2-8457-E7DE648EC0F4][StructPatternField]]. + (rep0 grp) =,= by [[#h:E4A5FB8F-3DEF-4AA2-8457-E7DE648EC0F4][StructPatternField]]. + (opt) =,=. Split by =,= until =}=, each parsed as [[#h:E4A5FB8F-3DEF-4AA2-8457-E7DE648EC0F4][StructPatternField]]. #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::203][parse_many()]] :lines 203-207 :src rust *************** TODO Update in-code Noir docs for StructPatternFields The question mark in the grouping should be an asterisk no? *************** END ******** BLOCK StructPatternField :PROPERTIES: :CUSTOM_ID: h:E4A5FB8F-3DEF-4AA2-8457-E7DE648EC0F4 :END: :LOGBOOK: - State "BLOCK" from "TODO" [2024-11-13 Wed 02:22] \\ Until Path is completed. :END: + ~Token::Ident~ as identifier. + (opt grp) =:= by [[#h:D349E307-F033-4D2A-A729-F2EE5B483065][Pattern]]. Parser: [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::fn parse_struct_pattern_field(&mut self)][parse_struct_pattern_field()]] ******* TODO IdentifierPattern :PROPERTIES: :CUSTOM_ID: h:CE58024C-51AD-4A68-A57B-CE4E6D5C0552 :END: - ~identifier~. FOR JORDAN: IdentifierPattern is yielded if none of PatternNoMut parsed and is_ident returned true. FOR JORDAN: This needs Path finished before it can be used. #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::118][IdentifierPattern doc]] :lines 118-118 :src rust Return ~AST::Pattern::Identifier()~. ****** TODO SelfPattern :PROPERTIES: :CUSTOM_ID: h:5B14A337-12EC-477C-8269-961094FAB41B :END: - =self=. - =&self=. - =mut self=. - =&mut self=. Parser: /within slice of [[#h:464E9BE0-4EC7-4D73-A1F2-F9C581DFD8E3][PatternOrSelf]]'s/. #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/pattern.rs::19][SelfPattern doc]] :lines 19-19 :src rust *************** TODO Update upstream in-code docs if =mut self= is in-fact valid? In-code don't suggest so but parser logic (thus far) says it is. *************** END :note: TODO: Claim sounds dubious based on doc comments, test if unclear when TOIMPL status. Guaranteed to NOT have a colon =:= following it. =self= is not a true keyword as it is contextual. #+transclude: [[file:noir/compiler/noirc_frontend/src/lexer/token.rs::1093][`self` is not a keyword]] :lines 1093-1094 :src rust :end: ** Internal *** [[file:noir/compiler/noirc_frontend/src/parser/parser/parse_many.rs::9][Parser::parse_many(items, sep)]] :PROPERTIES: :CUSTOM_ID: h:8E0DC05B-1ED6-47BE-9589-64DC06FAECCA :END: Parses list of items separated by sep, can optionally end when another (different configurable) separator is found. - [ ] ~Parser::parse_many_return_trailing_separator_if_any()~. TODO: Don't think I need to document parse_many_return blah blah, that's a compiler implementation detail (unless in future we have problems relating to it). * Grammar :PROPERTIES: :header-args: :noweb-sep ",\n\n" :END: Constructed grammar from investigating Noir compiler frontend. #+begin_src js :noweb yes :tangle hithere.js <> <> module.exports = grammar({ name: 'noir', extras: ($) => [/\s/], word: ($) => $.identifier, rules: { source_file: ($) => repeat($._statement), _statement: ($) => choice($._expression_statement, $._declaration_statement), _expression_statement: ($) => seq($._expression, ';'), _declaration_statement: ($) => choice($.function_definition), _expression: ($) => 'foo', // * * * * * * * * * * * * * * * * * * * * * * * * * DECLARATIONS <>, // * * * * * * * * * * * * * * * * * * * * * * * * * EXPRESSIONS <>, }, }) // Match one or more occurrences of rule separated by sep. function sepBy1(rule, sep) { return seq(rule, repeat(seq(sep, rule))) } #+end_src *** Declarations :PROPERTIES: :header-args+: :noweb-ref Declarations :END: **** FunctionParameters #+transclude: [[#h:B635EAF3-0AE1-47E0-8817-7174186912D8]] :treesit **** ItemVisibility #+transclude: [[#h:46B8EF89-89A5-4346-9B5B-04630DAEF262][ItemVisibility]] :treesit **** Function #+transclude: [[#h:30A04BE4-E1C5-40E1-B2B2-DA0747C66D48][Definition / Modifiers]] :treesit *** Expressions :PROPERTIES: :header-args+: :noweb-ref Expressions :END: #+begin_src js foo #+end_src * TODO Old stuff bin or categorise ** TODO Attribute Document attributes. Note too that SecondaryAttributes can have a tag see 957 in token.rs ***** TODO Top-level statement :node: - [[Function definition]]. - Struct definition. - Trait definition. - Trait implementation. - [[Implementation]]. - Submodule. - Contract. - Module declaration. - Use statement. - Global declaration. #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser.rs][top_level_statement_kind()]] :lines 144-170 :src rust ****** TODO Function definition + [[Function modifiers]] + Function keyword =fn= + [[Identifier]] + Generics + Function parameters (TODO: That ~parenthesized~ function call) + Function return type + Where clause + Fresh statement (TODO: That spanned block function call) TODO: Attributes?? Source file line `attributes()`. Parser: #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/function.rs][function_definition()]] :lines 30-76 :src rust ******* TODO Function modifiers Ordered: 1. Keyword =unconstrained= 2. [[Visibility]] 3. [[Comptime]] #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/function.rs][function_modifiers()]] :lines 78-85 :src rust ******* TODO Function parameters ******* TODO Function return type ******* TODO Fresh statement What is this? ****** TODO Struct definition + Identifier + Parse type Parser: #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/structs.rs][struct_definition()]] :lines 18-41 :src rust Parser: #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/structs.rs][struct_fields()]] :lines 43-49 :src rust ****** Trait definition ****** Trait implementation ****** Implementation + Non-trait implementation, add a set of methods to a type. + Must contain 1 or more valid function definitions. Parser: #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser.rs]] :lines 219-232 :src rust ****** Submodule ****** Contract ****** Module declaration ****** Use statement ****** Global declaration ** Auxiliary *** TODO Parse type TODO: This is where Noir's recursive definitions stuff is too. Parser: #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser.rs]] :lines 675-697 :src rust *** TODO Generic *** TODO Where clause *** TODO Visibility Handles both crate visibility and /other/ visibility. *************** TODO Crates 1. Keyword =pub= 2. Token =(= 3. Keyword =crate= 4. Token =)= *************** END *************** DONE Other :leaf: CLOSED: [2024-09-23 Mon 18:34] :LOGBOOK: - State "DONE" from "TODO" [2024-09-23 Mon 18:34] :END: 1. Keyword =pub= Parser: #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/visibility.rs][item_visibility()]] :lines 14-27 :src rust *************** END *** TODO Comptime :leaf: - State "TODO" from "DONE" [2024-09-24 Tue 19:57] \\ update noir version :LOGBOOK: - State "DONE" from "TODO" [2024-09-23 Mon 18:37] :END: 1. Keyword =comptime= Parser: #+transclude: [[file:noir/compiler/noirc_frontend/src/parser/parser/types.rs]] :lines 14-20 :src rust *** TODO Identifier =lexer/lexer.rs= https://github.com/noir-lang/noir/blob/a3bb09ebe2df473d4a34a34fbfc3966ffbc630cb/compiler/noirc_frontend/src/lexer/lexer.rs#L318-L355 ~Lexer::eat_word~ -> { ~Lexer::lex_word~, ~Lexer::lookup_word_token~ } -> identifier-or-not ~lex_word~ accumulates characters as long as they are: ~[a-z0-9_]~ (in source: ascii alphabetic, numeric, or _). ~lookup_word_token~ receives from ~lex_word~ the span of such a sequence of characters. To determine if /span/ of text is an identifier, check: 1. If it's an exact match to a keyword enum: ~Keyword::lookup_keyword~. 2. If it can be parsed as an integer type: ~IntType::lookup_int_type~. If these checks fail then it is an identifier. TODO: But valid identifiers further narrowed to this Regex (Chumsky ident): ~[a-zA-Z_][a-zA-Z0-9_]*~ TODO: I asked for clarification in Noir's Discord here: https://discord.com/channels/1113924620781883405/1260852401955536927 *** ~lookup_int_type~ =lexer/token.rs= https://github.com/noir-lang/noir/blob/a3bb09ebe2df473d4a34a34fbfc3966ffbc630cb/compiler/noirc_frontend/src/lexer/token.rs#L509-L532 Determined by checking: 1. Start with ~i~ or ~u~, comprised of only integers afterwards. If (1) fails then it is /not/ an integer /type/ (does not mean it's not an integer /literal/). ** Lexing - Whitespace not relevant: https://github.com/noir-lang/noir/blob/af57471035e4fa7eaffa71693219df6d029dbcde/compiler/noirc_frontend/src/lexer/lexer.rs#L584-L589 - TODO: However, it must be in certain contexts (e.g. a string). - Code whitespace: ~'\t'~, ~'\n'~, ~'\r'~, ~' '~: https://github.com/noir-lang/noir/blob/af57471035e4fa7eaffa71693219df6d029dbcde/compiler/noirc_frontend/src/lexer/lexer.rs#L580-L582 *** Keywords =lexer/token.rs= https://github.com/noir-lang/noir/blob/a3bb09ebe2df473d4a34a34fbfc3966ffbc630cb/compiler/noirc_frontend/src/lexer/token.rs#L927-L969 TODO: Checklist of implemented keywords. ** Parsing *** Modifiers **** General ***** Visibility ~pub~ applies generally. TODO: function.rs 56-68 TODO: How it applies to crates. TODO: Cannot have a function called ~pub~ right? **** Function-specific ***** Unconstrained ~unconstrained~ applies optionally before general-visibility. TODO: function.rs 73-81 TODO: Cannot have a function called ~unconstrained~ right? ***** Comptime TODO: Does the order come from? https://github.com/noir-lang/noir/blob/af57471035e4fa7eaffa71693219df6d029dbcde/compiler/noirc_frontend/src/parser/parser/function.rs#L41-L43 TODO: TODO: In later versions, unsure of how applicable this is to the current language version. TODO: Is it actually function-specific or can it be any statement? TODO: Cannot have a function called ~comptime~ right? * Temp bin TODOs and what not (temporary). *************** TODO Prevent =node= and =leaf= tags from overlapping So, if a parent headline has a =node= tag (or inherits one) and a child headline has a =leaf= tag then the =leaf= tag should not inherit (specifically) the =node= tag; it can continue to inherit others. Or ignore that since technically a leaf is a type of node. *************** END *************** TODO Nargo CLI test langauge grammar? Internal CLI to test Noir language grammar stuff? See how the current noir frontend compiler test suite is set up, want a nice way to run the tests alongside any tree-sitter stuff too. *************** END *************** TODO tree-sitter CLI check all syntax examples? Have the tree-sitter CLI check all syntax examples in a test marked :error do error, think about this though because technically each test case reads all the input as a single file. *************** END *************** TODO dynamic checkboxes? Have the following checkbox list created dynamically from headings, and also link to said headings. *************** END *************** TODO tree-sitter anonymous node queries When writing queries eventually, can use anonymous node queries also e.g. ~(function_modifiers "foo")~. *************** END # Local Variables: # org-todo-keyword-faces: ( # ("TOIMPL" . org-warning) # ("BLOCK" . org-verbatim)) # org-babel-header-args:js: '((treesit . :any)) # End: