I am trying to write semantic checks for my for my model using TypePal. Here is my model
Property(b => b.name)
.ColumnOrder(3)
.ColumnName("Name")
.ColumnType(varchar(45))
.ColumnType(date)
;
syntax Property
= property: "Property" "(" Expr e ")" PropertyType*
;
syntax PropertyType
= columnName: "." "ColumnName" "(" Expr e ")"
| columnOrder: "." "ColumnOrder" "(" Expr e ")"
| columnType: "." "ColumnType" "(" ColumnType c ")"
;
syntax ColumnType
= intColumn: "int"
| varcharColumn: "varchar" "(" Expr e ")"
| dateColumn: "date"
;
How do I write a rule with TypePal that enforces the requirement that a given PropertyType can not be repeated. I want each PropertyType to be used at most once. In the example above ColumnType was used twice I want this flagged as a semantic error.
here is what I came up with.
map[str, int] m = ();
for (PropertyType pt <- p){
switch(pt){
case (PropertyType) `. ColumnType ( <ColumnType _>)` : {
if ("ColumnType" notin m){
m = m + ("ColumnType" : 1);
}
else{
c.report(error(p, "Duplicate occurrence of %v", "ColumnType"));
}
}
case (PropertyType) `. ColumnName ( <Expr _>)` : {
if ("ColumnName" notin m){
m = m + ("ColumnName" : 1);
}
else{
c.report(error(p, "Duplicate occurrence of %v", "ColumnName"));
}
}
default : {
if ("ColumnOrder" notin m){
m = m + ("ColumnOrder" : 1);
}
else{
c.report(error(p, "Duplicate occurrence of %v", "ColumnOrder"));
}
}
}
}