diff options
| author | Gabriel Kerneis | 2013-08-19 12:20:48 +0100 |
|---|---|---|
| committer | Gabriel Kerneis | 2013-08-19 12:20:48 +0100 |
| commit | 2209e971363bbd294194f9799f290b7814d1dfd6 (patch) | |
| tree | 0c70fc02d0fa8625929ae33a20ddf47f902ac4b7 /src | |
| parent | 5cf0230381eab9e5b96ea9ebbdcac4cb430c4a82 (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.ml | 1 | ||||
| -rw-r--r-- | src/lexer.mll | 2 | ||||
| -rw-r--r-- | src/parse_ast.ml | 1 | ||||
| -rw-r--r-- | src/parser.mly | 24 |
4 files changed, 26 insertions, 2 deletions
@@ -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)) } |
