| 1 | 
 | 
| 2 | # Tea can run a limited form of procs.  The first word must be a name, and NO
 | 
| 3 | # BARE WORDS.
 | 
| 4 | #
 | 
| 5 | # Example:
 | 
| 6 | #   log "hello $name"       # valid in OSH, YSH, Tea
 | 
| 7 | #   myproc $(hostname)      # ditto
 | 
| 8 | #
 | 
| 9 | #   my-proc '/' $foo        # OSH and YSH
 | 
| 10 | #   run 'my-proc' '/' $foo  # Tea.  'run' is similar to 'command' and 'builtin'
 | 
| 11 | #
 | 
| 12 | 
 | 
| 13 | tea_word: (
 | 
| 14 |     dq_string | sq_string
 | 
| 15 |   | sh_command_sub | braced_var_sub | simple_var_sub
 | 
| 16 | )
 | 
| 17 | 
 | 
| 18 | type_expr_list: type_expr (',' type_expr)*
 | 
| 19 | 
 | 
| 20 | # Note: It may make sense to have ; here, for named params only!
 | 
| 21 | data_params: (param ',')* [ param [','] ]
 | 
| 22 | 
 | 
| 23 | # zero params allowed for consistency with func and class?
 | 
| 24 | tea_data: Expr_Name '(' [data_params] ')'
 | 
| 25 | 
 | 
| 26 | # e.g. Nullary %Token or Nullary(x Int)
 | 
| 27 | variant_type: Expr_Symbol | '(' data_params ')' 
 | 
| 28 | variant: Expr_Name [ variant_type ]
 | 
| 29 | 
 | 
| 30 | #
 | 
| 31 | # Experimental "Tea" stuff
 | 
| 32 | #
 | 
| 33 | # It also needs:
 | 
| 34 | # - cast expressions.  Although cast(Int, foo) works I suppose.  It feels like
 | 
| 35 | #   it has a runtime cost
 | 
| 36 | 
 | 
| 37 | tea_enum: (
 | 
| 38 |   Expr_Name '{' [Op_Newline]
 | 
| 39 |   # note: braces can be empty
 | 
| 40 |   [ variant (comma_newline variant)* [comma_newline] ]
 | 
| 41 |   '}'
 | 
| 42 | )
 | 
| 43 | 
 | 
| 44 | suite: '{' [Op_Newline] [func_items] '}'
 | 
| 45 | 
 | 
| 46 | func_item: (
 | 
| 47 |   ('var' | 'const') name_type_list '=' testlist  # ysh_var_decl
 | 
| 48 | 
 | 
| 49 |   # TODO: if/switch, with, try/except/throw, etc.
 | 
| 50 | | 'while' test suite
 | 
| 51 | | 'for' name_type_list 'in' test suite
 | 
| 52 | 
 | 
| 53 |   # In Python, imports, assert, etc. also at this 'small_stmt' level
 | 
| 54 | | 'break' | 'continue' | 'return' [testlist]
 | 
| 55 | 
 | 
| 56 |   # TODO: accept setvar for consistency with YSH?
 | 
| 57 | | 'set' place_list (augassign | '=') testlist  # ysh_place_mutation
 | 
| 58 |   # x  f(x)  etc.
 | 
| 59 |   #
 | 
| 60 |   # And x = 1.  Python uses the same "hack" to fit within pgen2.  It also
 | 
| 61 |   # supports a = b = 1, which we don't want.
 | 
| 62 |   #
 | 
| 63 |   # And echo 'hi' 'there'
 | 
| 64 |   #
 | 
| 65 |   # TODO: expr_to_ast needs to validate this
 | 
| 66 | | testlist (['=' testlist] | tea_word*)
 | 
| 67 | )
 | 
| 68 | 
 | 
| 69 | # we want to avoid requiring newline or ; before }
 | 
| 70 | func_items: func_item (semi_newline func_item)* [semi_newline]
 | 
| 71 | 
 | 
| 72 | # This is anonymous
 | 
| 73 | tea_func: (
 | 
| 74 |   '(' [param_group] [';' param_group] ')' [type_expr_list]
 | 
| 75 |   suite
 | 
| 76 | )
 | 
| 77 | named_func: Expr_Name tea_func
 | 
| 78 | 
 | 
| 79 | # TODO: Methods differ from functions:
 | 
| 80 | #  super() can be the first arg
 | 
| 81 | #  shortcut initializer: Parser(this.lexer) { }
 | 
| 82 | #  abstract, override, virtual
 | 
| 83 | #  should we allow annotations, like 'public' or 'export'?
 | 
| 84 | # 
 | 
| 85 | # No field initializers for now.  Later C++ versions allow it.
 | 
| 86 | #
 | 
| 87 | # Annotations:
 | 
| 88 | #
 | 
| 89 | # func Parse() Int
 | 
| 90 | #   [override const abstract] {
 | 
| 91 | # } ?
 | 
| 92 | 
 | 
| 93 | class_item: (
 | 
| 94 |   ('virtual' | 'override' | 'func' | 'abstract' ) Expr_Name tea_func
 | 
| 95 |   # Member declaration
 | 
| 96 | | 'var' name_type_list
 | 
| 97 | )
 | 
| 98 | 
 | 
| 99 | # Note: we could restrict separators to newlines.
 | 
| 100 | # But then you couldn't do class Foo { var a; var b }
 | 
| 101 | class_items: class_item (semi_newline class_item)* [semi_newline] 
 | 
| 102 | 
 | 
| 103 | tea_class: Expr_Name [':' Expr_Name ] '{' [Op_Newline] [class_items] '}'
 | 
| 104 | 
 | 
| 105 | # 'import' can't use 'semi_newline' because ending with an unknown number of
 | 
| 106 | # tokens doesn't compose with our CommandParser.
 | 
| 107 | end_import: ';' | Op_Newline
 | 
| 108 | 
 | 
| 109 | import_name: Expr_Name ['as' Expr_Name]
 | 
| 110 | import_names: import_name (comma_newline import_name)* [import_name]
 | 
| 111 | 
 | 
| 112 | # TODO: Should we have a simpler YSH string literal?
 | 
| 113 | tea_import: sq_string [ 'as' Expr_Name ] ['(' [Op_Newline] [import_names] ')'] end_import
 | 
| 114 | 
 | 
| 115 | # Top level:
 | 
| 116 | # declarations of constants -- with const only?
 | 
| 117 | # maybe only const?
 | 
| 118 | # use, data, enum, class, func.  That's it?  OK.
 | 
| 119 | 
 | 
| 120 | end_outer: ';' [Op_Newline] | Op_Newline | Eof_Real
 | 
| 121 | 
 | 
| 122 | module_item: (
 | 
| 123 |   # ysh_var_decl, but no mutation
 | 
| 124 |   ('var' | 'const') name_type_list '=' testlist end_outer
 | 
| 125 | | 'import' tea_import  # TODO: needs Eof_Real
 | 
| 126 |   # Also 'export'
 | 
| 127 | | 'class' tea_class end_outer
 | 
| 128 | | 'data' tea_data end_outer
 | 
| 129 | | 'enum' tea_enum end_outer
 | 
| 130 | | 'func' Expr_Name tea_func end_outer
 | 
| 131 | 
 | 
| 132 |   # Might need: typedef?  Or typealias?
 | 
| 133 | )
 | 
| 134 | 
 | 
| 135 | # Eof_Real either after newline or before newline are both valid
 | 
| 136 | tea_module: [Op_Newline] module_item* [Eof_Real]
 | 
| 137 | 
 |