@@ -595,10 +595,9 @@ class FastParser {
595595 case class MacroApp (name : String , arguments : Seq [PExp ], node : PNode )
596596
597597 val matchOnMacroCall : PartialFunction [PNode , MacroApp ] = {
598- case app : PMacroRef => MacroApp (app.idnuse.name, Nil , app)
599- case app@ PAssign (_, call : PCall ) if isMacro(call.func.name) => MacroApp (call.func.name, call.args, app)
600- case app : PCall if isMacro(app.func.name) => MacroApp (app.func.name, app.args, app)
601- case app : PIdnUse if isMacro(app.name) => MacroApp (app.name, Nil , app)
598+ case assign@ PAssign (Seq (), app : PMacro ) if isMacro(app.name) => MacroApp (app.name, app.args, assign)
599+ case app : PMacro if isMacro(app.name) => MacroApp (app.name, app.args, app)
600+ case app : PMacroType [_] => MacroApp (app.use.name, app.use.args, app)
602601 }
603602
604603 def detectCyclicMacros (start : PNode , seen : Set [String ]): Unit = {
@@ -706,11 +705,21 @@ class FastParser {
706705 throw ParseException (" Number of macro arguments does not match" , call.pos._1)
707706
708707 (call, body) match {
709- case (_ : PStmt , _ : PExp ) =>
710- throw ParseException (" Expression macro used in statement position" , call.pos._1)
711- case (_ : PExp , _ : PStmt ) =>
712- throw ParseException (" Statement macro used in expression position" , call.pos._1)
708+ case (_ : PStmt , _ : PStmt ) | (_ : PExp , _ : PExp ) | (_ : PType , _ : PType ) =>
713709 case _ =>
710+ val expandedType = body match {
711+ case _ : PExp => " Expression"
712+ case _ : PStmt => " Statement"
713+ case _ : PType => " Type"
714+ case _ => " Unknown"
715+ }
716+ val callType = call match {
717+ case _ : PExp => " expression"
718+ case _ : PStmt => " statement"
719+ case _ : PType => " type"
720+ case _ => " unknown"
721+ }
722+ throw ParseException (s " $expandedType macro used in $callType position " , call.pos._1)
714723 }
715724
716725 /* TODO: The current unsupported position detection is probably not exhaustive.
@@ -778,7 +787,6 @@ class FastParser {
778787 * to construct invalid AST nodes.
779788 * Recursing into such PIdnUse nodes caused Silver issue #205.
780789 */
781- case PMacroRef (_) => Seq .empty
782790 case PCall (_, args, typeAnnotated) => Seq (args, typeAnnotated)
783791 }.repeat
784792
@@ -997,28 +1005,29 @@ class FastParser {
9971005
9981006 def formalArg [$ : P ]: P [PFormalArgDecl ] = FP (idndef ~ " :" ~ typ).map { case (pos, (a, b)) => PFormalArgDecl (a, b)(pos) }
9991007
1000- def typ [$ : P ]: P [PType ] = P (primitiveTyp | domainTyp | seqType | setType | multisetType | mapType)
1001- // Maps: lazy val typ: P[PType] = P(primitiveTyp | domainTyp | seqType | setType | multisetType | mapType)
1008+ def typ [$ : P ]: P [PType ] = P (primitiveTyp | domainTyp | seqType | setType | multisetType | mapType | macroType)
10021009
10031010 def domainTyp [$ : P ]: P [PDomainType ] = P (FP (idnuse ~ " [" ~ typ.rep(sep = " ," ) ~ " ]" ).map { case (pos, (a, b)) => PDomainType (a, b)(pos) } |
10041011 // domain type without type arguments (might also be a type variable)
10051012 idnuse.map(name => {
10061013 PDomainType (name, Nil )(name.pos)
10071014 }))
10081015
1009- def seqType [$ : P ]: P [PType ] = FP (keyword(" Seq" ) ~ " [" ~ typ ~ " ]" ).map{ case (pos, t) => PSeqType (t)(pos)}
1016+ def seqType [$ : P ]: P [PSeqType ] = FP (keyword(" Seq" ) ~ " [" ~ typ ~ " ]" ).map{ case (pos, t) => PSeqType (t)(pos)}
10101017
1011- def setType [$ : P ]: P [PType ] = FP (keyword(" Set" ) ~ " [" ~ typ ~ " ]" ).map{ case (pos, t) => PSetType (t)(pos)}
1018+ def setType [$ : P ]: P [PSetType ] = FP (keyword(" Set" ) ~ " [" ~ typ ~ " ]" ).map{ case (pos, t) => PSetType (t)(pos)}
10121019
1013- def multisetType [$ : P ]: P [PType ] = FP (keyword(" Multiset" ) ~ " [" ~ typ ~ " ]" ).map{ case (pos, t) => PMultisetType (t)(pos)}
1020+ def multisetType [$ : P ]: P [PMultisetType ] = FP (keyword(" Multiset" ) ~ " [" ~ typ ~ " ]" ).map{ case (pos, t) => PMultisetType (t)(pos)}
10141021
10151022 // def mapType[$: P]: P[PType] = FP(keyword("Map") ~ "[" ~ typ ~ "," ~ typ ~ "]").map{ case (pos, t) => PSeqType(t._3)(pos)}
10161023 // Maps:
1017- def mapType [$ : P ] : P [PType ] = FP (keyword(" Map" ) ~ " [" ~ typ ~ " ," ~ typ ~ " ]" ).map {
1024+ def mapType [$ : P ] : P [PMapType ] = FP (keyword(" Map" ) ~ " [" ~ typ ~ " ," ~ typ ~ " ]" ).map {
10181025 case (pos, (keyType, valueType)) => PMapType (keyType, valueType)(pos)
10191026 }
10201027
1021- def primitiveTyp [$ : P ]: P [PType ] = P (FP (keyword(" Rational" )).map{ case (pos, _) => PPrimitiv (" Perm" )(pos)}
1028+ def macroType [$ : P ] : P [PMacroType [_]] = idnuse.map(PMacroType (_)) | fapp.map(PMacroType (_))
1029+
1030+ def primitiveTyp [$ : P ]: P [PPrimitiv ] = P (FP (keyword(" Rational" )).map{ case (pos, _) => PPrimitiv (" Perm" )(pos)}
10221031 | FP ((StringIn (" Int" , " Bool" , " Perm" , " Ref" ) ~~ ! identContinues).! ).map{ case (pos, name) => PPrimitiv (name)(pos)})
10231032/* Maps:
10241033 lazy val primitiveTyp: P[PType] = P(keyword("Rational").map(_ => PPrimitiv("Perm"))
@@ -1101,18 +1110,16 @@ class FastParser {
11011110 case (pos, (func, args, typeGiven)) => PCall (func, args, Some (typeGiven))(pos)
11021111 }
11031112
1104- def stmt (implicit ctx : P [_]) : P [PStmt ] = P (ParserExtension .newStmtAtStart(ctx) | fold | unfold | exhale | assertP |
1113+ def stmt (implicit ctx : P [_]) : P [PStmt ] = P (ParserExtension .newStmtAtStart(ctx) | assign | fold | unfold | exhale | assertP |
11051114 inhale | assume | ifthnels | whle | varDecl | defineDecl |
1106- goto | lbl | packageWand | applyWand | assign | macroref | block |
1115+ goto | lbl | packageWand | applyWand | block |
11071116 quasihavoc | quasihavocall | ParserExtension .newStmtAtEnd(ctx))
11081117
1109- def nodefinestmt (implicit ctx : P [_]) : P [PStmt ] = P (ParserExtension .newStmtAtStart(ctx) | fold | unfold | exhale | assertP |
1118+ def nodefinestmt (implicit ctx : P [_]) : P [PStmt ] = P (ParserExtension .newStmtAtStart(ctx) | assign | fold | unfold | exhale | assertP |
11101119 inhale | assume | ifthnels | whle | varDecl |
1111- goto | lbl | packageWand | applyWand | assign | macroref | block |
1120+ goto | lbl | packageWand | applyWand | block |
11121121 quasihavoc | quasihavocall | ParserExtension .newStmtAtEnd(ctx))
11131122
1114- def macroref [$ : P ]: P [PMacroRef ] = FP (idnuse).map { case (pos, a) => PMacroRef (a)(pos) }
1115-
11161123 def assignTarget [$ : P ]: P [PAssignTarget ] = P (fieldAcc | NoCut (fapp) | idnuse)
11171124
11181125 def assign [$ : P ]: P [PAssign ] = FP ((assignTarget.rep(min = 1 , sep = " ," ) ~ " :=" ).? ~ exp).map { case (pos, (targets, rhs)) => PAssign (targets.getOrElse(Seq ()), rhs)(pos) }
0 commit comments