%% optionnal_delimited(opening, X, closing): | v = delimited(opening, X, closing) { v } | v = X { v } (* Redefine the arguments from expression here because we accept * values without parens. *) argument(X): | a = optionnal_delimited(L_PAREN, arguments(X), R_PAREN) { a } | a = X { [ a ] } (** At the opposite of an expression, an instruction does not return anything. *) %public instruction: | s = single_instruction { s } (** Action like act or if in a single line *) %public inline_action: | a = onliner(ACT) { let loc, label, statements, _, _ = a in let label = Analyzer.Expression.v label in Analyzer.Instruction.act loc ~label statements } | a = onliner(IF) else_opt = preceded(ELSE, instruction)? { let loc, expr, statements, loc_s, _body = a in let elifs = [] and else_ = match else_opt with | None -> None | Some instructions -> Some ($loc(else_opt), [ instructions ]) in Analyzer.Instruction.if_ loc (loc_s, Analyzer.Expression.v expr, statements) ~elifs ~else_ } | a = onliner(IF) else_ = preceded(ELSE, inline_action) { let loc, expr, statements, loc_s, _body = a in let elifs = [] and else_ = Some ($loc(else_), [ else_ ]) in Analyzer.Instruction.if_ loc (loc_s, Analyzer.Expression.v expr, statements) ~elifs ~else_ } single_instruction: | expr = expression { let expr = Analyzer.Expression.v expr in Analyzer.Instruction.expression expr } | e = let_assignation { e } | k = keyword args = argument(expression) { let args = List.map args ~f:(Analyzer.Expression.v) in Analyzer.Instruction.call $loc k args } keyword: | k = KEYWORD { k } let_assignation: | is_local = assignation variable = variable op = assignation_operator value = expression { let variable = { (Helper.variable variable) with local = is_local } and value = Analyzer.Expression.v value in Analyzer.Instruction.assign $loc variable op value } %inline assignation: | | LET | SET { false } | LOCAL { true } assignation_operator: | EQUAL { T.Eq' } | INCR { T.Inc } | DECR { T.Decr } | MULT_EQUAL { T.Mult } | DIV_EQUAL { T.Div_assign } inline_instruction: | hd = inline_instruction tl = single_instruction AMPERSAND+ { tl :: hd } | { [] } final_inline_instruction: | hd = inline_instruction tl = instruction | hd = inline_instruction tl = inline_action { tl :: hd } | hd = inline_instruction COMMENT { (Analyzer.Instruction.comment $loc) :: hd } | hd = inline_instruction { hd } onliner(TOKEN): | TOKEN e = expression COLUMN s = rev (final_inline_instruction) { $loc, e, s, $loc(s), None }