%{ open Ast open Ast.Syntax %} %token Lint %token Lfloat %token Lvar %token Lchar %token Lstr %token Lbool %token Lint_kw Lfloat_kw Lchar_kw Lvoid_kw Lbool_kw %token Ladd Lsub Lmul Ldiv Lmod Lxor Lor Land Leq Lneq Lge Lgt Lle Llt Lnot %token Lopar Lcpar Lputs Lputi Lgeti %token Lreturn Lassign Lsc Lend Lif Lelse Lwhile %token Lcomma Lobr Lcbr (* Lob Lcb *) %left Ladd Lsub %left Lmul Ldiv %left Lmod Lxor Lor Land %left Leq Lneq Lge Lgt Lle Llt Lnot %left Lputs Lputi Lgeti Lrand %start prog %type prog %% prog: | d = def; p = prog { d :: p } | Lend { [] } ; def: | t = typ; id = Lvar; Lopar; a = args; Lcpar; Lobr; b = block; Lcbr { Func { typ = t; name = id; args = a; block = b; pos = $startpos(t) } } ; arg: | t = typ; id = Lvar { t, id } ; args: | { [] } | a = arg { a :: [] } | a = arg; Lcomma; r = args { a :: r } ; block: | { [] } | Lreturn; e = expr; Lsc; b = block { Return { expr = e; pos = $startpos($1) } :: b } | v = Lvar; Lassign; e = expr; Lsc; b = block { Assign { var = v; expr = e; pos = $startpos($2) } :: b } | t = typ; v = Lvar; Lsc; b = block { Decl { var = v; typ = t; pos = $startpos(t) } :: b } | t = typ; Lmul; v = Lvar; Lsc; b = block { Decl { var = v; typ = Point_t(t); pos = $startpos(t) } :: b } | t = typ; v = Lvar; Lassign; e = expr; Lsc; b = block { Decl { var = v; typ = t; pos = $startpos(t) } :: Assign { var = v; expr = e; pos = $startpos($3) } :: b } | e = expr; Lsc; b = block { Expr { expr = e; pos = $startpos(e) } :: b } | Lwhile; e = expr; Lobr; bl = block; Lcbr; b = block { Loop { expr = e; block = bl; pos = $startpos($1) } :: b } | c = cond; b = block { c :: b } ; cond: | Lif; e = expr; Lobr; bt = block; Lcbr { Cond { expr = e; blockt = bt; blockf = []; pos = $startpos($1) } } | Lif; e = expr; Lobr; bt = block; Lcbr; Lelse; Lobr; be = block; Lcbr { Cond { expr = e; blockt = bt; blockf = be; pos = $startpos($1) } } | Lif; e = expr; Lobr; bt = block; Lcbr; Lelse; bf = cond { Cond { expr = e; blockt = bt; blockf = [bf]; pos = $startpos($1) } } ; par: | { [] } | e = expr { e :: [] } | e = expr; Lcomma; p = par { e :: p } expr: | Lopar; e = expr; Lcpar { e } | n = Lfloat { Float { value = n; pos = $startpos(n) } } | c = Lchar { Char { value = c; pos = $startpos(c) } } | s = Lstr { Str { value = s; pos = $startpos(s) } } | n = Lint { Int { value = n; pos = $startpos(n) } } | b = Lbool { Bool { value = b; pos = $startpos(b) } } | v = Lvar { Var { name = v; pos = $startpos(v) } } | id = Lvar; Lopar; p = par; Lcpar; { Call { func = id; args = p; pos = $startpos(id) } } | Lnot; a = expr; { Call { func = "_not"; args = [ a ]; pos = $startpos($1) } } | Lsub; a = expr; { Call { func = "_neg"; args = [ a ]; pos = $startpos($1) } } | a = expr; Lmul; b = expr { Call { func = "_mul"; args = [ a ; b ]; pos = $startpos($2) } } | a = expr; Ladd; b = expr { Call { func = "_add"; args = [ a ; b ]; pos = $startpos($2) } } | a = expr; Lsub; b = expr { Call { func = "_sub"; args = [ a ; b ]; pos = $startpos($2) } } | a = expr; Ldiv; b = expr { Call { func = "_div"; args = [ a ; b ]; pos = $startpos($2) } } | a = expr; Lmod; b = expr { Call { func = "_mod"; args = [ a ; b ]; pos = $startpos($2) } } | a = expr; n = nat; b = expr { Call { func = n; args = [ a ; b ]; pos = $startpos(n) } } | n = nat; Lopar; e = expr; Lcpar; { Call { func = n; args = [ e ]; pos = $startpos(n) } } | n = nat; Lopar; Lcpar; { Call { func = n; args = [ ]; pos = $startpos(n) } } ; nat: | Lxor { "_xor" } | Lor { "_or" } | Land { "_and" } | Lputs { "puts" } | Lputi { "puti" } | Lgeti { "geti" } | Lneq { "_sne" } | Leq { "_seq" } | Lge { "_sge" } | Lgt { "_sgt" } | Lle { "_sle" } | Llt { "_slt" } ; typ: | Lint_kw { Int_t } | Lchar_kw { Char_t } | Lfloat_kw { Float_t } | Lbool_kw { Bool_t } | Lvoid_kw { Void_t } ;