aboutsummaryrefslogtreecommitdiff
path: root/lib/qparser/qsp_instruction.mly
blob: fe8a51add5c9320ffeb7ee775522fc94ab56a108 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
%%

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 = Helper.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_ = Option.to_list else_opt in
        Analyzer.Instruction.if_
            loc 
            (loc_s, Helper.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_ = [ else_ ] in

        Analyzer.Instruction.if_
            loc 
            (loc_s, Helper.v expr, statements) 
            ~elifs
            ~else_
      }
single_instruction:
    | expr = expression
    { 
        let expr = Helper.v expr in
        Analyzer.Instruction.expression expr
    }
    | e = let_assignation   { e }
    | k = keyword
      args = argument(expression)
    {
        let args = List.map args ~f:(Helper.v) in
        Analyzer.Instruction.call $loc k args
    }

keyword:
    | k = KEYWORD  { k }

let_assignation:
    | assignation
      variable = variable
      op = assignation_operator
      value = expression 
    { 
        let variable = Helper.variable variable
        and value = Helper.v value in

        Analyzer.Instruction.assign $loc variable op value
    }

%inline assignation: 
    |
    | LET 
    | SET {}

assignation_operator:
    | EQUAL { T.Eq'  }
    | INCR  { T.Inc  }
    | DECR  { T.Decr }
    | MULT_EQUAL { T.Mult }

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 }