From ad6cbf32eb25c0afe6de5343f829ca7c202dcc49 Mon Sep 17 00:00:00 2001 From: Christian Rinderknecht Date: Thu, 21 Mar 2019 23:45:19 +0100 Subject: [PATCH] I added support for set membership. Syntax: if s contains e then ... else (only as a test expression in conditionals). --- AST.ml | 25 +++++++++++++++++++++++-- AST.mli | 13 ++++++++++++- LexToken.mli | 1 + LexToken.mll | 5 +++++ ParToken.mly | 1 + Parser.mly | 18 +++++++++++++++++- 6 files changed, 59 insertions(+), 4 deletions(-) diff --git a/AST.ml b/AST.ml index f3b6a3ef7..a57d2e47d 100644 --- a/AST.ml +++ b/AST.ml @@ -43,6 +43,7 @@ type kwd_and = Region.t type kwd_begin = Region.t type kwd_case = Region.t type kwd_const = Region.t +type kwd_contains = Region.t type kwd_down = Region.t type kwd_else = Region.t type kwd_end = Region.t @@ -394,7 +395,7 @@ and fail_instr = { and conditional = { kwd_if : kwd_if; - test : expr; + test : test_expr; kwd_then : kwd_then; ifso : instruction; terminator : semi option; @@ -402,6 +403,16 @@ and conditional = { ifnot : instruction } +and test_expr = + GenExpr of expr +| SetMem of set_membership reg + +and set_membership = { + set : expr; + kwd_contains : kwd_contains; + element : expr +} + and case_instr = { kwd_case : kwd_case; expr : expr; @@ -1041,13 +1052,23 @@ and print_conditional node = let {kwd_if; test; kwd_then; ifso; terminator; kwd_else; ifnot} = node in print_token kwd_if "if"; - print_expr test; + print_test_expr test; print_token kwd_then "then"; print_instruction ifso; print_terminator terminator; print_token kwd_else "else"; print_instruction ifnot +and print_test_expr = function + GenExpr e -> print_expr e +| SetMem m -> print_set_membership m + +and print_set_membership {value; _} = + let {set; kwd_contains; element} = value in + print_expr set; + print_token kwd_contains "contains"; + print_expr element + and print_case_instr (node : case_instr) = let {kwd_case; expr; kwd_of; lead_vbar; cases; kwd_end} = node in diff --git a/AST.mli b/AST.mli index b1bd5d57f..fbf7545d9 100644 --- a/AST.mli +++ b/AST.mli @@ -27,6 +27,7 @@ type kwd_and = Region.t type kwd_begin = Region.t type kwd_case = Region.t type kwd_const = Region.t +type kwd_contains = Region.t type kwd_down = Region.t type kwd_else = Region.t type kwd_end = Region.t @@ -378,7 +379,7 @@ and fail_instr = { and conditional = { kwd_if : kwd_if; - test : expr; + test : test_expr; kwd_then : kwd_then; ifso : instruction; terminator : semi option; @@ -386,6 +387,16 @@ and conditional = { ifnot : instruction } +and test_expr = + GenExpr of expr +| SetMem of set_membership reg + +and set_membership = { + set : expr; + kwd_contains : kwd_contains; + element : expr +} + and case_instr = { kwd_case : kwd_case; expr : expr; diff --git a/LexToken.mli b/LexToken.mli index 0f219f215..b051120ae 100644 --- a/LexToken.mli +++ b/LexToken.mli @@ -69,6 +69,7 @@ type t = | Begin of Region.t (* "begin" *) | Case of Region.t (* "case" *) | Const of Region.t (* "const" *) +| Contains of Region.t (* "contains" *) | Down of Region.t (* "down" *) | Else of Region.t (* "else" *) | End of Region.t (* "end" *) diff --git a/LexToken.mll b/LexToken.mll index b5f1de1f4..ee2d663e3 100644 --- a/LexToken.mll +++ b/LexToken.mll @@ -68,6 +68,7 @@ type t = | Begin of Region.t (* "begin" *) | Case of Region.t (* "case" *) | Const of Region.t (* "const" *) +| Contains of Region.t (* "contains" *) | Down of Region.t (* "down" *) | Else of Region.t (* "else" *) | End of Region.t (* "end" *) @@ -191,6 +192,7 @@ let proj_token = function | Begin region -> region, "Begin" | Case region -> region, "Case" | Const region -> region, "Const" +| Contains region -> region, "Contains" | Down region -> region, "Down" | Else region -> region, "Else" | End region -> region, "End" @@ -279,6 +281,7 @@ let to_lexeme = function | Begin _ -> "begin" | Case _ -> "case" | Const _ -> "const" +| Contains _ -> "contains" | Down _ -> "down" | Fail _ -> "fail" | If _ -> "if" @@ -337,6 +340,7 @@ let keywords = [ (fun reg -> Begin reg); (fun reg -> Case reg); (fun reg -> Const reg); + (fun reg -> Contains reg); (fun reg -> Down reg); (fun reg -> Fail reg); (fun reg -> If reg); @@ -563,6 +567,7 @@ let is_kwd = function | Begin _ | Case _ | Const _ +| Contains _ | Down _ | Fail _ | If _ diff --git a/ParToken.mly b/ParToken.mly index 9d5efd7c1..1487ff491 100644 --- a/ParToken.mly +++ b/ParToken.mly @@ -46,6 +46,7 @@ %token Begin (* "begin" *) %token Case (* "case" *) %token Const (* "const" *) +%token Contains (* "contains" *) %token Down (* "down" *) %token Fail (* "fail" *) %token From (* "from" *) diff --git a/Parser.mly b/Parser.mly index e57c6c4bb..3d3cbddfe 100644 --- a/Parser.mly +++ b/Parser.mly @@ -581,7 +581,7 @@ proc_call: fun_call { $1 } conditional: - If expr Then instruction option(SEMI) Else instruction { + If test_expr Then instruction option(SEMI) Else instruction { let region = cover $1 (instr_to_region $7) in let value = { kwd_if = $1; @@ -594,6 +594,22 @@ conditional: in {region; value} } +test_expr: + expr { GenExpr $1 } +| set_membership { SetMem $1 } + +set_membership: + expr Contains expr { + let start = expr_to_region $1 + and stop = expr_to_region $3 in + let region = cover start stop in + let value = { + set = $1; + kwd_contains = $2; + element = $3} + in {region; value} + } + case_instr: Case expr Of option(VBAR) cases End { let region = cover $1 $6 in