# Copyright 2019 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Grammer tree for Halide IR

# Symbol explanation:
# [sym] : 'sym' may or may not appear
# |     : or
# (sym) : higher order
# sym*  : sym may appear 0 or more times,
#         until no token matched

program: (stmt | ENDLINE)* END

# Statement part
stmt: container_stmt | compound_stmt

# --
container_stmt: (let_stmt | attr_stmt | assert_stmt | alloc_stmt) ENDLINE stmt_list

stmt_list: ENDLINE* stmt (stmt | ENDLINE)*

let_stmt: LET ID '=' expr

attr_stmt: DOUBLESLASH ATTR '[' NODE_PRINTING ']' ID '=' expr

assert_stmt: ASSERT '(' expr ',' expr ')'

alloc_stmt: ALLOCATE ID '[' TYPE ('*' imm_num)* ']'

# --
compound_stmt: (if_stmt  | eval_stmt  | produce_stmt | realize_stmt |
                for_stmt | store_stmt | provide_stmt) ENDLINE

produce_stmt: PRODUCE ID stmt_body

store_stmt: ID '[' expr ']' '=' expr [IF imm_num]

provide_stmt: ID '(' [param_list] ')' '=' expr

realize_stmt: REALIZE ID '<' TYPE '>' '(' [bound_list] ')' stmt_body
bound_list: bound_ele (',' bound_ele)*
bound_ele: '[' imm_num ',' imm_num ']'

if_stmt: then_case [ELSE (if_stmt | stmt_body)]
#if_stmt: then_case (ELSE then_case)* [else_case]
then_case: IF '(' expr ')' stmt_body
#else_case: ELSE stmt_body

eval_stmt: expr

for_stmt: FOR '(' ID ',' expr ',' expr ')' stmt_body

stmt_body: '{' ENDLINE stmt_list '}'

# Expression part
expr: factor   | bin_expr  | cast_expr | select_expr |
      let_expr | call_expr | load_expr

# OP_SET contains: '+' '-' '*' '/' '&&' '||'
#                  '!' '>' '<' '%' '==' '<=' '>='
cast_expr: TYPE '(' expr ')'

select_expr: SELECT '(' expr ',' expr ',' expr ')'

let_expr: '(' LET ID '=' expr IN expr ')'

bin_expr: '(' expr OP_SET expr ')'

call_expr: ID '(' [param_list] ')' [':' TYPE ':' CALL_TYPE]

load_expr: ID '[' expr ']' [IF imm]

# IR nodes that defines a var: alloc_stmt, for_stmt, let_expr, let_stmt, realize_stmt
# var_expr: ID

param_list: expr (',' expr)*

factor: ID | imm

imm: imm_num | STRING

imm_num: ['(' TYPE ')'] ('-')* NUMBER
