summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabriel Kerneis2013-08-19 12:20:48 +0100
committerGabriel Kerneis2013-08-19 12:20:48 +0100
commit2209e971363bbd294194f9799f290b7814d1dfd6 (patch)
tree0c70fc02d0fa8625929ae33a20ddf47f902ac4b7 /src
parent5cf0230381eab9e5b96ea9ebbdcac4cb430c4a82 (diff)
Add loops and document optionnal else in conditional
Syntax: foreach id from exp (to|downto) exp (by exp)? exp foreach and by are keywords; from, to and downto aren't.
Diffstat (limited to 'src')
-rw-r--r--src/ast.ml1
-rw-r--r--src/lexer.mll2
-rw-r--r--src/parse_ast.ml1
-rw-r--r--src/parser.mly24
4 files changed, 26 insertions, 2 deletions
diff --git a/src/ast.ml b/src/ast.ml
index 356248ac..3ef45b12 100644
--- a/src/ast.ml
+++ b/src/ast.ml
@@ -233,6 +233,7 @@ and 'a exp_aux = (* Expression *)
| E_app_infix of 'a exp * id * 'a exp (* infix function application *)
| E_tuple of ('a exp) list (* tuple *)
| E_if of 'a exp * 'a exp * 'a exp (* conditional *)
+ | E_for of id * 'a exp * 'a exp * 'a exp * 'a exp (* loop *)
| E_vector of ('a exp) list (* vector (indexed from 0) *)
| E_vector_indexed of ((int * 'a exp)) list (* vector (indexed consecutively) *)
| E_vector_access of 'a exp * 'a exp (* vector access *)
diff --git a/src/lexer.mll b/src/lexer.mll
index 3bd4d5a1..0024b2b8 100644
--- a/src/lexer.mll
+++ b/src/lexer.mll
@@ -60,6 +60,7 @@ let kw_table =
[
("and", (fun _ -> And));
("as", (fun _ -> As));
+ ("by", (fun _ -> By));
("case", (fun _ -> Case));
("clause", (fun _ -> Clause));
("const", (fun _ -> Const));
@@ -71,6 +72,7 @@ let kw_table =
("else", (fun _ -> Else));
("false", (fun _ -> False));
("forall", (fun _ -> Forall));
+ ("foreach", (fun _ -> Foreach));
("function", (fun x -> Function_));
("if", (fun x -> If_));
("in", (fun x -> In));
diff --git a/src/parse_ast.ml b/src/parse_ast.ml
index e24294ae..f527c402 100644
--- a/src/parse_ast.ml
+++ b/src/parse_ast.ml
@@ -195,6 +195,7 @@ exp_aux = (* Expression *)
| E_app_infix of exp * id * exp (* infix function application *)
| E_tuple of (exp) list (* tuple *)
| E_if of exp * exp * exp (* conditional *)
+ | E_for of id * exp * exp * exp * exp (* loop *)
| E_vector of (exp) list (* vector (indexed from 0) *)
| E_vector_indexed of ((int * exp)) list (* vector (indexed consecutively) *)
| E_vector_access of exp * exp (* vector access *)
diff --git a/src/parser.mly b/src/parser.mly
index 84afecda..60969ebd 100644
--- a/src/parser.mly
+++ b/src/parser.mly
@@ -120,8 +120,8 @@ let star = "*"
/*Terminals with no content*/
-%token And As Bits Case Clause Const Default Dec Effect Effects End Enum Else False
-%token Forall Function_ If_ In IN Inc Let_ Member Nat Order Pure Rec Register
+%token And As Bits By Case Clause Const Default Dec Effect Effects End Enum Else False
+%token Forall Foreach Function_ If_ In IN Inc Let_ Member Nat Order Pure Rec Register
%token Scattered Struct Switch Then True Type TYPE Typedef Union With Val
/* Avoid shift/reduce conflict - see right_atomic_exp rule */
@@ -505,6 +505,26 @@ right_atomic_exp:
{ eloc (E_if($2,$4,$6)) }
| If_ exp Then exp
{ eloc (E_if($2,$4, eloc (E_lit(lloc L_unit)))) }
+ | Foreach id Id atomic_exp Id atomic_exp By atomic_exp exp
+ { if $3 <> "from" then
+ raise (Parse_error_locn ((loc ()),"Missing \"from\" in foreach loop"));
+ if $5 <> "to" && $5 <> "downto" then
+ raise (Parse_error_locn ((loc ()),"Missing \"to\" or \"downto\" in foreach loop"));
+ let step =
+ if $5 = "to"
+ then $8
+ else eloc (E_app_infix(eloc (E_lit(lloc (L_num 0))), idl (Id "-"), $8)) in
+ eloc (E_for($2,$4,$6,step,$9)) }
+ | Foreach id Id atomic_exp Id atomic_exp exp
+ { if $3 <> "from" then
+ raise (Parse_error_locn ((loc ()),"Missing \"from\" in foreach loop"));
+ if $5 <> "to" && $5 <> "downto" then
+ raise (Parse_error_locn ((loc ()),"Missing \"to\" or \"downto\" in foreach loop"));
+ let step =
+ if $5 = "to"
+ then eloc (E_lit(lloc (L_num 1)))
+ else eloc (E_lit(lloc (L_num (-1)))) in
+ eloc (E_for($2,$4,$6,step,$7)) }
| letbind In exp
{ eloc (E_let($1,$3)) }