I added support for set membership.

Syntax: if s contains e then ... else
(only as a test expression in conditionals).
This commit is contained in:
Christian Rinderknecht 2019-03-21 23:45:19 +01:00
parent 19f6981ae7
commit ad6cbf32eb
No known key found for this signature in database
GPG Key ID: 9446816CFD267040
6 changed files with 59 additions and 4 deletions

25
AST.ml
View File

@ -43,6 +43,7 @@ type kwd_and = Region.t
type kwd_begin = Region.t type kwd_begin = Region.t
type kwd_case = Region.t type kwd_case = Region.t
type kwd_const = Region.t type kwd_const = Region.t
type kwd_contains = Region.t
type kwd_down = Region.t type kwd_down = Region.t
type kwd_else = Region.t type kwd_else = Region.t
type kwd_end = Region.t type kwd_end = Region.t
@ -394,7 +395,7 @@ and fail_instr = {
and conditional = { and conditional = {
kwd_if : kwd_if; kwd_if : kwd_if;
test : expr; test : test_expr;
kwd_then : kwd_then; kwd_then : kwd_then;
ifso : instruction; ifso : instruction;
terminator : semi option; terminator : semi option;
@ -402,6 +403,16 @@ and conditional = {
ifnot : instruction 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 = { and case_instr = {
kwd_case : kwd_case; kwd_case : kwd_case;
expr : expr; expr : expr;
@ -1041,13 +1052,23 @@ and print_conditional node =
let {kwd_if; test; kwd_then; ifso; terminator; let {kwd_if; test; kwd_then; ifso; terminator;
kwd_else; ifnot} = node in kwd_else; ifnot} = node in
print_token kwd_if "if"; print_token kwd_if "if";
print_expr test; print_test_expr test;
print_token kwd_then "then"; print_token kwd_then "then";
print_instruction ifso; print_instruction ifso;
print_terminator terminator; print_terminator terminator;
print_token kwd_else "else"; print_token kwd_else "else";
print_instruction ifnot 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) = and print_case_instr (node : case_instr) =
let {kwd_case; expr; kwd_of; let {kwd_case; expr; kwd_of;
lead_vbar; cases; kwd_end} = node in lead_vbar; cases; kwd_end} = node in

13
AST.mli
View File

@ -27,6 +27,7 @@ type kwd_and = Region.t
type kwd_begin = Region.t type kwd_begin = Region.t
type kwd_case = Region.t type kwd_case = Region.t
type kwd_const = Region.t type kwd_const = Region.t
type kwd_contains = Region.t
type kwd_down = Region.t type kwd_down = Region.t
type kwd_else = Region.t type kwd_else = Region.t
type kwd_end = Region.t type kwd_end = Region.t
@ -378,7 +379,7 @@ and fail_instr = {
and conditional = { and conditional = {
kwd_if : kwd_if; kwd_if : kwd_if;
test : expr; test : test_expr;
kwd_then : kwd_then; kwd_then : kwd_then;
ifso : instruction; ifso : instruction;
terminator : semi option; terminator : semi option;
@ -386,6 +387,16 @@ and conditional = {
ifnot : instruction 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 = { and case_instr = {
kwd_case : kwd_case; kwd_case : kwd_case;
expr : expr; expr : expr;

View File

@ -69,6 +69,7 @@ type t =
| Begin of Region.t (* "begin" *) | Begin of Region.t (* "begin" *)
| Case of Region.t (* "case" *) | Case of Region.t (* "case" *)
| Const of Region.t (* "const" *) | Const of Region.t (* "const" *)
| Contains of Region.t (* "contains" *)
| Down of Region.t (* "down" *) | Down of Region.t (* "down" *)
| Else of Region.t (* "else" *) | Else of Region.t (* "else" *)
| End of Region.t (* "end" *) | End of Region.t (* "end" *)

View File

@ -68,6 +68,7 @@ type t =
| Begin of Region.t (* "begin" *) | Begin of Region.t (* "begin" *)
| Case of Region.t (* "case" *) | Case of Region.t (* "case" *)
| Const of Region.t (* "const" *) | Const of Region.t (* "const" *)
| Contains of Region.t (* "contains" *)
| Down of Region.t (* "down" *) | Down of Region.t (* "down" *)
| Else of Region.t (* "else" *) | Else of Region.t (* "else" *)
| End of Region.t (* "end" *) | End of Region.t (* "end" *)
@ -191,6 +192,7 @@ let proj_token = function
| Begin region -> region, "Begin" | Begin region -> region, "Begin"
| Case region -> region, "Case" | Case region -> region, "Case"
| Const region -> region, "Const" | Const region -> region, "Const"
| Contains region -> region, "Contains"
| Down region -> region, "Down" | Down region -> region, "Down"
| Else region -> region, "Else" | Else region -> region, "Else"
| End region -> region, "End" | End region -> region, "End"
@ -279,6 +281,7 @@ let to_lexeme = function
| Begin _ -> "begin" | Begin _ -> "begin"
| Case _ -> "case" | Case _ -> "case"
| Const _ -> "const" | Const _ -> "const"
| Contains _ -> "contains"
| Down _ -> "down" | Down _ -> "down"
| Fail _ -> "fail" | Fail _ -> "fail"
| If _ -> "if" | If _ -> "if"
@ -337,6 +340,7 @@ let keywords = [
(fun reg -> Begin reg); (fun reg -> Begin reg);
(fun reg -> Case reg); (fun reg -> Case reg);
(fun reg -> Const reg); (fun reg -> Const reg);
(fun reg -> Contains reg);
(fun reg -> Down reg); (fun reg -> Down reg);
(fun reg -> Fail reg); (fun reg -> Fail reg);
(fun reg -> If reg); (fun reg -> If reg);
@ -563,6 +567,7 @@ let is_kwd = function
| Begin _ | Begin _
| Case _ | Case _
| Const _ | Const _
| Contains _
| Down _ | Down _
| Fail _ | Fail _
| If _ | If _

View File

@ -46,6 +46,7 @@
%token <Region.t> Begin (* "begin" *) %token <Region.t> Begin (* "begin" *)
%token <Region.t> Case (* "case" *) %token <Region.t> Case (* "case" *)
%token <Region.t> Const (* "const" *) %token <Region.t> Const (* "const" *)
%token <Region.t> Contains (* "contains" *)
%token <Region.t> Down (* "down" *) %token <Region.t> Down (* "down" *)
%token <Region.t> Fail (* "fail" *) %token <Region.t> Fail (* "fail" *)
%token <Region.t> From (* "from" *) %token <Region.t> From (* "from" *)

View File

@ -581,7 +581,7 @@ proc_call:
fun_call { $1 } fun_call { $1 }
conditional: 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 region = cover $1 (instr_to_region $7) in
let value = { let value = {
kwd_if = $1; kwd_if = $1;
@ -594,6 +594,22 @@ conditional:
in {region; value} 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_instr:
Case expr Of option(VBAR) cases End { Case expr Of option(VBAR) cases End {
let region = cover $1 $6 in let region = cover $1 $6 in