| 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 |
|