From 8afa5995c23a5a474ea1ddb283933ef8424c732b Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 27 Jul 2023 20:01:17 -0500 Subject: [PATCH 001/283] Change originType and originNotes on OriginInfo into annotations --- .../definition/concrete_syntax/ast/Syntax.sv | 2 +- .../translation/java/core/ProductionDcl.sv | 6 ++-- grammars/silver/core/Origins.sv | 32 ++++++------------- runtime/java/src/common/OriginContext.java | 10 +++--- runtime/java/src/common/Reflection.java | 2 +- runtime/java/src/common/Tracked.java | 12 +++---- test/origintracking/force_origins/test.sv | 22 ++++++------- test/origintracking/no_redex/test.sv | 2 +- test/origintracking/noflags/test.sv | 22 ++++++------- 9 files changed, 49 insertions(+), 61 deletions(-) diff --git a/grammars/silver/compiler/definition/concrete_syntax/ast/Syntax.sv b/grammars/silver/compiler/definition/concrete_syntax/ast/Syntax.sv index fa17d1ea7..8ebb06a38 100644 --- a/grammars/silver/compiler/definition/concrete_syntax/ast/Syntax.sv +++ b/grammars/silver/compiler/definition/concrete_syntax/ast/Syntax.sv @@ -301,7 +301,7 @@ top::SyntaxDcl ::= ns::NamedSignature modifiers::SyntaxProductionModifiers end; local commaIfArgsOrAnnos :: String = if length(ns.inputElements) + length(ns.namedInputElements)!= 0 then "," else ""; local originImpl :: String = if isTracked then - "new silver.core.PparsedOriginInfo(common.OriginsUtil.SET_FROM_PARSER_OIT, common.Terminal.createSpan(_children, virtualLocation, (int)_pos.getPos()), common.ConsCell.nil)" ++ commaIfArgsOrAnnos + "new silver.core.PparsedOriginInfo(common.Terminal.createSpan(_children, virtualLocation, (int)_pos.getPos()), common.ConsCell.nil, common.OriginsUtil.SET_FROM_PARSER_OIT)" ++ commaIfArgsOrAnnos else ""; local code::String = diff --git a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv index 075a79ba8..d80089f32 100644 --- a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv +++ b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv @@ -290,7 +290,7 @@ ${body.translation} ${implode("\n\t\t", map(makeAnnoReify(fName, _), namedSig.namedInputElements))} ${namedSig.contextRuntimeResolve} - return new ${className}(${if wantsTracking then "new silver.core.PoriginOriginInfo(common.OriginsUtil.SET_FROM_REIFICATION_OIT, origAST, rules, true)"++commaIfAny else ""} ${namedSig.refInvokeTrans}); + return new ${className}(${if wantsTracking then "new silver.core.PoriginOriginInfo(origAST, true, rules, common.OriginsUtil.SET_FROM_REIFICATION_OIT)"++commaIfAny else ""} ${namedSig.refInvokeTrans}); } public ${className} constructDirect( @@ -360,9 +360,9 @@ ${makeTyVarDecls(3, namedSig.typerep.freeVariables)} public ${fnnt} duplicate(common.Node redex, common.ConsCell notes) { silver.core.NOriginInfo oi; if (redex == null || ${if top.config.noRedex then "true" else "false"}) { - oi = new PoriginOriginInfo(common.OriginsUtil.SET_AT_NEW_OIT, this, notes, true); + oi = new PoriginOriginInfo(this, true, notes, common.OriginsUtil.SET_AT_NEW_OIT); } else { - oi = new PoriginAndRedexOriginInfo(common.OriginsUtil.SET_AT_NEW_OIT, this, notes, redex, notes, true); + oi = new PoriginAndRedexOriginInfo(this, redex, notes, true, notes, common.OriginsUtil.SET_AT_NEW_OIT); } return new ${className}( ${implode(", ", diff --git a/grammars/silver/core/Origins.sv b/grammars/silver/core/Origins.sv index 7e9d08c9a..524194231 100644 --- a/grammars/silver/core/Origins.sv +++ b/grammars/silver/core/Origins.sv @@ -4,15 +4,15 @@ grammar silver:core; -- Don't change their names, grammar locations, or parameters unless you know what your doing -- (and have made the appropriate runtime and compiler changes!) -data nonterminal OriginInfo; +data nonterminal OriginInfo with originNotes, originType; data nonterminal OriginInfoType; data nonterminal OriginNote; synthesized attribute notepp :: String occurs on OriginNote; synthesized attribute isNewlyConstructed :: Boolean occurs on OriginInfo; -synthesized attribute originNotes :: [OriginNote] occurs on OriginInfo; -synthesized attribute originType :: OriginInfoType occurs on OriginInfo; +annotation originNotes :: [OriginNote]; +annotation originType :: OriginInfoType; synthesized attribute isBogus :: Boolean occurs on OriginInfoType; @@ -115,20 +115,16 @@ top::OriginInfoType ::= @{- 'catchall' for origins that don't encode other info -} abstract production otherOriginInfo -top::OriginInfo ::= typ::OriginInfoType source::String notes::[OriginNote] +top::OriginInfo ::= source::String { top.isNewlyConstructed = true; - top.originNotes = notes; - top.originType = typ; } @{- The production originated from a sequence of tokens at `source` in Copper -} abstract production parsedOriginInfo -top::OriginInfo ::= typ::OriginInfoType source::Location notes::[OriginNote] +top::OriginInfo ::= source::Location { top.isNewlyConstructed = true; - top.originNotes = notes; - top.originType = typ; } @@{- The following two are the same modulo if a redex is set or not @@ -144,28 +140,20 @@ top::OriginInfo ::= typ::OriginInfoType source::Location notes::[OriginNote] @{- See above -} abstract production originOriginInfo -top::OriginInfo ::= typ::OriginInfoType - origin :: a - originNotes :: [OriginNote] +top::OriginInfo ::= origin :: a newlyConstructed :: Boolean { top.isNewlyConstructed = newlyConstructed; - top.originNotes = originNotes; - top.originType = typ; } @{- See above -} abstract production originAndRedexOriginInfo -top::OriginInfo ::= typ::OriginInfoType - origin :: a - originNotes :: [OriginNote] +top::OriginInfo ::= origin :: a redex :: b redexNotes :: [OriginNote] newlyConstructed :: Boolean { top.isNewlyConstructed = newlyConstructed; - top.originNotes = originNotes; - top.originType = typ; } @@ -223,8 +211,8 @@ function getOriginInfoChain return case getOriginInfo(l) of | just(info) -> case info of - | originOriginInfo(_, o, _, _) -> info :: getOriginInfoChain(o) - | originAndRedexOriginInfo(_, o, _, _, _, _) -> info :: getOriginInfoChain(o) + | originOriginInfo(o, _) -> info :: getOriginInfoChain(o) + | originAndRedexOriginInfo(o, _, _, _) -> info :: getOriginInfoChain(o) | _ -> [info] end | _ -> [] @@ -263,7 +251,7 @@ Maybe ::= chain::[OriginInfo] | [] -> nothing() | link::rest -> case link of - | parsedOriginInfo(_, l, _) -> just(l) + | parsedOriginInfo(l) -> just(l) | other -> case getParsedOriginLocation_findLogicalLocationNote(other.originNotes) of | nothing() -> getParsedOriginLocation_helper(rest) | x -> x diff --git a/runtime/java/src/common/OriginContext.java b/runtime/java/src/common/OriginContext.java index 42aa70f89..74f5736d1 100644 --- a/runtime/java/src/common/OriginContext.java +++ b/runtime/java/src/common/OriginContext.java @@ -72,19 +72,19 @@ public ConsCell rulesAsSilverList() { public NOriginInfo makeNewConstructionOrigin(boolean isContractum) { switch (this.variety) { case NORMAL: - return new silver.core.PoriginOriginInfo(OriginsUtil.SET_AT_CONSTRUCTION_OIT, this.lhs, this.rulesAsSilverList(), isContractum); + return new silver.core.PoriginOriginInfo(this.lhs, isContractum, this.rulesAsSilverList(), OriginsUtil.SET_AT_CONSTRUCTION_OIT); case MAINFUNCTION: - return new silver.core.PotherOriginInfo(OriginsUtil.SET_FROM_ENTRY_OIT, new common.StringCatter("Main Function"), this.rulesAsSilverList()); + return new silver.core.PotherOriginInfo(new common.StringCatter("Main Function"), this.rulesAsSilverList(), OriginsUtil.SET_FROM_ENTRY_OIT); case FFI: - return new silver.core.PotherOriginInfo(OriginsUtil.SET_FROM_FFI_OIT, new common.StringCatter("Called from FFI"), this.rulesAsSilverList()); + return new silver.core.PotherOriginInfo(new common.StringCatter("Called from FFI"), this.rulesAsSilverList(), OriginsUtil.SET_FROM_FFI_OIT); case PARSERACTION: - return new silver.core.PotherOriginInfo(OriginsUtil.SET_FROM_PARSER_ACTION_OIT, new common.StringCatter("Called inside a parser action block"), this.rulesAsSilverList()); + return new silver.core.PotherOriginInfo(new common.StringCatter("Called inside a parser action block"), this.rulesAsSilverList(), OriginsUtil.SET_FROM_PARSER_ACTION_OIT); case GLOBAL: - return new silver.core.PotherOriginInfo(OriginsUtil.SET_IN_GLOBAL_OIT, new common.StringCatter("Built in a global"), this.rulesAsSilverList()); + return new silver.core.PotherOriginInfo(new common.StringCatter("Built in a global"), this.rulesAsSilverList(), OriginsUtil.SET_IN_GLOBAL_OIT); } throw new RuntimeException("Impossible state: this.variety not recognized."); } diff --git a/runtime/java/src/common/Reflection.java b/runtime/java/src/common/Reflection.java index ade037be7..4d7517447 100644 --- a/runtime/java/src/common/Reflection.java +++ b/runtime/java/src/common/Reflection.java @@ -69,7 +69,7 @@ public static NMaybe reflectTypeName(final Object o) { * @return The reflected AST. */ public static NAST reflect(final ConsCell rules, Object o) { - silver.core.NOriginInfo origin = (rules!=null)?new silver.core.PoriginOriginInfo(OriginsUtil.SET_FROM_REFLECTION_OIT, o, rules, true):null; + silver.core.NOriginInfo origin = (rules!=null)?new silver.core.PoriginOriginInfo(o, true, rules, OriginsUtil.SET_FROM_REFLECTION_OIT):null; if(o instanceof Node) { Node n = (Node)o; NASTs children = new PnilAST(origin); diff --git a/runtime/java/src/common/Tracked.java b/runtime/java/src/common/Tracked.java index 2779a65f3..d65c6fb6d 100644 --- a/runtime/java/src/common/Tracked.java +++ b/runtime/java/src/common/Tracked.java @@ -30,12 +30,12 @@ public default Tracked copy(Node redex, ConsCell redexNotes) { if (roi instanceof PoriginOriginInfo) { PoriginOriginInfo oi = (PoriginOriginInfo)roi; origin = oi.getChild_origin(); - originNotes = oi.getChild_originNotes(); + originNotes = oi.getAnno_silver_core_originNotes(); newlyConstructed = oi.getChild_newlyConstructed(); } else if (roi instanceof PoriginAndRedexOriginInfo) { PoriginAndRedexOriginInfo oi = (PoriginAndRedexOriginInfo)roi; origin = oi.getChild_origin(); - originNotes = oi.getChild_originNotes(); + originNotes = oi.getAnno_silver_core_originNotes(); newlyConstructed = oi.getChild_newlyConstructed(); } else { return this; @@ -43,14 +43,14 @@ public default Tracked copy(Node redex, ConsCell redexNotes) { return updateOriginInfo( new PoriginAndRedexOriginInfo( - OriginsUtil.SET_AT_ACCESS_OIT, - origin, originNotes, redex, redexNotes, newlyConstructed)); + origin, redex, redexNotes, newlyConstructed, + originNotes, OriginsUtil.SET_AT_ACCESS_OIT)); } public default Tracked duplicateForForwarding(Node redex, String note) { return updateOriginInfo( new PoriginOriginInfo( - OriginsUtil.SET_AT_FORWARDING_OIT, - this, new ConsCell(new PoriginDbgNote(new StringCatter(note)), ConsCell.nil), true)); + this, true, + new ConsCell(new PoriginDbgNote(new StringCatter(note)), ConsCell.nil), OriginsUtil.SET_AT_FORWARDING_OIT)); } } \ No newline at end of file diff --git a/test/origintracking/force_origins/test.sv b/test/origintracking/force_origins/test.sv index 5a6fe7439..33e1c91e4 100644 --- a/test/origintracking/force_origins/test.sv +++ b/test/origintracking/force_origins/test.sv @@ -10,49 +10,49 @@ equalityTest(identityHashCode(three), identityHashCode(three), Integer, oitests) equalityTest( case getOriginInfo(four) of - | just(originOriginInfo(_, link, _, _)) -> identityHashCode(link) + | just(originOriginInfo(link, _)) -> identityHashCode(link) | _ -> -1 end, identityHashCode(three), Integer, oitests); equalityTest( case getOriginInfo(five) of - | just(originOriginInfo(_, link, _, _)) -> identityHashCode(link) + | just(originOriginInfo(link, _)) -> identityHashCode(link) | _ -> -1 end, identityHashCode(four), Integer, oitests); equalityTest( case getOriginInfoChain(five) of - | _::originOriginInfo(_, link, _, _)::_ -> identityHashCode(link) + | _::originOriginInfo(link, _)::_ -> identityHashCode(link) | _ -> -1 end, identityHashCode(three), Integer, oitests); equalityTest( case getOriginInfo(three) of - | just(otherOriginInfo(setInGlobalOIT(), _, _)) -> "OK" + | just(otherOriginInfo(_, originType=setInGlobalOIT())) -> "OK" | _ -> "NO" end, "OK", String, oitests); equalityTest( case getOriginInfo(two) of - | just(originAndRedexOriginInfo(_, _, _, r, _, _)) -> identityHashCode(r) + | just(originAndRedexOriginInfo(_, r, _, _)) -> identityHashCode(r) | _ -> -1 end, identityHashCode(three), Integer, oitests); equalityTest( case getOriginInfo(two) of - | just(originAndRedexOriginInfo(setAtNewOIT(), _, _, _, _, _)) -> "OK" + | just(originAndRedexOriginInfo(_, _, _, _, originType=setAtNewOIT())) -> "OK" | _ -> "NO" end, "OK", String, oitests); equalityTest( case getOriginInfo(four) of - | just(originOriginInfo(setAtConstructionOIT(), _, _, _)) -> "OK" + | just(originOriginInfo(_, _, originType=setAtConstructionOIT())) -> "OK" | _ -> "NO" end, "OK", String, oitests); @@ -61,14 +61,14 @@ global reflectedThree :: AST = reflect(three); equalityTest( case getOriginInfo(reflectedThree) of - | just(originOriginInfo(setFromReflectionOIT(), _, _, _)) -> "OK" + | just(originOriginInfo(_, _, originType=setFromReflectionOIT())) -> "OK" | _ -> "NO" end, "OK", String, oitests); equalityTest( case getOriginInfo(reflectedThree) of - | just(originOriginInfo(_, o, _, _)) -> identityHashCode(o) + | just(originOriginInfo(o, _)) -> identityHashCode(o) | _ -> -1 end, identityHashCode(three), Integer, oitests); @@ -77,14 +77,14 @@ global reifiedThree :: Nat = reify(reflectedThree).fromRight; equalityTest( case getOriginInfo(reifiedThree) of - | just(originOriginInfo(setFromReificationOIT(), _, _, _)) -> "OK" + | just(originOriginInfo(_, _, originType=setFromReificationOIT())) -> "OK" | _ -> "NO" end, "OK", String, oitests); equalityTest( case getOriginInfo(reifiedThree) of - | just(originOriginInfo(_, o, _, _)) -> identityHashCode(o) + | just(originOriginInfo(o, _)) -> identityHashCode(o) | _ -> -1 end, identityHashCode(reflectedThree), Integer, oitests); diff --git a/test/origintracking/no_redex/test.sv b/test/origintracking/no_redex/test.sv index 71772a118..8630738e5 100644 --- a/test/origintracking/no_redex/test.sv +++ b/test/origintracking/no_redex/test.sv @@ -7,7 +7,7 @@ global two :: Nat = three.minusOne; equalityTest( case getOriginInfo(two) of - | just(originAndRedexOriginInfo(_, _, _, _, _, _)) -> "NO" + | just(originAndRedexOriginInfo(_, _, _, _)) -> "NO" | x -> "OK" end, "OK", String, oitests); \ No newline at end of file diff --git a/test/origintracking/noflags/test.sv b/test/origintracking/noflags/test.sv index 38ecfa4e8..f8707da4f 100644 --- a/test/origintracking/noflags/test.sv +++ b/test/origintracking/noflags/test.sv @@ -11,49 +11,49 @@ equalityTest(identityHashCode(three), identityHashCode(three), Integer, oitests) equalityTest( case getOriginInfo(four) of - | just(originOriginInfo(_, link, _, _)) -> identityHashCode(link) + | just(originOriginInfo(link, _)) -> identityHashCode(link) | _ -> -1 end, identityHashCode(three), Integer, oitests); equalityTest( case getOriginInfo(five) of - | just(originOriginInfo(_, link, _, _)) -> identityHashCode(link) + | just(originOriginInfo(link, _)) -> identityHashCode(link) | _ -> -1 end, identityHashCode(four), Integer, oitests); equalityTest( case getOriginInfoChain(five) of - | _::originOriginInfo(_, link, _, _)::_ -> identityHashCode(link) + | _::originOriginInfo(link, _)::_ -> identityHashCode(link) | _ -> -1 end, identityHashCode(three), Integer, oitests); equalityTest( case getOriginInfo(three) of - | just(otherOriginInfo(setInGlobalOIT(), _, _)) -> "OK" + | just(otherOriginInfo(_, originType=setInGlobalOIT())) -> "OK" | _ -> "NO" end, "OK", String, oitests); equalityTest( case getOriginInfo(two) of - | just(originAndRedexOriginInfo(_, _, _, r, _, _)) -> identityHashCode(r) + | just(originAndRedexOriginInfo(_, r, _, _)) -> identityHashCode(r) | _ -> -1 end, identityHashCode(three), Integer, oitests); equalityTest( case getOriginInfo(two) of - | just(originAndRedexOriginInfo(setAtNewOIT(), _, _, _, _, _)) -> "OK" + | just(originAndRedexOriginInfo(_, _, _, _, originType=setAtNewOIT())) -> "OK" | _ -> "NO" end, "OK", String, oitests); equalityTest( case getOriginInfo(four) of - | just(originOriginInfo(setAtConstructionOIT(), _, _, _)) -> "OK" + | just(originOriginInfo(_, _, originType=setAtConstructionOIT())) -> "OK" | _ -> "NO" end, "OK", String, oitests); @@ -62,14 +62,14 @@ global reflectedThree :: AST = reflect(three); equalityTest( case getOriginInfo(reflectedThree) of - | just(originOriginInfo(setFromReflectionOIT(), _, _, _)) -> "OK" + | just(originOriginInfo(_, _, originType=setFromReflectionOIT())) -> "OK" | _ -> "NO" end, "OK", String, oitests); equalityTest( case getOriginInfo(reflectedThree) of - | just(originOriginInfo(_, o, _, _)) -> identityHashCode(o) + | just(originOriginInfo(o, _)) -> identityHashCode(o) | _ -> -1 end, identityHashCode(three), Integer, oitests); @@ -78,14 +78,14 @@ global reifiedThree :: Nat = reify(reflectedThree).fromRight; equalityTest( case getOriginInfo(reifiedThree) of - | just(originOriginInfo(setFromReificationOIT(), _, _, _)) -> "OK" + | just(originOriginInfo(_, _, originType=setFromReificationOIT())) -> "OK" | _ -> "NO" end, "OK", String, oitests); equalityTest( case getOriginInfo(reifiedThree) of - | just(originOriginInfo(_, o, _, _)) -> identityHashCode(o) + | just(originOriginInfo(o, _)) -> identityHashCode(o) | _ -> -1 end, identityHashCode(reflectedThree), Integer, oitests); From 3671d850e31f4943674efbb332b326056ee18d36 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 27 Jul 2023 20:04:21 -0500 Subject: [PATCH 002/283] Make OriginNote closed --- grammars/silver/core/Origins.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/core/Origins.sv b/grammars/silver/core/Origins.sv index 524194231..4c919b740 100644 --- a/grammars/silver/core/Origins.sv +++ b/grammars/silver/core/Origins.sv @@ -6,7 +6,7 @@ grammar silver:core; data nonterminal OriginInfo with originNotes, originType; data nonterminal OriginInfoType; -data nonterminal OriginNote; +closed data nonterminal OriginNote; synthesized attribute notepp :: String occurs on OriginNote; From bb4162f7c79cb80a678dc97580bd4266db497e0f Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 27 Jul 2023 20:25:38 -0500 Subject: [PATCH 003/283] attachNote expression should have the same decoration site --- grammars/silver/compiler/definition/flow/env/Expr.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index a32869764..8c0f9c774 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -253,9 +253,9 @@ aspect production noteAttachment top::Expr ::= 'attachNote' note::Expr 'on' e::Expr 'end' { note.decSiteVertexInfo = nothing(); - e.decSiteVertexInfo = nothing(); + e.decSiteVertexInfo = top.decSiteVertexInfo; note.alwaysDecorated = false; - e.alwaysDecorated = false; + e.alwaysDecorated = top.alwaysDecorated; } aspect production access From 1f8a390b781b0fa0951296346311221c1d5c4974 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 27 Jul 2023 20:41:38 -0500 Subject: [PATCH 004/283] Fix test --- test/origintracking/tracing_origins/test.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/origintracking/tracing_origins/test.sv b/test/origintracking/tracing_origins/test.sv index b20495f0e..6e6bbe84b 100644 --- a/test/origintracking/tracing_origins/test.sv +++ b/test/origintracking/tracing_origins/test.sv @@ -13,8 +13,8 @@ Nat ::= equalityTest( case getOriginInfo(constructFour()) of | just(originAndRedexOriginInfo(_, _, - [traceNote("nat.sv:18:16")], _, - [traceNote("test.sv:14:27"), traceNote("test.sv:10:15")], _)) -> "OK" + [traceNote("test.sv:14:27"), traceNote("test.sv:10:15")], _, + originNotes=[traceNote("nat.sv:18:16")])) -> "OK" | _ -> "NO" end, "OK", String, oitests); From d6795ae4d11f472f6f3572dc97c15a9e3bfad627 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 28 Jul 2023 18:13:03 -0500 Subject: [PATCH 005/283] Avoid trying to print horrifically large origin fallback strings --- grammars/silver/core/Origins.sv | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/grammars/silver/core/Origins.sv b/grammars/silver/core/Origins.sv index 4c919b740..9aeaa9aea 100644 --- a/grammars/silver/core/Origins.sv +++ b/grammars/silver/core/Origins.sv @@ -278,10 +278,16 @@ Maybe ::= notes::[OriginNote] function getParsedOriginLocationOrFallback Location ::= arg::a { + local fallbackString::String = + "arg: " ++ hackUnparse(arg) ++ + " ochain: " ++ hackUnparse(getOriginInfoChain(arg)); + local truncatedFallbackString::String = + if length(fallbackString) > 10000 + then substring(0, 10000, fallbackString) ++ "... truncated at 10000 chars" + else fallbackString; return case getParsedOriginLocation(arg) of | just(l) -> l - | _ -> txtLoc("") + | _ -> txtLoc("") end; } From 6d09ccf4d4e3728f67e6d856fc6b033e4982ff95 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Sun, 30 Jul 2023 20:13:11 -0500 Subject: [PATCH 006/283] Reduce parsed origin fallback debug string length limit to 1000 chars --- grammars/silver/core/Origins.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grammars/silver/core/Origins.sv b/grammars/silver/core/Origins.sv index 9aeaa9aea..225328bdd 100644 --- a/grammars/silver/core/Origins.sv +++ b/grammars/silver/core/Origins.sv @@ -282,8 +282,8 @@ Location ::= arg::a "arg: " ++ hackUnparse(arg) ++ " ochain: " ++ hackUnparse(getOriginInfoChain(arg)); local truncatedFallbackString::String = - if length(fallbackString) > 10000 - then substring(0, 10000, fallbackString) ++ "... truncated at 10000 chars" + if length(fallbackString) > 1000 + then substring(0, 1000, fallbackString) ++ "... truncated at 1000 chars" else fallbackString; return case getParsedOriginLocation(arg) of | just(l) -> l From 50a2a98b69876cce2a2d64fd893cadf314818b89 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Sun, 30 Jul 2023 20:13:38 -0500 Subject: [PATCH 007/283] Report location from origin info in DecoratedNode debug ID --- runtime/java/src/common/DecoratedNode.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/runtime/java/src/common/DecoratedNode.java b/runtime/java/src/common/DecoratedNode.java index 691645cab..89eeaaa6f 100644 --- a/runtime/java/src/common/DecoratedNode.java +++ b/runtime/java/src/common/DecoratedNode.java @@ -7,6 +7,8 @@ import common.exceptions.SilverException; import common.exceptions.SilverInternalError; import common.exceptions.TraceException; +import silver.core.NLocation; +import silver.core.NMaybe; /** * This is the StackHeap Frame and primary data structure of Silver. @@ -801,17 +803,24 @@ public final DecoratedTypeRep getType() { * @return an identification string for this node. */ public final String getDebugID() { - String qualifier; if(self == null) { return ""; - } else if(self instanceof silver.core.Alocation) { - DecoratedNode loc = ((silver.core.Alocation)self).getAnno_silver_core_location().decorate(); + } + NLocation loc = null; + if(self instanceof silver.core.Alocation) { + loc = ((silver.core.Alocation)self).getAnno_silver_core_location(); + } else if(self instanceof Tracked) { + NMaybe maybeLoc = silver.core.PgetParsedOriginLocation.invoke(OriginContext.FFI_CONTEXT, self); + if(maybeLoc instanceof silver.core.Pjust) { + loc = (silver.core.NLocation)maybeLoc.getChild(0); + } + } + String qualifier = ""; + if(loc != null) { String file = loc.synthesized(silver.core.Init.silver_core_filename__ON__silver_core_Location).toString(); int line = (Integer)loc.synthesized(silver.core.Init.silver_core_line__ON__silver_core_Location); int col = (Integer)loc.synthesized(silver.core.Init.silver_core_column__ON__silver_core_Location); qualifier = ", " + file + ":" + Integer.toString(line) + ":" + Integer.toString(col); - } else { - qualifier = ""; } return "'" + self.getName() + "' (" + Integer.toHexString(System.identityHashCode(this)) + qualifier + ")"; } From fbd2e6908cb75cec8e2d81643525f48189d75779 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 31 Jul 2023 14:34:25 -0500 Subject: [PATCH 008/283] Minor cleanup --- grammars/silver/compiler/translation/java/core/Origins.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/compiler/translation/java/core/Origins.sv b/grammars/silver/compiler/translation/java/core/Origins.sv index b09025bb4..3ced5b4f4 100644 --- a/grammars/silver/compiler/translation/java/core/Origins.sv +++ b/grammars/silver/compiler/translation/java/core/Origins.sv @@ -83,7 +83,7 @@ function getSpecialCaseNoOrigins function typeWantsTracking Boolean ::= ty::Type conf::Decorated CmdArgs env::Env { - return if conf.noOrigins || containsBy((\a::String b::String -> a==b), ty.typeName, getSpecialCaseNoOrigins()) then false + return if conf.noOrigins || contains(ty.typeName, getSpecialCaseNoOrigins()) then false else case ty of | nonterminalType(fn, _, _, tracked) -> conf.forceOrigins || tracked | appType(c, _) -> typeWantsTracking(c, conf, env) From 377a82a6b6a3f1e515291724d24f3505b974141e Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 31 Jul 2023 16:20:17 -0500 Subject: [PATCH 009/283] Move Louis's code for reporting errors in extension-generated code from ableC into Silver. --- grammars/silver/langutil/Message.sv | 29 ++++++++++++++++++++++++++++- grammars/silver/langutil/Origins.sv | 29 +++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 grammars/silver/langutil/Origins.sv diff --git a/grammars/silver/langutil/Message.sv b/grammars/silver/langutil/Message.sv index 7d380edc7..811101bae 100644 --- a/grammars/silver/langutil/Message.sv +++ b/grammars/silver/langutil/Message.sv @@ -133,13 +133,40 @@ Boolean ::= l::[Message] wError::Boolean end; } +@{-- + - Show a message as a string, specially reporting undesired errors from extension-generated code. + -} +function showMessage +String ::= m::Message +{ + local fromExt::Maybe = originatesInExt(getOriginInfoChain(m)); + local originsSource::Maybe = getParsedOriginLocation(m); + local fromExtMessage::String = + "\n\n" ++ + "\nINTERNAL ERROR: The following error message originated in extension-generated code." ++ + "\nThis is probably indicative of a bug in the extension as opposed to your code." ++ + "\nThe offending extension was: '" ++ fromExt.fromJust ++ "' - please report this to it's developers." ++ + "\nThe error was: " ++ m.noLocOutput ++ "." ++ -- We do not expect the location to be useful/correct + (if originsSource.isJust + then "\nOrigins reports the following source location: " ++ originsSource.fromJust.unparse ++ "." + else "\nOrigins chain terminates without location.") ++ + "\nOrigins chain follows:" ++ + "\n -> " ++ implode("\n -> ", map(hackUnparse, getOriginInfoChain(m))) ++ + "\n\n"; + + + return if fromExt.isJust + then fromExtMessage + else m.output; +} + @{-- - Returns a list of strings, ready to be printed to the command line. -} function messagesToString String ::= msgs::[Message] { - return implode("\n", map((.output), sortBy(messageLte, msgs))); + return implode("\n", map(showMessage, sortBy(messageLte, msgs))); } -- for use with sortBy diff --git a/grammars/silver/langutil/Origins.sv b/grammars/silver/langutil/Origins.sv new file mode 100644 index 000000000..7e72afba7 --- /dev/null +++ b/grammars/silver/langutil/Origins.sv @@ -0,0 +1,29 @@ +grammar silver:langutil; + + +production extensionGenerated +top::OriginNote ::= string::String +{ + +} + +function originatesInExt +Maybe ::= chain::[OriginInfo] +{ + return case chain of + | [] -> nothing() + | link::rest -> + orElse(findExtensionGeneratedNote(link.originNotes), + originatesInExt(rest)) + end; +} + +function findExtensionGeneratedNote +Maybe ::= notes::[OriginNote] +{ + return case notes of + | [] -> nothing() + | extensionGenerated(l)::_ -> just(l) + | x::r -> findExtensionGeneratedNote(r) + end; +} From f5ab850c55bdf8a6cf1a110ea074653439939bf0 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 31 Jul 2023 21:58:09 -0500 Subject: [PATCH 010/283] Proper locations for metatranslating ASTs that use origin tracking --- grammars/silver/compiler/metatranslation/Translation.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/compiler/metatranslation/Translation.sv b/grammars/silver/compiler/metatranslation/Translation.sv index 2e6a11d43..c6df074ec 100644 --- a/grammars/silver/compiler/metatranslation/Translation.sv +++ b/grammars/silver/compiler/metatranslation/Translation.sv @@ -41,7 +41,7 @@ aspect production nonterminalAST top::AST ::= prodName::String children::ASTs annotations::NamedASTs { production givenLocation::Location = - fromMaybe(top.givenLocation, orElse(children.foundLocation, annotations.foundLocation)); + fromMaybe(top.givenLocation, alt(getParsedOriginLocation(top), alt(children.foundLocation, annotations.foundLocation))); production attribute antiquoteTranslation::Maybe with orElse; antiquoteTranslation := nothing(); From 06ea1aa5329e31e63557d51c75eb7d55baaa987b Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 31 Jul 2023 21:58:57 -0500 Subject: [PATCH 011/283] Better pretty-printing of origin chains --- .../compiler/translation/java/core/Origins.sv | 2 +- grammars/silver/core/Origins.sv | 28 --- grammars/silver/langutil/Message.sv | 2 +- grammars/silver/langutil/Origins.sv | 189 +++++++++++++++++- 4 files changed, 190 insertions(+), 31 deletions(-) diff --git a/grammars/silver/compiler/translation/java/core/Origins.sv b/grammars/silver/compiler/translation/java/core/Origins.sv index 3ced5b4f4..f2ac44f35 100644 --- a/grammars/silver/compiler/translation/java/core/Origins.sv +++ b/grammars/silver/compiler/translation/java/core/Origins.sv @@ -43,7 +43,7 @@ function makeOriginContextRef String ::= top::Decorated Expr --need .frame anno { local rulesTrans :: [String] = (if top.config.tracingOrigins then [locRule] else []) ++ map((.translation), top.originRules); - local locRule :: String = s"new silver.core.PtraceNote(new common.StringCatter(\"${escapeString(top.location.unparse)}\"))"; + local locRule :: String = s"new silver.core.PtraceNote(new common.StringCatter(\"${top.grammarName}:${escapeString(top.location.unparse)}\"))"; return if top.config.noOrigins then "null" else if length(rulesTrans)==0 diff --git a/grammars/silver/core/Origins.sv b/grammars/silver/core/Origins.sv index 225328bdd..9e5690650 100644 --- a/grammars/silver/core/Origins.sv +++ b/grammars/silver/core/Origins.sv @@ -8,8 +8,6 @@ data nonterminal OriginInfo with originNotes, originType; data nonterminal OriginInfoType; closed data nonterminal OriginNote; -synthesized attribute notepp :: String occurs on OriginNote; - synthesized attribute isNewlyConstructed :: Boolean occurs on OriginInfo; annotation originNotes :: [OriginNote]; annotation originType :: OriginInfoType; @@ -161,12 +159,6 @@ top::OriginInfo ::= origin :: a -- These are some simple builtin node types, and may be generated automatically -- inside the compiler. -aspect default production -top::OriginNote ::= -{ - top.notepp = "<" ++ hackUnparse(top) ++ ">"; -} - abstract production traceNote top::OriginNote ::= loc::String { @@ -271,26 +263,6 @@ Maybe ::= notes::[OriginNote] end; } -@{- - - Try to walk back to a parsedOriginInfo and extract the location the node came from in the source, - - giving diagnostic garbage if failed. - -} -function getParsedOriginLocationOrFallback -Location ::= arg::a -{ - local fallbackString::String = - "arg: " ++ hackUnparse(arg) ++ - " ochain: " ++ hackUnparse(getOriginInfoChain(arg)); - local truncatedFallbackString::String = - if length(fallbackString) > 1000 - then substring(0, 1000, fallbackString) ++ "... truncated at 1000 chars" - else fallbackString; - return case getParsedOriginLocation(arg) of - | just(l) -> l - | _ -> txtLoc("") - end; -} - @{- - Dump out two objects in a format for svdraw2 to consume and draw their - structure and the origins links that connect them (and any intermediate diff --git a/grammars/silver/langutil/Message.sv b/grammars/silver/langutil/Message.sv index 811101bae..a89044b88 100644 --- a/grammars/silver/langutil/Message.sv +++ b/grammars/silver/langutil/Message.sv @@ -151,7 +151,7 @@ String ::= m::Message then "\nOrigins reports the following source location: " ++ originsSource.fromJust.unparse ++ "." else "\nOrigins chain terminates without location.") ++ "\nOrigins chain follows:" ++ - "\n -> " ++ implode("\n -> ", map(hackUnparse, getOriginInfoChain(m))) ++ + "\n" ++ showOriginInfoChain(m) ++ "\n\n"; diff --git a/grammars/silver/langutil/Origins.sv b/grammars/silver/langutil/Origins.sv index 7e72afba7..c6a7784c0 100644 --- a/grammars/silver/langutil/Origins.sv +++ b/grammars/silver/langutil/Origins.sv @@ -1,12 +1,199 @@ grammar silver:langutil; +import silver:langutil:pp; +import silver:reflect; +attribute pp occurs on OriginInfoType; + +aspect production setAtConstructionOIT +top::OriginInfoType ::= +{ + top.pp = pp"construction"; +} + +aspect production setAtNewOIT +top::OriginInfoType ::= +{ + top.pp = pp"new"; +} + +aspect production setAtForwardingOIT +top::OriginInfoType ::= +{ + top.pp = pp"forwarding"; +} + +aspect production setAtAccessOIT +top::OriginInfoType ::= +{ + top.pp = pp"access"; +} + +aspect production setFromParserOIT +top::OriginInfoType ::= +{ + top.pp = pp"parser"; +} + +aspect production setFromParserActionOIT +top::OriginInfoType ::= +{ + top.pp = pp"parse action"; +} + +aspect production setFromFFIOIT +top::OriginInfoType ::= +{ + top.pp = pp"foreign function"; +} + +aspect production setFromReflectionOIT +top::OriginInfoType ::= +{ + top.pp = pp"reflect"; +} + +aspect production setFromReificationOIT +top::OriginInfoType ::= +{ + top.pp = pp"reify"; +} + +aspect production setFromEntryOIT +top::OriginInfoType ::= +{ + top.pp = pp"main function"; +} + +aspect production setInGlobalOIT +top::OriginInfoType ::= +{ + top.pp = pp"global"; +} + +attribute pp occurs on OriginInfo; + +aspect production otherOriginInfo +top::OriginInfo ::= source::String +{ + top.pp = text(source) ++ originNotesPP(top.originNotes); +} + +aspect production parsedOriginInfo +top::OriginInfo ::= source::Location +{ + top.pp = pp"Parsed from ${source}${originNotesPP(top.originNotes)}"; +} + +aspect production originOriginInfo +top::OriginInfo ::= origin :: a + newlyConstructed :: Boolean +{ + local constructionNote::Document = + case top.originType of + | setAtConstructionOIT() -> + if newlyConstructed then pp"" else pp" (preserved)" + | oit -> pp" (from ${oit})" + end; + top.pp = pp"${reflect(origin)}${constructionNote}${originNotesPP(top.originNotes)}"; +} + +aspect production originAndRedexOriginInfo +top::OriginInfo ::= origin :: a + redex :: b + redexNotes :: [OriginNote] + newlyConstructed :: Boolean +{ + local constructionNote::Document = + case top.originType of + | setAtConstructionOIT() -> + if newlyConstructed then pp"" else pp" (preserved)" + | oit -> pp" (from ${oit})" + end; + top.pp = pp"${reflect(origin)}${constructionNote}${originNotesPP(top.originNotes)}, redex ${reflect(redex)}${originNotesPP(redexNotes)}"; +} + +function originNotesPP +Document ::= ns::[OriginNote] +{ + return initiate(pp", ", filterMap((.notePP), ns)); +} + +synthesized attribute notePP::Maybe occurs on OriginNote; + +aspect default production +top::OriginNote ::= +{ + top.notePP = nothing(); +} + +@{- + - This note can be attached to indicate that code is generated by an extension, + - and should not contain errors. If an error is encountered in extension-generated code, + - a diagnostic message is printed by showMessage. + -} production extensionGenerated +top::OriginNote ::= extName::String +{ + top.notePP = just(pp"generated by ${text(extName)}"); +} + +aspect production traceNote +top::OriginNote ::= loc::String +{ + top.notePP = just(pp"at ${text(loc)}"); +} + +aspect production originDbgNote +top::OriginNote ::= string::String +{ + top.notePP = nothing(); +} + +aspect production dbgNote top::OriginNote ::= string::String { - + top.notePP = just(pp"debug ${string}"); +} + +aspect production logicalLocationNote +top::OriginNote ::= loc::Location +{ + top.notePP = just(pp"logical ${loc}"); +} + +aspect production ruleLocNote +top::OriginNote ::= attributeName::String sourceGrammar::String prod::String nt::String sourceLocation::Location +{ + -- TODO: This doesn't seem to be used anywhere? +} + +@{- + - Try to walk back to a parsedOriginInfo and extract the location the node came from in the source, + - giving diagnostic garbage if failed. + -} +function getParsedOriginLocationOrFallback +Location ::= arg::a +{ + return + case getParsedOriginLocation(arg) of + | just(l) -> l + | _ -> txtLoc("") + end; +} + +@{- + - Render the origin chain for a term as a human-readable string. + -} +function showOriginInfoChain +String ::= x::a +{ + return show(80, ppImplode(pp"${line()} -> ", map((.pp), getOriginInfoChain(x)))); } +@{- + - Walk back an orgin chain to determine if an object was generated by an extension. + -} function originatesInExt Maybe ::= chain::[OriginInfo] { From 928fe170a6212ca97403aa35378c532cdf23cdf4 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 31 Jul 2023 23:08:41 -0500 Subject: [PATCH 012/283] Make rebuild-runtime always work after deep-clean --- rebuild-runtime | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rebuild-runtime b/rebuild-runtime index f2e9a81c6..96c305845 100755 --- a/rebuild-runtime +++ b/rebuild-runtime @@ -2,6 +2,11 @@ set -eu +# Make sure this one annoying random dependency is built +if [[ ! -d generated/src/silver/xml/ast ]]; then + SV_BUILD_TARGET="silver:xml:ast" ./self-compile +fi + echo === BUILD JAVA RUNTIME === cd runtime/java ant From 1bfcbe62e9954220e7414cb0d77037a8017a079c Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 31 Jul 2023 23:51:47 -0500 Subject: [PATCH 013/283] Runtime implementation for reflective getInherited/getSynthesized --- runtime/java/src/common/Decorable.java | 10 ++++ runtime/java/src/common/Node.java | 10 ---- runtime/java/src/common/RTTIManager.java | 7 ++- runtime/java/src/common/Reflection.java | 61 ++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 12 deletions(-) diff --git a/runtime/java/src/common/Decorable.java b/runtime/java/src/common/Decorable.java index 9ce5599fe..f6f170a63 100644 --- a/runtime/java/src/common/Decorable.java +++ b/runtime/java/src/common/Decorable.java @@ -34,4 +34,14 @@ public DecoratedNode decorate( final Lazy[] inhs, final DecoratedNode fwdParent, final boolean prodFwrd); + + /** + * A convenience method unused by generate Silver code, but useful when working with + * the Silver runtime from Java. + * + * @return A node decorated with no inherited attributes, without a parent. + */ + public default DecoratedNode decorate() { + return decorate(TopNode.singleton, null); + } } diff --git a/runtime/java/src/common/Node.java b/runtime/java/src/common/Node.java index 8caccd42d..ac5a9cb17 100644 --- a/runtime/java/src/common/Node.java +++ b/runtime/java/src/common/Node.java @@ -67,16 +67,6 @@ public DecoratedNode decorate( this, parent, inhs, fwdParent, isProdForward); } - /** - * A convenience method unused by generate Silver code, but useful when working with - * the Silver runtime from Java. - * - * @return A node decorated with no inherited attributes, without a parent. - */ - public DecoratedNode decorate() { - return decorate(TopNode.singleton, null); - } - private Node undecoratedValue = null; public final Node undecorate(final DecoratedNode context) { if (undecoratedValue == null) { diff --git a/runtime/java/src/common/RTTIManager.java b/runtime/java/src/common/RTTIManager.java index debddc6a4..f3f03d780 100644 --- a/runtime/java/src/common/RTTIManager.java +++ b/runtime/java/src/common/RTTIManager.java @@ -106,8 +106,11 @@ public static abstract class Nonterminalton { public abstract String getName(); private final Map occursIndices = new HashMap(16, 0.5f); - public int getOccursIndex(String attrName) { - if (!occursIndices.containsKey(attrName)) { + public final boolean hasAttr(String attrName) { + return occursIndices.containsKey(attrName); + } + public final int getOccursIndex(String attrName) { + if (!hasAttr(attrName)) { throw new SilverError("Attribute " + attrName + " does not occur on " + getName() + "."); } return occursIndices.get(attrName); diff --git a/runtime/java/src/common/Reflection.java b/runtime/java/src/common/Reflection.java index 4d7517447..2afe900f9 100644 --- a/runtime/java/src/common/Reflection.java +++ b/runtime/java/src/common/Reflection.java @@ -672,4 +672,65 @@ public static Object nDeserItem(ArrayList> s, DataInput throw new NativeSerializationException("Unknown type id (" + Integer.toString(typeId) + ")"); } } + + /** + * Try to access an inherited attribute from a DecoratedNode, by name. + * @param node A DecoratedNode on which to compute the attribute. + * @param attr The name of the inherited attribute to access. + * @return An Either object containing either an error message or the reflected result of evaluating the attribute. + */ + public static NEither getInherited(final TypeRep expected, final DecoratedNode d, final String attr) { + RTTIManager.Nonterminalton nt = d.getNode().getProdleton().getNonterminalton(); + if (!nt.hasAttr(attr)) { + return new Pleft(new StringCatter("Attribute " + attr + " does not occur on " + nt.getName())); + } + int i = nt.getOccursIndex(attr); + Object res; + try { + res = d.inherited(i); + } catch (SilverException e) { + Throwable rootCause = SilverException.getRootCause(e); + if (e instanceof SilverError) { + return new Pleft(new StringCatter(SilverException.getRootCause(e).getMessage())); + } else { + throw e; + } + } + if (!TypeRep.unify(expected, getType(res))) { + return new Pleft(new StringCatter("getInherited expected " + expected.toString() + ", but " + attr + " on " + nt.getName() + " gave type " + getType(res).toString())); + } + return new Pright(res); + } + + /** + * Try to access a synthesized attribute from a node, by name. + * @param node A Node or DecoratedNode on which to compute the attribute. + * @param attr The name of the synthesized attribute to access. + * @return An Either object containing either an error message or the reflected result of evaluating the attribute. + */ + public static NEither getSynthesized(final TypeRep expected, final Object o, final String attr) { + if (!(o instanceof Decorable)) { + return new Pleft(new StringCatter(getType(o).toString() + " does not have attributes")); + } + DecoratedNode d = ((Decorable)o).decorate(); + RTTIManager.Nonterminalton nt = d.getNode().getProdleton().getNonterminalton(); + if (!nt.hasAttr(attr)) { + return new Pleft(new StringCatter("Attribute " + attr + " does not occur on " + nt.getName())); + } + int i = nt.getOccursIndex(attr); + Object res; + try { + res = d.synthesized(i); + } catch (SilverException e) { + if (SilverException.getRootCause(e) instanceof MissingDefinitionException) { + return new Pleft(new StringCatter(SilverException.getRootCause(e).getMessage())); + } else { + throw e; + } + } + if (!TypeRep.unify(expected, getType(res))) { + return new Pleft(new StringCatter("getSynthesized expected " + expected.toString() + ", but " + attr + " on " + nt.getName() + " gave type " + getType(res).toString())); + } + return new Pright(res); + } } From 1e932b49867e512cf96b1b5d591ee525e3c0470d Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 31 Jul 2023 23:52:52 -0500 Subject: [PATCH 014/283] Add reflective getInherited/getSynthesized functions --- grammars/silver/reflect/util/Util.sv | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/grammars/silver/reflect/util/Util.sv b/grammars/silver/reflect/util/Util.sv index a2b436cfd..3aced7a6c 100644 --- a/grammars/silver/reflect/util/Util.sv +++ b/grammars/silver/reflect/util/Util.sv @@ -51,3 +51,19 @@ runtimeTypeable a => a ::= x::AST | right(a) -> a end; } + +function getInherited +runtimeTypeable a => Either ::= x::Decorated b with i attr::String +{ + return error("Foreign function"); +} foreign { + "java" : return "common.Reflection.getInherited(%@0@%, %x%, %attr%.toString())"; +} + +function getSynthesized +runtimeTypeable a => Either ::= x::b attr::String +{ + return error("Foreign function"); +} foreign { + "java" : return "common.Reflection.getSynthesized(%@0@%, %x%, %attr%.toString())"; +} From f9ffdd9cdc076dc50d73148307ac46b1c65899dc Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 31 Jul 2023 23:53:33 -0500 Subject: [PATCH 015/283] genericPP method to pp an arbitrary term --- grammars/silver/langutil/Origins.sv | 4 ++-- grammars/silver/langutil/reflect/Util.sv | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 grammars/silver/langutil/reflect/Util.sv diff --git a/grammars/silver/langutil/Origins.sv b/grammars/silver/langutil/Origins.sv index c6a7784c0..27af4bf3b 100644 --- a/grammars/silver/langutil/Origins.sv +++ b/grammars/silver/langutil/Origins.sv @@ -95,7 +95,7 @@ top::OriginInfo ::= origin :: a if newlyConstructed then pp"" else pp" (preserved)" | oit -> pp" (from ${oit})" end; - top.pp = pp"${reflect(origin)}${constructionNote}${originNotesPP(top.originNotes)}"; + top.pp = pp"${genericPP(origin)}${constructionNote}${originNotesPP(top.originNotes)}"; } aspect production originAndRedexOriginInfo @@ -110,7 +110,7 @@ top::OriginInfo ::= origin :: a if newlyConstructed then pp"" else pp" (preserved)" | oit -> pp" (from ${oit})" end; - top.pp = pp"${reflect(origin)}${constructionNote}${originNotesPP(top.originNotes)}, redex ${reflect(redex)}${originNotesPP(redexNotes)}"; + top.pp = pp"${genericPP(origin)}${constructionNote}${originNotesPP(top.originNotes)}, redex ${genericPP(redex)}${originNotesPP(redexNotes)}"; } function originNotesPP diff --git a/grammars/silver/langutil/reflect/Util.sv b/grammars/silver/langutil/reflect/Util.sv new file mode 100644 index 000000000..76299dcc5 --- /dev/null +++ b/grammars/silver/langutil/reflect/Util.sv @@ -0,0 +1,19 @@ +grammar silver:langutil:reflect; + +@{- + - Use reflection to get the pp or unparse of an unknown term, + - falling back to use the reflective pp. + -} +function genericPP +Document ::= x::a +{ + return + fromRight( + alt( + getSynthesized(x, "silver:langutil:pp"), + alt( + map(\ pps::[Document] -> pp"[${ppImplode(pp", ", pps)}]", + getSynthesized(x, "silver:langutil:pps")), + map(text, getSynthesized(x, "silver:langutil:unparse")))), + reflect(x).pp); +} From adf2e1568399d4daef9992cc87733199cc921763 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 1 Aug 2023 02:11:00 -0500 Subject: [PATCH 016/283] Avoid complaining about messages themselves constructed in an extension production --- grammars/silver/core/Origins.sv | 7 +++---- grammars/silver/langutil/Message.sv | 10 +++++++--- grammars/silver/langutil/Origins.sv | 9 +++++---- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/grammars/silver/core/Origins.sv b/grammars/silver/core/Origins.sv index 9e5690650..93563370d 100644 --- a/grammars/silver/core/Origins.sv +++ b/grammars/silver/core/Origins.sv @@ -232,11 +232,10 @@ Maybe ::= arg::a function getParsedOriginLocation Maybe ::= arg::a { - return getParsedOriginLocation_helper(getOriginInfoChain(arg)); + return getParsedOriginLocationFromChain(getOriginInfoChain(arg)); } -@{- @hide -} -function getParsedOriginLocation_helper +function getParsedOriginLocationFromChain Maybe ::= chain::[OriginInfo] { return case chain of @@ -245,7 +244,7 @@ Maybe ::= chain::[OriginInfo] case link of | parsedOriginInfo(l) -> just(l) | other -> case getParsedOriginLocation_findLogicalLocationNote(other.originNotes) of - | nothing() -> getParsedOriginLocation_helper(rest) + | nothing() -> getParsedOriginLocationFromChain(rest) | x -> x end end diff --git a/grammars/silver/langutil/Message.sv b/grammars/silver/langutil/Message.sv index a89044b88..a2b5b3df4 100644 --- a/grammars/silver/langutil/Message.sv +++ b/grammars/silver/langutil/Message.sv @@ -139,8 +139,12 @@ Boolean ::= l::[Message] wError::Boolean function showMessage String ::= m::Message { - local fromExt::Maybe = originatesInExt(getOriginInfoChain(m)); - local originsSource::Maybe = getParsedOriginLocation(m); + local chain::[OriginInfo] = getOriginInfoChain(m); + local fromExt::Maybe = + -- The first item in the chain is the message itself; + -- we don't want to complain about messages raised directly in extension productions as "extension generated". + if null(chain) then nothing() else originatesInExt(tail(chain)); + local originsSource::Maybe = getParsedOriginLocationFromChain(chain); local fromExtMessage::String = "\n\n" ++ "\nINTERNAL ERROR: The following error message originated in extension-generated code." ++ @@ -151,7 +155,7 @@ String ::= m::Message then "\nOrigins reports the following source location: " ++ originsSource.fromJust.unparse ++ "." else "\nOrigins chain terminates without location.") ++ "\nOrigins chain follows:" ++ - "\n" ++ showOriginInfoChain(m) ++ + "\n" ++ showOriginInfoChain(chain) ++ "\n\n"; diff --git a/grammars/silver/langutil/Origins.sv b/grammars/silver/langutil/Origins.sv index 27af4bf3b..d6a2b95d8 100644 --- a/grammars/silver/langutil/Origins.sv +++ b/grammars/silver/langutil/Origins.sv @@ -175,10 +175,11 @@ top::OriginNote ::= attributeName::String sourceGrammar::String prod::String nt: function getParsedOriginLocationOrFallback Location ::= arg::a { + local chain::[OriginInfo] = getOriginInfoChain(arg); return - case getParsedOriginLocation(arg) of + case getParsedOriginLocationFromChain(chain) of | just(l) -> l - | _ -> txtLoc("") + | _ -> txtLoc("") end; } @@ -186,9 +187,9 @@ Location ::= arg::a - Render the origin chain for a term as a human-readable string. -} function showOriginInfoChain -String ::= x::a +String ::= chain::[OriginInfo] { - return show(80, ppImplode(pp"${line()} -> ", map((.pp), getOriginInfoChain(x)))); + return show(80, ppImplode(pp"${line()} -> ", map((.pp), chain))); } @{- From 557208a9977bee2be17ef288f7cf208800b28d7c Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 1 Aug 2023 11:11:25 -0500 Subject: [PATCH 017/283] Fix test --- test/origintracking/tracing_origins/test.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/origintracking/tracing_origins/test.sv b/test/origintracking/tracing_origins/test.sv index 6e6bbe84b..468113290 100644 --- a/test/origintracking/tracing_origins/test.sv +++ b/test/origintracking/tracing_origins/test.sv @@ -13,8 +13,8 @@ Nat ::= equalityTest( case getOriginInfo(constructFour()) of | just(originAndRedexOriginInfo(_, _, - [traceNote("test.sv:14:27"), traceNote("test.sv:10:15")], _, - originNotes=[traceNote("nat.sv:18:16")])) -> "OK" + [traceNote("tracing_origins:test.sv:14:27"), traceNote("tracing_origins:test.sv:10:15")], _, + originNotes=[traceNote("common:nat.sv:18:16")])) -> "OK" | _ -> "NO" end, "OK", String, oitests); From 8e432031e7043e95106b09c05278a05099630067 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 1 Aug 2023 17:47:52 -0500 Subject: [PATCH 018/283] Include origin notes in stack traces --- grammars/silver/core/Origins.sv | 33 ++++++++++++++--- grammars/silver/langutil/Origins.sv | 42 ++-------------------- runtime/java/src/common/DecoratedNode.java | 11 ++++-- 3 files changed, 38 insertions(+), 48 deletions(-) diff --git a/grammars/silver/core/Origins.sv b/grammars/silver/core/Origins.sv index 93563370d..e3b3f1df5 100644 --- a/grammars/silver/core/Origins.sv +++ b/grammars/silver/core/Origins.sv @@ -8,6 +8,8 @@ data nonterminal OriginInfo with originNotes, originType; data nonterminal OriginInfoType; closed data nonterminal OriginNote; +synthesized attribute notepp :: Maybe occurs on OriginNote; + synthesized attribute isNewlyConstructed :: Boolean occurs on OriginInfo; annotation originNotes :: [OriginNote]; annotation originType :: OriginInfoType; @@ -155,6 +157,12 @@ top::OriginInfo ::= origin :: a } +aspect default production +top::OriginNote ::= +{ + top.notepp = nothing(); +} + -- These are some simple builtin node types, and may be generated automatically -- inside the compiler. @@ -162,25 +170,25 @@ top::OriginInfo ::= origin :: a abstract production traceNote top::OriginNote ::= loc::String { - + top.notepp = just(s"at ${loc}"); } abstract production originDbgNote top::OriginNote ::= string::String { - + top.notepp = nothing(); } abstract production dbgNote top::OriginNote ::= string::String { - + top.notepp = just(s"debug ${string}"); } abstract production logicalLocationNote top::OriginNote ::= loc::Location { - + top.notepp = just(s"logical ${loc.filename}:${toString(loc.line)}:${toString(loc.column)}"); } @{- @@ -250,7 +258,6 @@ Maybe ::= chain::[OriginInfo] end end; } - @{- @hide -} function getParsedOriginLocation_findLogicalLocationNote Maybe ::= notes::[OriginNote] @@ -262,6 +269,22 @@ Maybe ::= notes::[OriginNote] end; } +function originNotesToString +String ::= ns::[OriginNote] +{ + return implode(", ", filterMap((.notepp), ns)); +} + +function getOriginNotesString +String ::= arg::a +{ + return + case getOriginInfo(arg) of + | just(oi) -> originNotesToString(oi.originNotes) + | nothing() -> "" + end; +} + @{- - Dump out two objects in a format for svdraw2 to consume and draw their - structure and the origins links that connect them (and any intermediate diff --git a/grammars/silver/langutil/Origins.sv b/grammars/silver/langutil/Origins.sv index d6a2b95d8..4a6120580 100644 --- a/grammars/silver/langutil/Origins.sv +++ b/grammars/silver/langutil/Origins.sv @@ -116,15 +116,7 @@ top::OriginInfo ::= origin :: a function originNotesPP Document ::= ns::[OriginNote] { - return initiate(pp", ", filterMap((.notePP), ns)); -} - -synthesized attribute notePP::Maybe occurs on OriginNote; - -aspect default production -top::OriginNote ::= -{ - top.notePP = nothing(); + return if null(ns) then pp"" else pp", ${text(originNotesToString(ns))}"; } @{- @@ -135,37 +127,7 @@ top::OriginNote ::= production extensionGenerated top::OriginNote ::= extName::String { - top.notePP = just(pp"generated by ${text(extName)}"); -} - -aspect production traceNote -top::OriginNote ::= loc::String -{ - top.notePP = just(pp"at ${text(loc)}"); -} - -aspect production originDbgNote -top::OriginNote ::= string::String -{ - top.notePP = nothing(); -} - -aspect production dbgNote -top::OriginNote ::= string::String -{ - top.notePP = just(pp"debug ${string}"); -} - -aspect production logicalLocationNote -top::OriginNote ::= loc::Location -{ - top.notePP = just(pp"logical ${loc}"); -} - -aspect production ruleLocNote -top::OriginNote ::= attributeName::String sourceGrammar::String prod::String nt::String sourceLocation::Location -{ - -- TODO: This doesn't seem to be used anywhere? + top.notepp = just(s"generated by ${extName}"); } @{- diff --git a/runtime/java/src/common/DecoratedNode.java b/runtime/java/src/common/DecoratedNode.java index 89eeaaa6f..64c0e5c6e 100644 --- a/runtime/java/src/common/DecoratedNode.java +++ b/runtime/java/src/common/DecoratedNode.java @@ -807,6 +807,7 @@ public final String getDebugID() { return ""; } NLocation loc = null; + String notes = ""; if(self instanceof silver.core.Alocation) { loc = ((silver.core.Alocation)self).getAnno_silver_core_location(); } else if(self instanceof Tracked) { @@ -814,15 +815,19 @@ public final String getDebugID() { if(maybeLoc instanceof silver.core.Pjust) { loc = (silver.core.NLocation)maybeLoc.getChild(0); } + notes = silver.core.PgetOriginNotesString.invoke(OriginContext.FFI_CONTEXT, self).toString(); } - String qualifier = ""; + String qualifier = Integer.toHexString(System.identityHashCode(this)); if(loc != null) { String file = loc.synthesized(silver.core.Init.silver_core_filename__ON__silver_core_Location).toString(); int line = (Integer)loc.synthesized(silver.core.Init.silver_core_line__ON__silver_core_Location); int col = (Integer)loc.synthesized(silver.core.Init.silver_core_column__ON__silver_core_Location); - qualifier = ", " + file + ":" + Integer.toString(line) + ":" + Integer.toString(col); + qualifier += ", " + file + ":" + Integer.toString(line) + ":" + Integer.toString(col); } - return "'" + self.getName() + "' (" + Integer.toHexString(System.identityHashCode(this)) + qualifier + ")"; + if(!notes.isEmpty()) { + qualifier += ", " + notes; + } + return "'" + self.getName() + "' (" + qualifier + ")"; } public final String toString() { From 89ef57045c435b9754321a752fd4ed4f04840d27 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 2 Aug 2023 18:22:12 -0500 Subject: [PATCH 019/283] Add shorthand for specifying logical location from an origin --- grammars/silver/langutil/Origins.sv | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/grammars/silver/langutil/Origins.sv b/grammars/silver/langutil/Origins.sv index 4a6120580..aa0a9394b 100644 --- a/grammars/silver/langutil/Origins.sv +++ b/grammars/silver/langutil/Origins.sv @@ -116,7 +116,7 @@ top::OriginInfo ::= origin :: a function originNotesPP Document ::= ns::[OriginNote] { - return if null(ns) then pp"" else pp", ${text(originNotesToString(ns))}"; + return if null(ns) then pp"" else pp": ${text(originNotesToString(ns))}"; } @{- @@ -154,6 +154,15 @@ String ::= chain::[OriginInfo] return show(80, ppImplode(pp"${line()} -> ", map((.pp), chain))); } +@{- + - Shorthand for note specifying logical location as some object's origin + -} +function logicalLocationFromOrigin +OriginNote ::= arg::a +{ + return logicalLocationNote(getParsedOriginLocationOrFallback(arg)); +} + @{- - Walk back an orgin chain to determine if an object was generated by an extension. -} From e1fdcd3975a06e4c1b88f3f4ecf53ca05ef5218e Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 2 Aug 2023 22:14:41 -0500 Subject: [PATCH 020/283] Add new origin rules to start of list --- grammars/silver/compiler/definition/core/Expr.sv | 2 +- runtime/java/src/common/OriginContext.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index 258854bd9..c3f8a5743 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -381,7 +381,7 @@ top::Expr ::= 'attachNote' note::Expr 'on' e::Expr 'end' note.isRoot = false; e.isRoot = false; note.originRules = top.originRules; - e.originRules = top.originRules ++ [note]; + e.originRules = note :: top.originRules; } -- NOTE: this is not intended to be used normally. diff --git a/runtime/java/src/common/OriginContext.java b/runtime/java/src/common/OriginContext.java index 74f5736d1..2dc3fd54b 100644 --- a/runtime/java/src/common/OriginContext.java +++ b/runtime/java/src/common/OriginContext.java @@ -46,7 +46,7 @@ public OriginContext(final Node lhs, final NOriginNote[] rules) { } public OriginContext(final OriginContext old, final NOriginNote[] newRules) { - this(old.variety, old.lhs, mergeRulesArr(old.rules, newRules)); + this(old.variety, old.lhs, mergeRulesArr(newRules, old.rules)); } private static NOriginNote[] mergeRulesArr(final NOriginNote[] a, final NOriginNote[] b) { From b945d8913bb7b182ba3e18b22c0cf4a4808487f7 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 3 Aug 2023 18:01:58 -0500 Subject: [PATCH 021/283] Fix cycles in Strategy utils pp --- grammars/silver/rewrite/Strategy.sv | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/grammars/silver/rewrite/Strategy.sv b/grammars/silver/rewrite/Strategy.sv index 13882630f..8747813dc 100644 --- a/grammars/silver/rewrite/Strategy.sv +++ b/grammars/silver/rewrite/Strategy.sv @@ -164,107 +164,125 @@ top::Strategy ::= abstract production rec top::Strategy ::= ctr::(Strategy ::= Strategy) { + top.pp = pp"rec(${text(nativeToString(ctr))}})"; forwards to ctr(top); } abstract production try top::Strategy ::= s::Strategy { + top.pp = pp"try(${s})"; forwards to s <+ id(); } abstract production repeat top::Strategy ::= s::Strategy { + top.pp = pp"repeat(${s})"; forwards to try(s <* repeat(s)); } abstract production reduce top::Strategy ::= s::Strategy { + top.pp = pp"reduce(${s})"; forwards to repeat(rec(\ x::Strategy -> some(x) <+ s)); } abstract production bottomUp top::Strategy ::= s::Strategy { + top.pp = pp"bottomUp(${s})"; forwards to all(bottomUp(s)) <* s; } abstract production topDown top::Strategy ::= s::Strategy { + top.pp = pp"topDown(${s})"; forwards to s <* all(topDown(s)); } abstract production downUp top::Strategy ::= s1::Strategy s2::Strategy { + top.pp = pp"downUp(${s1}, ${s2})"; forwards to s1 <* all(downUp(s1, s2)) <* s2; } abstract production allBottomUp top::Strategy ::= s::Strategy { + top.pp = pp"allBottomUp(${s})"; forwards to all(allBottomUp(s)) <+ s; } abstract production allTopDown top::Strategy ::= s::Strategy { + top.pp = pp"allTopDown(${s})"; forwards to s <+ all(allTopDown(s)); } abstract production allDownUp top::Strategy ::= s1::Strategy s2::Strategy { + top.pp = pp"allDownUp(${s1}, ${s2})"; forwards to s1 <+ all(allDownUp(s1, s2)) <+ s2; } abstract production someBottomUp top::Strategy ::= s::Strategy { + top.pp = pp"someBottomUp(${s})"; forwards to some(someBottomUp(s)) <+ s; } abstract production someTopDown top::Strategy ::= s::Strategy { + top.pp = pp"someTopDown(${s})"; forwards to s <+ some(someTopDown(s)); } abstract production someDownUp top::Strategy ::= s1::Strategy s2::Strategy { + top.pp = pp"someDownUp(${s1}, ${s2})"; forwards to s1 <+ some(someDownUp(s1, s2)) <+ s2; } abstract production onceBottomUp top::Strategy ::= s::Strategy { + top.pp = pp"onceBottomUp(${s})"; forwards to one(onceBottomUp(s)) <+ s; } abstract production onceTopDown top::Strategy ::= s::Strategy { + top.pp = pp"onceTopDown(${s})"; forwards to s <+ one(onceTopDown(s)); } abstract production onceDownUp top::Strategy ::= s1::Strategy s2::Strategy { + top.pp = pp"onceDownUp(${s1}, ${s2})"; forwards to s1 <+ one(onceDownUp(s1, s2)) <+ s2; } abstract production innermost top::Strategy ::= s::Strategy { + top.pp = pp"innermost(${s})"; forwards to bottomUp(try(s <* innermost(s))); } abstract production outermost top::Strategy ::= s::Strategy { + top.pp = pp"outermost(${s})"; forwards to repeat(onceTopDown(s)); } From 3771bd9edeb71a5c4264cdbf4d66a67f3a56005f Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 3 Aug 2023 18:54:47 -0500 Subject: [PATCH 022/283] Refactor nonterminaltons to track syn/inh occurs seperately --- .../translation/java/core/NamedSignature.sv | 4 +-- .../translation/java/core/NonTerminalDcl.sv | 1 - .../translation/java/core/OccursDcl.sv | 2 +- runtime/java/src/common/RTTIManager.java | 32 +++++++++++++------ runtime/java/src/common/Reflection.java | 14 ++++---- 5 files changed, 33 insertions(+), 20 deletions(-) diff --git a/grammars/silver/compiler/translation/java/core/NamedSignature.sv b/grammars/silver/compiler/translation/java/core/NamedSignature.sv index 47c308e1c..36bd05d76 100644 --- a/grammars/silver/compiler/translation/java/core/NamedSignature.sv +++ b/grammars/silver/compiler/translation/java/core/NamedSignature.sv @@ -142,7 +142,7 @@ top::Context ::= attr::String args::[Type] atty::Type ntty::Type if (${makeConstraintDictName(attr, ntty, top.boundVariables)}_nt == null) { throw new common.exceptions.SilverError(common.Reflection.getType(${child}) + " is not a nonterminal."); } - final int ${makeConstraintDictName(attr, ntty, top.boundVariables)} = ${makeConstraintDictName(attr, ntty, top.boundVariables)}_nt.getOccursIndex("${attr}"); + final int ${makeConstraintDictName(attr, ntty, top.boundVariables)} = ${makeConstraintDictName(attr, ntty, top.boundVariables)}_nt.getInhOccursIndex("${attr}"); """ | nothing() -> top.contextRuntimeResolveFailure end; @@ -160,7 +160,7 @@ top::Context ::= attr::String args::[Type] atty::Type inhs::Type ntty::Type if (${makeConstraintDictName(attr, ntty, top.boundVariables)}_nt == null) { throw new common.exceptions.SilverError(common.Reflection.getType(${child}) + " is not a nonterminal."); } - final int ${makeConstraintDictName(attr, ntty, top.boundVariables)} = ${makeConstraintDictName(attr, ntty, top.boundVariables)}_nt.getOccursIndex("${attr}"); + final int ${makeConstraintDictName(attr, ntty, top.boundVariables)} = ${makeConstraintDictName(attr, ntty, top.boundVariables)}_nt.getSynOccursIndex("${attr}"); """ | nothing() -> top.contextRuntimeResolveFailure end; diff --git a/grammars/silver/compiler/translation/java/core/NonTerminalDcl.sv b/grammars/silver/compiler/translation/java/core/NonTerminalDcl.sv index adae11cfb..143861727 100644 --- a/grammars/silver/compiler/translation/java/core/NonTerminalDcl.sv +++ b/grammars/silver/compiler/translation/java/core/NonTerminalDcl.sv @@ -231,7 +231,6 @@ ${if quals.data then "" else s""" public static final class Nonterminalton extends common.RTTIManager.Nonterminalton<${className}> { public String getName(){ return "${top.grammarName}:${id.name}"; } - public String[] getOccursInh() { return ${className}.occurs_inh; } } ${otImpl} diff --git a/grammars/silver/compiler/translation/java/core/OccursDcl.sv b/grammars/silver/compiler/translation/java/core/OccursDcl.sv index 2d93977ad..8d621a6d9 100644 --- a/grammars/silver/compiler/translation/java/core/OccursDcl.sv +++ b/grammars/silver/compiler/translation/java/core/OccursDcl.sv @@ -19,7 +19,7 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: if at.lookupAttribute.dcl.isAnnotation then "" else - s"\t\tcommon.RTTIManager.registerOccurs(\"${ntfn}\", \"${at.lookupAttribute.fullName}\", ${head(occursCheck).attrGlobalOccursInitIndex});\n"; + s"\t\tcommon.RTTIManager.registerOccurs(\"${ntfn}\", \"${at.lookupAttribute.fullName}\", ${toString(at.lookupAttribute.dcl.isInherited)}, ${head(occursCheck).attrGlobalOccursInitIndex});\n"; top.valueWeaving := if at.lookupAttribute.dcl.isAnnotation then diff --git a/runtime/java/src/common/RTTIManager.java b/runtime/java/src/common/RTTIManager.java index f3f03d780..2f2f1f5b8 100644 --- a/runtime/java/src/common/RTTIManager.java +++ b/runtime/java/src/common/RTTIManager.java @@ -57,8 +57,13 @@ public static Terminalton getTerminalton(String name) { } - public static void registerOccurs(String nt, String attr, int index) { - getNonterminalton(nt).occursIndices.put(attr, index); + public static void registerOccurs(String nt, String attr, boolean isInherited, int index) { + Nonterminalton ntton = getNonterminalton(nt); + if (isInherited) { + ntton.inhOccursIndices.put(attr, index); + } else { + ntton.synOccursIndices.put(attr, index); + } } @@ -102,18 +107,27 @@ public static abstract class Terminalton { // Represents a nonterminal (not a production or instance, but the nonterminal type itself.) // T = the nonterminal type (NSomething) public static abstract class Nonterminalton { - public abstract String[] getOccursInh(); public abstract String getName(); - private final Map occursIndices = new HashMap(16, 0.5f); - public final boolean hasAttr(String attrName) { - return occursIndices.containsKey(attrName); + private final Map inhOccursIndices = new HashMap(16, 0.5f); + private final Map synOccursIndices = new HashMap(16, 0.5f); + public final boolean hasInh(String attrName) { + return inhOccursIndices.containsKey(attrName); + } + public final boolean hasSyn(String attrName) { + return synOccursIndices.containsKey(attrName); + } + public final int getInhOccursIndex(String attrName) { + if (!hasInh(attrName)) { + throw new SilverError("Attribute " + attrName + " does not occur on " + getName() + "."); + } + return inhOccursIndices.get(attrName); } - public final int getOccursIndex(String attrName) { - if (!hasAttr(attrName)) { + public final int getSynOccursIndex(String attrName) { + if (!hasSyn(attrName)) { throw new SilverError("Attribute " + attrName + " does not occur on " + getName() + "."); } - return occursIndices.get(attrName); + return synOccursIndices.get(attrName); } } diff --git a/runtime/java/src/common/Reflection.java b/runtime/java/src/common/Reflection.java index 2afe900f9..05097af5b 100644 --- a/runtime/java/src/common/Reflection.java +++ b/runtime/java/src/common/Reflection.java @@ -681,10 +681,10 @@ public static Object nDeserItem(ArrayList> s, DataInput */ public static NEither getInherited(final TypeRep expected, final DecoratedNode d, final String attr) { RTTIManager.Nonterminalton nt = d.getNode().getProdleton().getNonterminalton(); - if (!nt.hasAttr(attr)) { - return new Pleft(new StringCatter("Attribute " + attr + " does not occur on " + nt.getName())); + if (!nt.hasInh(attr)) { + return new Pleft(new StringCatter("Inherited attribute " + attr + " does not occur on " + nt.getName())); } - int i = nt.getOccursIndex(attr); + int i = nt.getInhOccursIndex(attr); Object res; try { res = d.inherited(i); @@ -714,15 +714,15 @@ public static NEither getSynthesized(final TypeRep expected, final Object o, fin } DecoratedNode d = ((Decorable)o).decorate(); RTTIManager.Nonterminalton nt = d.getNode().getProdleton().getNonterminalton(); - if (!nt.hasAttr(attr)) { - return new Pleft(new StringCatter("Attribute " + attr + " does not occur on " + nt.getName())); + if (!nt.hasSyn(attr)) { + return new Pleft(new StringCatter("Synthesized attribute " + attr + " does not occur on " + nt.getName())); } - int i = nt.getOccursIndex(attr); + int i = nt.getSynOccursIndex(attr); Object res; try { res = d.synthesized(i); } catch (SilverException e) { - if (SilverException.getRootCause(e) instanceof MissingDefinitionException) { + if (SilverException.getRootCause(e) instanceof SilverError) { return new Pleft(new StringCatter(SilverException.getRootCause(e).getMessage())); } else { throw e; From d1857414cb54706051ff23ad5b09690e5e4a66fa Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 3 Aug 2023 18:55:03 -0500 Subject: [PATCH 023/283] Add tests for reflective attr access --- test/silver_features/Reflection.sv | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/silver_features/Reflection.sv b/test/silver_features/Reflection.sv index 1bd176afb..caffb9ad5 100644 --- a/test/silver_features/Reflection.sv +++ b/test/silver_features/Reflection.sv @@ -364,3 +364,17 @@ equalityTest( "Reification error at ?:\nCan't construct production silver_features:eqPair because context silver_features:myeq:MyEq a cannot be resolved at runtime", String, silver_tests); + +inherited attribute rIdIn::Integer; +synthesized attribute rIdOut::Integer; +nonterminal RThing with rIdIn, rIdOut; +production rThing top::RThing ::= +{ top.rIdOut = top.rIdIn; } + +equalityTest(getSynthesized(just(42), "silver:core:fromJust"), right(42), Either, silver_tests); +equalityTest(getSynthesized(decorate rThing() with {rIdIn = 42;}, "silver_features:rIdOut"), right(42), Either, silver_tests); +equalityTest(getInherited(decorate rThing() with {rIdIn = 42;}, "silver_features:rIdIn"), right(42), Either, silver_tests); +equalityTest(getSynthesized(decorate rThing() with {}, "silver_features:rIdOut").isLeft, true, Boolean, silver_tests); +equalityTest(getInherited(decorate rThing() with {}, "silver_features:rIdIn").isLeft, true, Boolean, silver_tests); +equalityTest(getInherited(decorate rThing() with {rIdIn = 42;}, "silver_features:rIdOut").isLeft, true, Boolean, silver_tests); +equalityTest(getSynthesized(decorate rThing() with {rIdIn = 42;}, "silver_features:rIdIn").isLeft, true, Boolean, silver_tests); From 79bc6a3c698d88ec2b84e1314c65ff37524a55fe Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 3 Aug 2023 19:53:34 -0500 Subject: [PATCH 024/283] Add utility to force a term and catch errors --- grammars/silver/langutil/reflect/Util.sv | 4 +- grammars/silver/reflect/util/Util.sv | 13 +++++++ runtime/java/src/common/Reflection.java | 47 +++++++++++++++++------- 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/grammars/silver/langutil/reflect/Util.sv b/grammars/silver/langutil/reflect/Util.sv index 76299dcc5..4a37b3b81 100644 --- a/grammars/silver/langutil/reflect/Util.sv +++ b/grammars/silver/langutil/reflect/Util.sv @@ -10,10 +10,10 @@ Document ::= x::a return fromRight( alt( - getSynthesized(x, "silver:langutil:pp"), + bind(getSynthesized(x, "silver:langutil:pp"), tryForceTerm), alt( map(\ pps::[Document] -> pp"[${ppImplode(pp", ", pps)}]", - getSynthesized(x, "silver:langutil:pps")), + bind(getSynthesized(x, "silver:langutil:pps"), tryForceTerm)), map(text, getSynthesized(x, "silver:langutil:unparse")))), reflect(x).pp); } diff --git a/grammars/silver/reflect/util/Util.sv b/grammars/silver/reflect/util/Util.sv index 3aced7a6c..5e4e529a0 100644 --- a/grammars/silver/reflect/util/Util.sv +++ b/grammars/silver/reflect/util/Util.sv @@ -67,3 +67,16 @@ runtimeTypeable a => Either ::= x::b attr::String } foreign { "java" : return "common.Reflection.getSynthesized(%@0@%, %x%, %attr%.toString())"; } + +@{- + - Force the evaluation of a term down to non-term leaves, catching any thrown errors. + - Use with caution! + -} +function tryForceTerm +Either ::= x::a +{ + return error("Foreign function"); +} foreign { + "java" : return "common.Reflection.tryForceTerm(%?x?%)"; +} + diff --git a/runtime/java/src/common/Reflection.java b/runtime/java/src/common/Reflection.java index 05097af5b..4944aeffd 100644 --- a/runtime/java/src/common/Reflection.java +++ b/runtime/java/src/common/Reflection.java @@ -688,13 +688,8 @@ public static NEither getInherited(final TypeRep expected, final DecoratedNode d Object res; try { res = d.inherited(i); - } catch (SilverException e) { - Throwable rootCause = SilverException.getRootCause(e); - if (e instanceof SilverError) { - return new Pleft(new StringCatter(SilverException.getRootCause(e).getMessage())); - } else { - throw e; - } + } catch (Throwable t) { + return new Pleft(new StringCatter(SilverException.getRootCause(t).getMessage())); } if (!TypeRep.unify(expected, getType(res))) { return new Pleft(new StringCatter("getInherited expected " + expected.toString() + ", but " + attr + " on " + nt.getName() + " gave type " + getType(res).toString())); @@ -721,16 +716,42 @@ public static NEither getSynthesized(final TypeRep expected, final Object o, fin Object res; try { res = d.synthesized(i); - } catch (SilverException e) { - if (SilverException.getRootCause(e) instanceof SilverError) { - return new Pleft(new StringCatter(SilverException.getRootCause(e).getMessage())); - } else { - throw e; - } + } catch (Throwable t) { + return new Pleft(new StringCatter(SilverException.getRootCause(t).getMessage())); } if (!TypeRep.unify(expected, getType(res))) { return new Pleft(new StringCatter("getSynthesized expected " + expected.toString() + ", but " + attr + " on " + nt.getName() + " gave type " + getType(res).toString())); } return new Pright(res); } + + /** + * Recursively force the evaluation of a term, catching any errors. + * @param o A Thunk or Node to force + * @return An Either containing either an error message or the forced input. + */ + public static NEither tryForceTerm(Object o) { + try { + traverseTerm(o); + } catch (Throwable t) { + return new Pleft(new StringCatter(SilverException.getRootCause(t).getMessage())); + } + return new Pright(o); + } + private static void traverseTerm(Object o) { + if (o instanceof Thunk) { + o = Util.demand(o); + } + if (o instanceof Node) { + Node n = (Node)o; + for (int i = n.getNumberOfChildren() - 1; i >= 0; i--) { + traverseTerm(n.getChild(i)); + } + String[] annotationNames = n.getAnnoNames(); + for (int i = annotationNames.length - 1; i >= 0; i--) { + String name = annotationNames[i]; + traverseTerm(n.getAnno(name)); + } + } + } } From 9ddaf8892b76d6d15b1097b67ae93064e058c772 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 3 Aug 2023 20:14:27 -0500 Subject: [PATCH 025/283] Make getInherited and getSynthesized force the result --- grammars/silver/langutil/reflect/Util.sv | 4 ++-- grammars/silver/reflect/util/Util.sv | 10 ++++++++++ runtime/java/src/common/Reflection.java | 2 ++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/grammars/silver/langutil/reflect/Util.sv b/grammars/silver/langutil/reflect/Util.sv index 4a37b3b81..76299dcc5 100644 --- a/grammars/silver/langutil/reflect/Util.sv +++ b/grammars/silver/langutil/reflect/Util.sv @@ -10,10 +10,10 @@ Document ::= x::a return fromRight( alt( - bind(getSynthesized(x, "silver:langutil:pp"), tryForceTerm), + getSynthesized(x, "silver:langutil:pp"), alt( map(\ pps::[Document] -> pp"[${ppImplode(pp", ", pps)}]", - bind(getSynthesized(x, "silver:langutil:pps"), tryForceTerm)), + getSynthesized(x, "silver:langutil:pps")), map(text, getSynthesized(x, "silver:langutil:unparse")))), reflect(x).pp); } diff --git a/grammars/silver/reflect/util/Util.sv b/grammars/silver/reflect/util/Util.sv index 5e4e529a0..277b1e0ff 100644 --- a/grammars/silver/reflect/util/Util.sv +++ b/grammars/silver/reflect/util/Util.sv @@ -52,6 +52,12 @@ runtimeTypeable a => a ::= x::AST end; } +-- TODO: We could add lazy versions of these, if needed. + +@{- + - Reflectively access an inherited attribute from a tree by name. + - Note that this deeply forces the result if it is a term, and catches any errors thrown in evaluation. + -} function getInherited runtimeTypeable a => Either ::= x::Decorated b with i attr::String { @@ -60,6 +66,10 @@ runtimeTypeable a => Either ::= x::Decorated b with i attr::String "java" : return "common.Reflection.getInherited(%@0@%, %x%, %attr%.toString())"; } +@{- + - Reflectively access a synthesized attribute from a tree by name. + - Note that this deeply forces the result if it is a term, and catches any errors thrown in evaluation. + -} function getSynthesized runtimeTypeable a => Either ::= x::b attr::String { diff --git a/runtime/java/src/common/Reflection.java b/runtime/java/src/common/Reflection.java index 4944aeffd..3c874b7ef 100644 --- a/runtime/java/src/common/Reflection.java +++ b/runtime/java/src/common/Reflection.java @@ -688,6 +688,7 @@ public static NEither getInherited(final TypeRep expected, final DecoratedNode d Object res; try { res = d.inherited(i); + traverseTerm(res); } catch (Throwable t) { return new Pleft(new StringCatter(SilverException.getRootCause(t).getMessage())); } @@ -716,6 +717,7 @@ public static NEither getSynthesized(final TypeRep expected, final Object o, fin Object res; try { res = d.synthesized(i); + traverseTerm(res); } catch (Throwable t) { return new Pleft(new StringCatter(SilverException.getRootCause(t).getMessage())); } From 4aab38ef13d333da6fa8bba46aec374a4d7b6f7c Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 7 Aug 2023 11:45:32 -0500 Subject: [PATCH 026/283] Include type name in genericPP --- grammars/silver/langutil/reflect/Util.sv | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/grammars/silver/langutil/reflect/Util.sv b/grammars/silver/langutil/reflect/Util.sv index 76299dcc5..fe8b10789 100644 --- a/grammars/silver/langutil/reflect/Util.sv +++ b/grammars/silver/langutil/reflect/Util.sv @@ -7,13 +7,16 @@ grammar silver:langutil:reflect; function genericPP Document ::= x::a { + local typeNamePP::Document = text(fromMaybe("", reflectTypeName(x))); return fromRight( alt( - getSynthesized(x, "silver:langutil:pp"), + map(\ pp::Document -> pp"${typeNamePP} { ${pp} }", + getSynthesized(x, "silver:langutil:pp")), alt( - map(\ pps::[Document] -> pp"[${ppImplode(pp", ", pps)}]", + map(\ pps::[Document] -> pp"${typeNamePP} [ ${ppImplode(pp", ", pps)} ]", getSynthesized(x, "silver:langutil:pps")), - map(text, getSynthesized(x, "silver:langutil:unparse")))), + map(\ unparse::String -> pp"${typeNamePP} { ${text(unparse)} }", + getSynthesized(x, "silver:langutil:unparse")))), reflect(x).pp); } From 14418e455c210caecd72b8e631bbd7872b62e59a Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 7 Aug 2023 11:46:00 -0500 Subject: [PATCH 027/283] Tweak to extension generated origin error message format --- grammars/silver/langutil/Message.sv | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/grammars/silver/langutil/Message.sv b/grammars/silver/langutil/Message.sv index a2b5b3df4..99bc354e5 100644 --- a/grammars/silver/langutil/Message.sv +++ b/grammars/silver/langutil/Message.sv @@ -145,15 +145,14 @@ String ::= m::Message -- we don't want to complain about messages raised directly in extension productions as "extension generated". if null(chain) then nothing() else originatesInExt(tail(chain)); local originsSource::Maybe = getParsedOriginLocationFromChain(chain); - local fromExtMessage::String = - "\n\n" ++ - "\nINTERNAL ERROR: The following error message originated in extension-generated code." ++ + local fromExtMessage::String = + "INTERNAL ERROR: The following error message originated in extension-generated code." ++ "\nThis is probably indicative of a bug in the extension as opposed to your code." ++ "\nThe offending extension was: '" ++ fromExt.fromJust ++ "' - please report this to it's developers." ++ - "\nThe error was: " ++ m.noLocOutput ++ "." ++ -- We do not expect the location to be useful/correct (if originsSource.isJust then "\nOrigins reports the following source location: " ++ originsSource.fromJust.unparse ++ "." else "\nOrigins chain terminates without location.") ++ + "\nThe error was: " ++ m.noLocOutput ++ "." ++ -- We do not expect the location to be useful/correct "\nOrigins chain follows:" ++ "\n" ++ showOriginInfoChain(chain) ++ "\n\n"; From 73c82f9d34deec606333e895b6d2cf8712498f7d Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 8 Aug 2023 18:54:10 -0500 Subject: [PATCH 028/283] Removing unused-and-scary tryForceTerm for now. --- grammars/silver/reflect/util/Util.sv | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/grammars/silver/reflect/util/Util.sv b/grammars/silver/reflect/util/Util.sv index 277b1e0ff..3ef3d5d27 100644 --- a/grammars/silver/reflect/util/Util.sv +++ b/grammars/silver/reflect/util/Util.sv @@ -77,16 +77,3 @@ runtimeTypeable a => Either ::= x::b attr::String } foreign { "java" : return "common.Reflection.getSynthesized(%@0@%, %x%, %attr%.toString())"; } - -@{- - - Force the evaluation of a term down to non-term leaves, catching any thrown errors. - - Use with caution! - -} -function tryForceTerm -Either ::= x::a -{ - return error("Foreign function"); -} foreign { - "java" : return "common.Reflection.tryForceTerm(%?x?%)"; -} - From fe2852bf51994f7a22dc22dcb2d0caa807e57d1b Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 8 Aug 2023 19:42:06 -0500 Subject: [PATCH 029/283] Include the initial object in printing the origins chain --- grammars/silver/langutil/Message.sv | 2 +- grammars/silver/langutil/Origins.sv | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/grammars/silver/langutil/Message.sv b/grammars/silver/langutil/Message.sv index 99bc354e5..684b03db9 100644 --- a/grammars/silver/langutil/Message.sv +++ b/grammars/silver/langutil/Message.sv @@ -154,7 +154,7 @@ String ::= m::Message else "\nOrigins chain terminates without location.") ++ "\nThe error was: " ++ m.noLocOutput ++ "." ++ -- We do not expect the location to be useful/correct "\nOrigins chain follows:" ++ - "\n" ++ showOriginInfoChain(chain) ++ + "\n" ++ showOriginInfoChain(m) ++ "\n\n"; diff --git a/grammars/silver/langutil/Origins.sv b/grammars/silver/langutil/Origins.sv index aa0a9394b..05ee9585a 100644 --- a/grammars/silver/langutil/Origins.sv +++ b/grammars/silver/langutil/Origins.sv @@ -137,11 +137,10 @@ top::OriginNote ::= extName::String function getParsedOriginLocationOrFallback Location ::= arg::a { - local chain::[OriginInfo] = getOriginInfoChain(arg); return - case getParsedOriginLocationFromChain(chain) of + case getParsedOriginLocationFromChain(getOriginInfoChain(arg)) of | just(l) -> l - | _ -> txtLoc("") + | _ -> txtLoc("") end; } @@ -149,9 +148,9 @@ Location ::= arg::a - Render the origin chain for a term as a human-readable string. -} function showOriginInfoChain -String ::= chain::[OriginInfo] +String ::= arg::a { - return show(80, ppImplode(pp"${line()} -> ", map((.pp), chain))); + return show(80, ppImplode(pp"${line()} -> ", genericPP(arg) :: map((.pp), getOriginInfoChain(arg)))); } @{- From 7d14075911edc89741b0266a40acbbf2d445d262 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 8 Aug 2023 19:53:46 -0500 Subject: [PATCH 030/283] FIx origin note order in test --- test/origintracking/tracing_origins/test.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/origintracking/tracing_origins/test.sv b/test/origintracking/tracing_origins/test.sv index 468113290..d56721077 100644 --- a/test/origintracking/tracing_origins/test.sv +++ b/test/origintracking/tracing_origins/test.sv @@ -13,8 +13,8 @@ Nat ::= equalityTest( case getOriginInfo(constructFour()) of | just(originAndRedexOriginInfo(_, _, - [traceNote("tracing_origins:test.sv:14:27"), traceNote("tracing_origins:test.sv:10:15")], _, + [traceNote("tracing_origins:test.sv:10:15"), traceNote("tracing_origins:test.sv:14:27")], _, originNotes=[traceNote("common:nat.sv:18:16")])) -> "OK" - | _ -> "NO" + | ou -> hackUnparse(ou) end, "OK", String, oitests); From 1b3a949b3956ee1eec60082a91332f62abd98a21 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 8 Aug 2023 19:54:05 -0500 Subject: [PATCH 031/283] Make Strategy and associated NTs tracked --- grammars/silver/rewrite/ASTExpr.sv | 8 ++++---- grammars/silver/rewrite/ASTPattern.sv | 8 ++++---- grammars/silver/rewrite/Strategy.sv | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/grammars/silver/rewrite/ASTExpr.sv b/grammars/silver/rewrite/ASTExpr.sv index 48ccbcae9..38c63aaf3 100644 --- a/grammars/silver/rewrite/ASTExpr.sv +++ b/grammars/silver/rewrite/ASTExpr.sv @@ -6,7 +6,7 @@ imports silver:langutil:pp; inherited attribute substitutionEnv::[Pair]; synthesized attribute value::AST; -nonterminal ASTExpr with pp, substitutionEnv, value; +tracked nonterminal ASTExpr with pp, substitutionEnv, value; propagate substitutionEnv on ASTExpr excluding letASTExpr, matchASTExpr; -- AST constructors @@ -454,7 +454,7 @@ synthesized attribute astExprs::[ASTExpr]; synthesized attribute values::[AST]; synthesized attribute appValues::[Maybe]; -nonterminal ASTExprs with pps, astExprs, substitutionEnv, values, appValues; +tracked nonterminal ASTExprs with pps, astExprs, substitutionEnv, values, appValues; propagate substitutionEnv on ASTExprs; abstract production consASTExpr @@ -492,7 +492,7 @@ ASTExprs ::= a::ASTExprs b::ASTExprs synthesized attribute namedValues::[NamedAST]; synthesized attribute namedAppValues::[Pair>]; -nonterminal NamedASTExprs with pps, substitutionEnv, namedValues, namedAppValues; +tracked nonterminal NamedASTExprs with pps, substitutionEnv, namedValues, namedAppValues; propagate substitutionEnv on NamedASTExprs; abstract production consNamedASTExpr @@ -524,7 +524,7 @@ NamedASTExprs ::= a::NamedASTExprs b::NamedASTExprs synthesized attribute namedValue::NamedAST; synthesized attribute namedAppValue::Pair>; -nonterminal NamedASTExpr with pp, substitutionEnv, namedValue, namedAppValue; +tracked nonterminal NamedASTExpr with pp, substitutionEnv, namedValue, namedAppValue; propagate substitutionEnv on NamedASTExpr; abstract production namedASTExpr diff --git a/grammars/silver/rewrite/ASTPattern.sv b/grammars/silver/rewrite/ASTPattern.sv index 789122c3b..d8ce01204 100644 --- a/grammars/silver/rewrite/ASTPattern.sv +++ b/grammars/silver/rewrite/ASTPattern.sv @@ -3,7 +3,7 @@ grammar silver:rewrite; inherited attribute matchWith::a; synthesized attribute substitution::Maybe<[Pair]>; -nonterminal ASTPattern with pp, matchWith, substitution; +tracked nonterminal ASTPattern with pp, matchWith, substitution; -- AST constructors abstract production prodCallASTPattern @@ -124,7 +124,7 @@ top::ASTPattern ::= synthesized attribute astPatterns::[ASTPattern]; -nonterminal ASTPatterns with pps, astPatterns, matchWith, substitution; +tracked nonterminal ASTPatterns with pps, astPatterns, matchWith, substitution; abstract production consASTPattern top::ASTPatterns ::= h::ASTPattern t::ASTPatterns @@ -168,7 +168,7 @@ ASTPatterns ::= a::ASTPatterns b::ASTPatterns end; } -nonterminal NamedASTPatterns with pps, substitutionEnv, matchWith<[Pair]>, substitution; +tracked nonterminal NamedASTPatterns with pps, substitutionEnv, matchWith<[Pair]>, substitution; abstract production consNamedASTPattern top::NamedASTPatterns ::= h::NamedASTPattern t::NamedASTPatterns @@ -202,7 +202,7 @@ NamedASTPatterns ::= a::NamedASTPatterns b::NamedASTPatterns end; } -nonterminal NamedASTPattern with pp, substitutionEnv, matchWith<[Pair]>, substitution; +tracked nonterminal NamedASTPattern with pp, substitutionEnv, matchWith<[Pair]>, substitution; abstract production namedASTPattern top::NamedASTPattern ::= n::String v::ASTPattern diff --git a/grammars/silver/rewrite/Strategy.sv b/grammars/silver/rewrite/Strategy.sv index 8747813dc..a4f8853bd 100644 --- a/grammars/silver/rewrite/Strategy.sv +++ b/grammars/silver/rewrite/Strategy.sv @@ -15,7 +15,7 @@ runtimeTypeable a => Maybe ::= s::Strategy x::a inherited attribute term::AST; synthesized attribute result::Maybe; -nonterminal Strategy with pp, term, result; +tracked nonterminal Strategy with pp, term, result; -- Basic combinators abstract production id From 131f3f03e33388213e72f11cd97fa9c1bcb15ff3 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 11 Aug 2023 19:09:18 -0500 Subject: [PATCH 032/283] Reset demanded count while unwinding stack since we can potentially demand a Thunk now that previously errored --- runtime/java/src/common/Thunk.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/runtime/java/src/common/Thunk.java b/runtime/java/src/common/Thunk.java index 6faf6d3a1..b5bff7513 100644 --- a/runtime/java/src/common/Thunk.java +++ b/runtime/java/src/common/Thunk.java @@ -52,9 +52,14 @@ private void handleCycleError() { throw new CycleException("Cycle detected in execution"); } private void traceCycleError(Throwable t) { + // Reset the demanded count while unwinding the stack, + // to avoid superfluous cycle errors if the error is caught and this + // thunk is later demanded again. + demanded--; // If we caught a cycle, report the start of it here. // Otherwise just re-throw the exception. - if (demanded > 1) { + if (demanded > 0) { + demanded = 0; throw new CycleTraceException("Cycle begins here", t); } else if (t instanceof RuntimeException) { throw (RuntimeException)t; From bd0195689d51cded4f7111548f4aedbfcf2aadab Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 14 Aug 2023 15:26:23 -0500 Subject: [PATCH 033/283] Make regex library nonterminals tracked --- grammars/silver/regex/AbstractSyntax.sv | 2 +- grammars/silver/regex/concrete_syntax/Regex.sv | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/grammars/silver/regex/AbstractSyntax.sv b/grammars/silver/regex/AbstractSyntax.sv index 2a775ef60..364282d06 100644 --- a/grammars/silver/regex/AbstractSyntax.sv +++ b/grammars/silver/regex/AbstractSyntax.sv @@ -10,7 +10,7 @@ synthesized attribute seqPP::Document; synthesized attribute basePP::Document; implicit synthesized attribute classPP::Maybe; -nonterminal Regex with pp, altPP, seqPP, basePP, classPP, compareTo, isEqual; +tracked nonterminal Regex with pp, altPP, seqPP, basePP, classPP, compareTo, isEqual; propagate isEqual, compareTo on Regex; diff --git a/grammars/silver/regex/concrete_syntax/Regex.sv b/grammars/silver/regex/concrete_syntax/Regex.sv index d026a9717..b0caabc55 100644 --- a/grammars/silver/regex/concrete_syntax/Regex.sv +++ b/grammars/silver/regex/concrete_syntax/Regex.sv @@ -41,7 +41,7 @@ disambiguate RegexChar_t, RegexWildcard_t { pluck RegexWildcard_t; } - - At lowest precedence, a regex consists of a series of choices (a|b|c) -} -nonterminal Regex with unparse, ast; +tracked nonterminal Regex with unparse, ast; concrete production regexEpsilon top::Regex ::= @@ -68,7 +68,7 @@ top::Regex ::= h::RegexSeq '|' t::Regex {-- - A sequence of regular expressions. -} -nonterminal RegexSeq with unparse, ast; +tracked nonterminal RegexSeq with unparse, ast; concrete production regexSeqSnoc top::RegexSeq ::= h::RegexSeq t::RegexRepetition @@ -88,7 +88,7 @@ top::RegexSeq ::= t::RegexRepetition {-- - A RegexItem with an optional repetition operator (*+?) -} -nonterminal RegexRepetition with unparse, ast; +tracked nonterminal RegexRepetition with unparse, ast; concrete production regexKleene top::RegexRepetition ::= i::RegexItem '*' @@ -122,7 +122,7 @@ top::RegexRepetition ::= i::RegexItem {-- - A single matched entity (char, wildcard, set, group) -} -nonterminal RegexItem with unparse, ast; -- characters or sequences/sets +tracked nonterminal RegexItem with unparse, ast; -- characters or sequences/sets concrete production regexCharItem top::RegexItem ::= char::RegexChar @@ -163,7 +163,7 @@ top::RegexItem ::= '(' r::Regex ')' {-- - A list of options or ranges within a regexSet. -} -nonterminal RegexCharSet with unparse, ast; +tracked nonterminal RegexCharSet with unparse, ast; concrete production regexCharSetSnoc top::RegexCharSet ::= h::RegexCharSet t::RegexCharSetItem @@ -183,7 +183,7 @@ top::RegexCharSet ::= t::RegexCharSetItem {-- - An option or range within a regexSet. -} -nonterminal RegexCharSetItem with unparse, ast; +tracked nonterminal RegexCharSetItem with unparse, ast; concrete production regexSetChar top::RegexCharSetItem ::= char::RegexChar @@ -203,7 +203,7 @@ top::RegexCharSetItem ::= l::RegexChar '-' u::RegexChar {-- - A character, escaped or otherwise. -} -nonterminal RegexChar with unparse, ast; +tracked nonterminal RegexChar with unparse, ast; concrete production regexChar top::RegexChar ::= char::RegexChar_t From 42c596078d1c851a8d559844588be364e69a348e Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 15 Aug 2023 13:18:33 -0500 Subject: [PATCH 034/283] Use new data syntax for origins --- grammars/silver/core/Origins.sv | 182 +++++++++++--------------------- 1 file changed, 60 insertions(+), 122 deletions(-) diff --git a/grammars/silver/core/Origins.sv b/grammars/silver/core/Origins.sv index e3b3f1df5..f86eef682 100644 --- a/grammars/silver/core/Origins.sv +++ b/grammars/silver/core/Origins.sv @@ -4,158 +4,98 @@ grammar silver:core; -- Don't change their names, grammar locations, or parameters unless you know what your doing -- (and have made the appropriate runtime and compiler changes!) -data nonterminal OriginInfo with originNotes, originType; -data nonterminal OriginInfoType; -closed data nonterminal OriginNote; - -synthesized attribute notepp :: Maybe occurs on OriginNote; - -synthesized attribute isNewlyConstructed :: Boolean occurs on OriginInfo; -annotation originNotes :: [OriginNote]; -annotation originType :: OriginInfoType; - -synthesized attribute isBogus :: Boolean occurs on OriginInfoType; - -@@{- ## Origin info types +@{- Origin info types - - Single instances of the following are constructed once in OriginsUtil.java in the runtime and used - to indicate when the origin information was computed. -} - +data OriginInfoType = @{- Information was computed at the site of invoking a constructor (this is "normal") -} -abstract production setAtConstructionOIT -top::OriginInfoType ::= -{ - top.isBogus = false; -} - + setAtConstructionOIT @{- Result of calling new(x) on a tracked nonterminal (including children of x that were also new-ed) -} -abstract production setAtNewOIT -top::OriginInfoType ::= -{ - top.isBogus = false; -} - +| setAtNewOIT @{- - Result of forwarding to a nonterminal. This is a little weird because there's an extra indirection. - The attached origin info has an origin pointing to the value that was computed for the production - to forward to. At forwarding time (in evalForward) it's copied and has an origin attached of this - type. This is so that it's possible to tell something was forwarded to. -} -abstract production setAtForwardingOIT -top::OriginInfoType ::= -{ - top.isBogus = false; -} - +| setAtForwardingOIT @{- Result of doing foo.bar (this is "normal") -} -abstract production setAtAccessOIT -top::OriginInfoType ::= -{ - top.isBogus = false; -} - +| setAtAccessOIT @{- The origin was set when constructing a concrete production in the parser (will be a parsedOriginInfo) -} -abstract production setFromParserOIT -top::OriginInfoType ::= -{ - top.isBogus = false; -} - +| setFromParserOIT @{- The origin was set in something constructed in a parser action block -} -abstract production setFromParserActionOIT -top::OriginInfoType ::= -{ - top.isBogus = true; -} - +| setFromParserActionOIT @{- - This is a catchall for stuff constructed in java (really only used in the SilverComparator and in the XML lib) - where the java library dosen't keep track of origins info meaningfully -} -abstract production setFromFFIOIT -top::OriginInfoType ::= -{ - top.isBogus = true; -} - +| setFromFFIOIT @{- This originates from something via a call to `reflect` -} -abstract production setFromReflectionOIT -top::OriginInfoType ::= -{ - top.isBogus = true; -} - +| setFromReflectionOIT @{- This originates from it's reflective representation via a call to `reify` -} -abstract production setFromReificationOIT -top::OriginInfoType ::= -{ - top.isBogus = true; -} - +| setFromReificationOIT @{- - This was constructed in `main` or in a function called from `main` without - passing through a context with a meaningful nonterminal to use instead -} -abstract production setFromEntryOIT -top::OriginInfoType ::= -{ - top.isBogus = false; -} - +| setFromEntryOIT @{- This is a global -} -abstract production setInGlobalOIT -top::OriginInfoType ::= -{ - top.isBogus = false; -} - - -@@{- ## OriginInfo represent the origin information contained in nodes/values -} +| setInGlobalOIT +; +synthesized attribute isBogus :: Boolean occurs on OriginInfoType; +aspect isBogus on OriginInfoType of +| setFromParserActionOIT() -> true +| setFromFFIOIT() -> true +| setFromReflectionOIT() -> true +| _ -> false +end; + + +@{- OriginInfo represent the origin information contained in nodes/values. + - originOriginInfo and originAndRedexOriginInfo are the same modulo if a redex is set or not + - `origin` is the node that this node originated from, `originNotes` are + - notes set on the control-flow path to where the origin was set. + - `redex` is the node that catalyzed the movement of this node to where it + - is now (i.e. where a `foo.bar` happaned that 'moved' the `bar` in the new + - tree. `redexNotes` are similarly the notes set on the control-flow path to + - where the tree motion that set the redex occurred. + - `newlyConstructed` is `er` from the paper, and represents if the node + - is not the result of a basically no-op transformation. + -} +data OriginInfo = @{- 'catchall' for origins that don't encode other info -} -abstract production otherOriginInfo -top::OriginInfo ::= source::String -{ - top.isNewlyConstructed = true; -} - + otherOriginInfo source::String @{- The production originated from a sequence of tokens at `source` in Copper -} -abstract production parsedOriginInfo -top::OriginInfo ::= source::Location -{ - top.isNewlyConstructed = true; -} - -@@{- The following two are the same modulo if a redex is set or not - - `origin` is the node that this node originated from, `originNotes` are - - notes set on the control-flow path to where the origin was set. - - `redex` is the node that catalyzed the movement of this node to where it - - is now (i.e. where a `foo.bar` happaned that 'moved' the `bar` in the new - - tree. `redexNotes` are similarly the notes set on the control-flow path to - - where the tree motion that set the redex occurred. - - `newlyConstructed` is `er` from the paper, and represents if the node - - is not the result of a basically no-op transformation. - -} +| parsedOriginInfo source::Location @{- See above -} -abstract production originOriginInfo -top::OriginInfo ::= origin :: a - newlyConstructed :: Boolean -{ - top.isNewlyConstructed = newlyConstructed; -} - +| originOriginInfo origin::a newlyConstructed::Boolean @{- See above -} -abstract production originAndRedexOriginInfo -top::OriginInfo ::= origin :: a - redex :: b - redexNotes :: [OriginNote] - newlyConstructed :: Boolean -{ - top.isNewlyConstructed = newlyConstructed; -} +| originAndRedexOriginInfo origin::a redex::b redexNotes::[OriginNote] newlyConstructed::Boolean + with originNotes, originType; + +annotation originNotes :: [OriginNote]; +annotation originType :: OriginInfoType; + +synthesized attribute isNewlyConstructed :: Boolean occurs on OriginInfo; +aspect isNewlyConstructed on OriginInfo of +| otherOriginInfo(_) -> true +| parsedOriginInfo(_) -> true +| originOriginInfo(_, nc) -> nc +| originAndRedexOriginInfo(_, _, _, nc) -> nc +end; + +@{- + - OriginNotes are various pieces of information associated with the origin of a term. + - A notepp can optionally be supplied, if the note should be displayed in stack traces + - and other diagnostic messages. + -} +closed data nonterminal OriginNote with notepp; +synthesized attribute notepp :: Maybe; aspect default production top::OriginNote ::= @@ -197,9 +137,7 @@ top::OriginNote ::= loc::Location -} abstract production ruleLocNote top::OriginNote ::= attributeName::String sourceGrammar::String prod::String nt::String sourceLocation::Location -{ - -} +{} @{- From 4bc7b6fec4359b8d6c2dafbc5caec6d57918b567 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 25 Sep 2023 22:10:15 -0500 Subject: [PATCH 035/283] Fix import scoping and name resolution to permit shadowing of names in `silver:core` --- .../silver/compiler/definition/core/QName.sv | 55 ++++++++----------- .../silver/compiler/definition/core/Root.sv | 12 +++- .../silver/compiler/definition/env/DclInfo.sv | 5 +- .../silver/compiler/definition/env/Defs.sv | 2 +- .../silver/compiler/definition/env/Env.sv | 26 ++++++++- .../silver/compiler/driver/util/FlowTypes.sv | 2 +- .../silver/compiler/driver/util/RootSpec.sv | 17 +++--- .../compiler/langserver/ReferenceLocations.sv | 14 ++--- .../compiler/modification/copper/ParserDcl.sv | 2 +- grammars/silver/util/deque/Deque.sv | 2 +- 10 files changed, 80 insertions(+), 57 deletions(-) diff --git a/grammars/silver/compiler/definition/core/QName.sv b/grammars/silver/compiler/definition/core/QName.sv index c4ee8100e..bfcf99879 100644 --- a/grammars/silver/compiler/definition/core/QName.sv +++ b/grammars/silver/compiler/definition/core/QName.sv @@ -187,71 +187,60 @@ top::QNameAttrOccur ::= at::QName top.unparse = at.unparse; propagate env; - -- We start with all attributes we find with the name `at`: - local attrs :: [AttributeDclInfo] = at.lookupAttribute.dcls; - - -- Then we filter to just those that appear to have an occurrence on `top.attrFor`: - local narrowed :: [[OccursDclInfo]] = - -- The occurs dcls on this nonterminal for - map(getOccursDcl(_, top.attrFor.typeName, top.env), - -- the full names of each candidate - map((.fullName), attrs)); - -- TODO: BUG: this disambiguates, but doesn't find full-named that aren't in scope with short names! - -- i.e. 'import somthing as prefixed; something.a' won't find prefixed:a. + local attrs :: [AttributeDclInfo] = + if top.attrFor.isError + then at.lookupAttribute.dcls + else getOccuringAttrDcl(top.attrFor.typeName, at.name, top.env); - -- Occurs dcls for `at` on `top.attrFor` (there should be only one) - local dclsNarrowed :: [OccursDclInfo] = concat(narrowed); - - -- Attribute dcls - local attrsNarrowed :: [AttributeDclInfo] = zipFilterDcls(attrs, narrowed); + local dcls :: [OccursDclInfo] = + case attrs of + | attr :: _ -> getOccursDcl(attr.fullName, top.attrFor.typeName, top.env) + | _ -> [] + end; -- This basically has to mirror the logic in errors below! - top.found = - !(null(at.lookupAttribute.dcls) || - top.attrFor.isError || - null(dclsNarrowed) || - length(attrsNarrowed) != 1); + top.found = at.lookupAttribute.found && !top.attrFor.isError && !null(dcls) && length(attrs) == 1; - top.attrFound = !null(attrs); + top.attrFound = at.lookupAttribute.found; top.errors := -- If we fail to look up the attribute, just report that. - if null(at.lookupAttribute.dcls) then + if !at.lookupAttribute.found then at.lookupAttribute.errors -- If we're looking up an attribute on `errorType`, an error is already raised, don't create noise else if top.attrFor.isError then [] -- If no attribute occurs on this type, raise that error - else if null(dclsNarrowed) then + else if null(dcls) then -- This is a heuristic error message for the situation where you have a type, but haven't imported -- the grammar declaring that type. (if lastIndexOf(":", top.attrFor.typeName) > 0 && null(getTypeDcl(top.attrFor.typeName, top.env)) then [err(at.location, "Attribute '" ++ at.name ++ "' does not occur on '" ++ prettyType(top.attrFor) ++ "'. Perhaps import '" ++ substring(0, lastIndexOf(":", top.attrFor.typeName), top.attrFor.typeName) ++ "'?")] else - [err(at.location, "Attribute '" ++ at.name ++ "' does not occur on '" ++ prettyType(top.attrFor) ++ "'. Looked at:\n" ++ printPossibilities(attrs))] + [err(at.location, "Attribute '" ++ at.name ++ "' does not occur on '" ++ prettyType(top.attrFor) ++ "'. Looked at:\n" ++ printPossibilities(at.lookupAttribute.dcls))] ) -- If more than one attribute on the same _short name_ occurs, raise ambiguity - else if length(attrsNarrowed) > 1 then - [err(at.location, "Ambiguous reference to attribute occurring on '" ++ at.name ++ "'. Possibilities are:\n" ++ printPossibilities(attrsNarrowed))] + else if length(attrs) > 1 then + [err(at.location, "Ambiguous reference to attribute occurring on '" ++ prettyType(top.attrFor) ++ "'. Possibilities are:\n" ++ printPossibilities(attrs))] -- If this same attribute has multiple occurences (must be due to orphaned occurs) - else []; {-if length(dclsNarrowed) > 1 then - [err(at.location, "There are erroneously multiple attribute occurrences for '" ++ at.name ++ "'. Possibilities are:\n" ++ printPossibilities(dclsNarrowed))] + else []; {-if length(dcls) > 1 then + [err(at.location, "There are erroneously multiple attribute occurrences for '" ++ at.name ++ "'. Possibilities are:\n" ++ printPossibilities(dcls))] else [];-} -- TODO: This last bit is disabled because we have problems with importing grammars multiple times. -- TODO FIXME: enable this, and fix the grammar import issues! - production resolvedDcl::OccursDclInfo = if top.found then head(dclsNarrowed) else + production resolvedDcl::OccursDclInfo = if top.found then head(dcls) else error("INTERNAL ERROR: Accessing dcl of occurrence " ++ at.name ++ " at " ++ top.grammarName ++ " " ++ top.location.unparse); resolvedDcl.givenNonterminalType = top.attrFor; production resolvedTypeScheme::PolyType = resolvedDcl.typeScheme; production requiredContexts::Contexts = foldContexts(resolvedTypeScheme.contexts); requiredContexts.env = top.env; - top.typerep = if top.found then determineAttributeType(head(dclsNarrowed), top.attrFor) else errorType(); + top.typerep = if top.found then determineAttributeType(head(dcls), top.attrFor) else errorType(); top.dcl = resolvedDcl; - top.attrDcl = if top.found then head(attrsNarrowed) else + top.attrDcl = if top.found then head(attrs) else -- Workaround fix for proper error reporting - appairently there are some places where this is still demanded. - if !null(attrs) then head(attrs) else + if at.lookupAttribute.found then at.lookupAttribute.dcl else error("INTERNAL ERROR: Accessing dcl of attribute " ++ at.name ++ " at " ++ top.grammarName ++ " " ++ top.location.unparse); } diff --git a/grammars/silver/compiler/definition/core/Root.sv b/grammars/silver/compiler/definition/core/Root.sv index 0306ecdf7..a2126ec8d 100644 --- a/grammars/silver/compiler/definition/core/Root.sv +++ b/grammars/silver/compiler/definition/core/Root.sv @@ -38,11 +38,21 @@ top::Root ::= gdcl::GrammarDcl ms::ModuleStmts ims::ImportStmts ags::AGDcls top.jarName := ags.jarName; -- We have an mismatch in how the environment gets put together: - -- Outermost, we have grammar-wide imports in one sope. That's top.globalImports here. + -- Outermost, we have grammar-wide imports in one scope. That's top.globalImports here. -- THEN, we have this particular file's list of local imports. That's ims.defs here. -- THEN, we have the grammar-wide definitions, from the whole grammr. That's top.env here. -- So we're kind of injecting local imports in between two grammar-wide things there. ags.env = appendEnv(top.env, newScopeEnv(ims.defs, occursEnv(ims.occursDefs, top.globalImports))); + + -- See https://github.com/melt-umn/silver/issues/444. + -- An explicit file-scope import of silver:core would cause silver:core to not get implicitly imported + -- for the whole grammar, but since it is file scope silver:core wouldn't be visible in other files. + -- This behaviour is unintuitative, and the user probably meant to write a grammar-scope import hiding + -- or renaming something - so raise an error in this case. + top.errors <- + if contains("silver:core", ims.moduleNames) + then [err(ims.location, "File-scope import of silver:core is non supported. Did you mean 'imports silver:core ...;'?")] + else []; } concrete production noGrammarDcl diff --git a/grammars/silver/compiler/definition/env/DclInfo.sv b/grammars/silver/compiler/definition/env/DclInfo.sv index bc219af49..da9d7ab0f 100644 --- a/grammars/silver/compiler/definition/env/DclInfo.sv +++ b/grammars/silver/compiler/definition/env/DclInfo.sv @@ -2,7 +2,8 @@ grammar silver:compiler:definition:env; imports silver:compiler:definition:type; imports silver:compiler:definition:type:syntax only mentionedAliases; -imports silver:regex; + +imports silver:regex as r; -- Some of these nonterminals are closed, but the dispatch attributes are -- defined in silver:compiler:definition:core, and we don't want to have defaults for those: @@ -179,7 +180,7 @@ top::TypeDclInfo ::= fn::String ks::[Kind] data::Boolean closed::Boolean tracked top.isClosed = closed; } abstract production termDcl -top::TypeDclInfo ::= fn::String regex::Regex easyName::Maybe genRepeatProb::Maybe +top::TypeDclInfo ::= fn::String regex::r:Regex easyName::Maybe genRepeatProb::Maybe { top.fullName = fn; diff --git a/grammars/silver/compiler/definition/env/Defs.sv b/grammars/silver/compiler/definition/env/Defs.sv index ea8049d26..54e745ea0 100644 --- a/grammars/silver/compiler/definition/env/Defs.sv +++ b/grammars/silver/compiler/definition/env/Defs.sv @@ -161,7 +161,7 @@ Def ::= sg::String sl::Location fn::String ks::[Kind] data::Boolean closed: return typeDef(defaultEnvItem(ntDcl(fn,ks,data,closed,tracked,sourceGrammar=sg,sourceLocation=sl))); } function termDef -Def ::= sg::String sl::Location fn::String regex::Regex easyName::Maybe genRepeatProb::Maybe +Def ::= sg::String sl::Location fn::String regex::r:Regex easyName::Maybe genRepeatProb::Maybe { -- Terminals are also in the value namespace as terminal identifiers return typeValueDef( diff --git a/grammars/silver/compiler/definition/env/Env.sv b/grammars/silver/compiler/definition/env/Env.sv index 9145bf9a6..9df362c01 100644 --- a/grammars/silver/compiler/definition/env/Env.sv +++ b/grammars/silver/compiler/definition/env/Env.sv @@ -44,9 +44,9 @@ top::Env ::= } function toEnv -Env ::= d::[Def] +Env ::= d::[Def] od::[OccursDclInfo] { - return newScopeEnv(d, emptyEnv()); + return occursEnv(od, newScopeEnv(d, emptyEnv())); } {-- @@ -180,6 +180,28 @@ function getAttrDclAll return searchEnvAll(search, e.attrTree); } +{-- + - Look up the short name of an attribute, + - disambiguating based on some nonterminal on which it is known to occur. + -} +function getOccuringAttrDcl +[AttributeDclInfo] ::= fnnt::String search::String e::Env +{ + return getOccuringAttrDclHelp(map((.attrOccurring), getAttrOccursOn(fnnt, e)), search, e.attrTree); +} +function getOccuringAttrDclHelp +[AttributeDclInfo] ::= allAttrs::[String] search::String e::[EnvTree] +{ + local found :: [AttributeDclInfo] = + filter( + \ a::AttributeDclInfo -> contains(a.fullName, allAttrs), + searchEnvTree(search, head(e))); + + return if null(e) then [] + else if null(found) then getOccuringAttrDclHelp(allAttrs, search, tail(e)) + else found; +} + function getOccursDcl [OccursDclInfo] ::= fnat::String fnnt::String e::Env { diff --git a/grammars/silver/compiler/driver/util/FlowTypes.sv b/grammars/silver/compiler/driver/util/FlowTypes.sv index edf105a22..df7e4cdca 100644 --- a/grammars/silver/compiler/driver/util/FlowTypes.sv +++ b/grammars/silver/compiler/driver/util/FlowTypes.sv @@ -26,7 +26,7 @@ top::Compilation ::= g::Grammars r::Grammars buildGrammars::[String] benv::Bu -- It's possible (likely) we could do better than using the overall env here. local allRealDefs :: [Def] = flatMap((.defs), allLatestGrammars); local allRealOccursDefs :: [OccursDclInfo] = flatMap((.occursDefs), allLatestGrammars); - local allRealEnv :: Env = occursEnv(allRealOccursDefs, toEnv(allRealDefs)); + local allRealEnv :: Env = toEnv(allRealDefs, allRealOccursDefs); -- List of all productions local allProds :: [ValueDclInfo] = foldr(consDefs, nilDefs(), allRealDefs).prodDclList; diff --git a/grammars/silver/compiler/driver/util/RootSpec.sv b/grammars/silver/compiler/driver/util/RootSpec.sv index 2045e77db..899193a06 100644 --- a/grammars/silver/compiler/driver/util/RootSpec.sv +++ b/grammars/silver/compiler/driver/util/RootSpec.sv @@ -66,14 +66,15 @@ top::RootSpec ::= g::Grammar oldInterface::Maybe grammarName:: g.grammarName = grammarName; -- Create the environments for this grammar - g.env = occursEnv(g.occursDefs, toEnv(g.defs)); - g.globalImports = - occursEnv( - if contains("silver:core", g.moduleNames) || grammarName == "silver:core" then g.importedOccursDefs - else g.importedOccursDefs ++ head(searchEnvTree("silver:core", top.compiledGrammars)).occursDefs, - toEnv( - if contains("silver:core", g.moduleNames) || grammarName == "silver:core" then g.importedDefs - else g.importedDefs ++ head(searchEnvTree("silver:core", top.compiledGrammars)).defs)); + g.env = toEnv(g.defs, g.occursDefs); + + -- silver:core gets implicitly imported in a new outermost scope, unless imported explicitly + local coreGrammar::Decorated RootSpec = head(searchEnvTree("silver:core", top.compiledGrammars)); + local coreEnv::Env = + if contains("silver:core", g.moduleNames) || grammarName == "silver:core" + then emptyEnv() + else toEnv(coreGrammar.defs, coreGrammar.occursDefs); + g.globalImports = occursEnv(g.importedOccursDefs, newScopeEnv(g.importedDefs, coreEnv)); -- This grammar, its direct imports, and only transitively close over exports and TRIGGERED conditional imports. -- i.e. these are the things that we really, truly depend upon. (in the sense that we get their symbols) diff --git a/grammars/silver/compiler/langserver/ReferenceLocations.sv b/grammars/silver/compiler/langserver/ReferenceLocations.sv index ccc3dc8f0..86c674c22 100644 --- a/grammars/silver/compiler/langserver/ReferenceLocations.sv +++ b/grammars/silver/compiler/langserver/ReferenceLocations.sv @@ -101,9 +101,9 @@ aspect attributeRefLocs on Constraint using <- of end; aspect valueRefLocs on top::ProductionStmt using <- of -| localAttributeDcl(_, _, id, _, _, _) -> map(\dcl :: ValueDclInfo -> (id.location, dcl), getValueDcl(id.name, top.env)) -| productionAttributeDcl(_, _, id, _, _, _) -> map(\dcl :: ValueDclInfo -> (id.location, dcl), getValueDcl(id.name, top.env)) -| forwardProductionAttributeDcl(_, _, _, id, _) -> map(\dcl :: ValueDclInfo -> (id.location, dcl), getValueDcl(id.name, top.env)) +| localAttributeDcl(_, _, n, _, _, _) -> map(\dcl :: ValueDclInfo -> (n.location, dcl), getValueDcl(n.name, top.env)) +| productionAttributeDcl(_, _, n, _, _, _) -> map(\dcl :: ValueDclInfo -> (n.location, dcl), getValueDcl(n.name, top.env)) +| forwardProductionAttributeDcl(_, _, _, n, _) -> map(\dcl :: ValueDclInfo -> (n.location, dcl), getValueDcl(n.name, top.env)) end; aspect valueRefLocs on ProductionStmt using := of @@ -188,11 +188,11 @@ end; -- Productions -- LHS aspect valueRefLocs on top::ProductionLHS using <- of -| productionLHS(id, _, _) -> map(\dcl :: ValueDclInfo -> (id.location, dcl), getValueDcl(id.name, top.env)) +| productionLHS(n, _, _) -> map(\dcl :: ValueDclInfo -> (n.location, dcl), getValueDcl(n.name, top.env)) end; aspect valueRefLocs on top::AspectProductionLHS using <- of -| aspectProductionLHSFull(id, _) -> map(\dcl :: ValueDclInfo -> (id.location, dcl), getValueDcl(id.name, top.env)) +| aspectProductionLHSFull(n, _) -> map(\dcl :: ValueDclInfo -> (n.location, dcl), getValueDcl(n.name, top.env)) end; aspect typeRefLocs on ProductionLHS using <- of @@ -209,11 +209,11 @@ end; --RHS aspect valueRefLocs on top::ProductionRHSElem using <- of -| productionRHSElem(id, _, _) -> map(\dcl :: ValueDclInfo -> (id.location, dcl), getValueDcl(id.name, top.env)) +| productionRHSElem(n, _, _) -> map(\dcl :: ValueDclInfo -> (n.location, dcl), getValueDcl(n.name, top.env)) end; aspect valueRefLocs on top::AspectRHSElem using <- of -| aspectRHSElemFull(id, _) -> map(\dcl :: ValueDclInfo -> (id.location, dcl), getValueDcl(id.name, top.env)) +| aspectRHSElemFull(n, _) -> map(\dcl :: ValueDclInfo -> (n.location, dcl), getValueDcl(n.name, top.env)) end; aspect typeRefLocs on ProductionRHSElem using <- of diff --git a/grammars/silver/compiler/modification/copper/ParserDcl.sv b/grammars/silver/compiler/modification/copper/ParserDcl.sv index 101606344..62c71946d 100644 --- a/grammars/silver/compiler/modification/copper/ParserDcl.sv +++ b/grammars/silver/compiler/modification/copper/ParserDcl.sv @@ -25,7 +25,7 @@ top::AGDcl ::= 'parser' n::Name '::' t::TypeExpr '{' m::ParserComponents '}' moduleExportedDefs(top.location, top.compiledGrammars, m.grammarDependencies, m.moduleNames, []); t.env = top.env; - m.env = appendEnv(toEnv(med.defs), top.env); + m.env = appendEnv(toEnv(med.defs, med.occursDefs), top.env); production fName :: String = top.grammarName ++ ":" ++ n.name; diff --git a/grammars/silver/util/deque/Deque.sv b/grammars/silver/util/deque/Deque.sv index 3ad84bcff..315136e1a 100644 --- a/grammars/silver/util/deque/Deque.sv +++ b/grammars/silver/util/deque/Deque.sv @@ -1,6 +1,6 @@ grammar silver:util:deque; -import silver:core with reverse as listReverse; +imports silver:core with reverse as listReverse; -- This is all based on Okasaki 1998. From 5bff9a776e29fa78e206d416df737261d05f0c29 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 25 Sep 2023 22:23:41 -0500 Subject: [PATCH 036/283] Limit check for prods with the same name to other prods on the same nonterminal --- .../silver/compiler/definition/core/ProductionDcl.sv | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/grammars/silver/compiler/definition/core/ProductionDcl.sv b/grammars/silver/compiler/definition/core/ProductionDcl.sv index 3f2c82d6b..a69ae6d9a 100644 --- a/grammars/silver/compiler/definition/core/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/core/ProductionDcl.sv @@ -49,12 +49,18 @@ top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::Pr if null(body.productionAttributes) then [] else [prodOccursDef(top.grammarName, id.location, namedSig, body.productionAttributes)]; + -- Other productions on the same nonterminal with the same name: + local sameNTProds::[ValueDclInfo] = filter( + \ v::ValueDclInfo -> + case v of + | prodDcl(ns, _) -> ns.outputElement.typerep == namedSig.outputElement.typerep + | _ -> false + end, + getValueDclAll(id.name, top.env)); top.errors <- if length(getValueDclAll(fName, top.env)) > 1 then [err(id.location, "Value '" ++ fName ++ "' is already bound.")] - - -- TODO: Narrow this down to just a list of productions of the same nonterminal before deciding to error. - else if length(getValueDclAll(id.name, top.env)) > 1 + else if length(sameNTProds) > 1 then [err(top.location, "Production " ++ id.name ++ " shares a name with another production from an imported grammar. Either this production is meant to be an aspect, or you should use 'import ... with " ++ id.name ++ " as ...' to change the other production's apparent name.")] else []; From 219a64b65313c46dcec3f327e9f0b75c49d9f184 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 26 Sep 2023 13:13:57 -0500 Subject: [PATCH 037/283] Add tree-sharing-demo to Jenkins --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 244f36da9..26732a387 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -137,7 +137,7 @@ melt.trynode('silver') { // Projects with 'develop' as main branch, we'll try to build specific branch names if they exist def github_projects = ["/melt-umn/ableC", "/melt-umn/Oberon0", "/melt-umn/meta-ocaml-lite", "/melt-umn/lambda-calculus", "/melt-umn/rewriting-regex-matching", "/melt-umn/rewriting-optimization-demo", - "/melt-umn/caml-light"] + "/melt-umn/caml-light", "/melt-umn/tree-sharing-demo"] // These are not currently maintened: "/internal/ring" // Specific other jobs to build def specific_jobs = ["/internal/matlab/master"] From f6550eddcfabd3ab01698432b0807b2c1bf465bd Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 28 Sep 2023 15:10:17 -0500 Subject: [PATCH 038/283] Temporarily exclude location annotation in metatranslation --- grammars/silver/compiler/metatranslation/Translation.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/compiler/metatranslation/Translation.sv b/grammars/silver/compiler/metatranslation/Translation.sv index c6df074ec..c95ff8c8f 100644 --- a/grammars/silver/compiler/metatranslation/Translation.sv +++ b/grammars/silver/compiler/metatranslation/Translation.sv @@ -129,7 +129,7 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs givenLocation, baseExpr(qName(givenLocation, prodName), location=givenLocation), children.translation, - annotations.translation), + filter(\ a::(String, Expr) -> a.1 != "location", annotations.translation)), antiquoteTranslation); production attribute patternAntiquoteTranslation::Maybe with orElse; From fed9def6f56313ddebb951d2986948fa47831d41 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 22 Sep 2023 00:35:21 -0500 Subject: [PATCH 039/283] Initial pass changing the Silver compiler to use origin tracking --- .../analysis/typechecking/core/AspectDcl.sv | 18 +- .../analysis/typechecking/core/ClassDcl.sv | 2 +- .../analysis/typechecking/core/Expr.sv | 70 +-- .../analysis/typechecking/core/GlobalDcl.sv | 2 +- .../analysis/typechecking/core/InstanceDcl.sv | 6 +- .../analysis/typechecking/core/OccursDcl.sv | 2 +- .../typechecking/core/ProductionBody.sv | 20 +- .../typechecking/core/ProductionDcl.sv | 2 +- .../compiler/analysis/uniqueness/Expr.sv | 44 +- .../analysis/uniqueness/ProductionBody.sv | 2 +- .../warnings/flow/FlowTypeCopyEquation.sv | 6 +- .../compiler/analysis/warnings/flow/Inh.sv | 106 ++-- .../analysis/warnings/flow/MissingSynEq.sv | 14 +- .../analysis/warnings/flow/MwdaFlag.sv | 13 + .../warnings/flow/OrphanedEquation.sv | 18 +- .../analysis/warnings/flow/OrphanedOccurs.sv | 4 +- .../warnings/flow/OrphanedProduction.sv | 2 +- .../concrete_syntax/NonTerminalDcl.sv | 4 +- .../definition/concrete_syntax/ParserSpec.sv | 4 +- .../concrete_syntax/ProductionDcl.sv | 22 +- .../definition/concrete_syntax/RootSpec.sv | 2 +- .../definition/concrete_syntax/TerminalDcl.sv | 30 +- .../silver/compiler/definition/core/AGDcl.sv | 19 +- .../compiler/definition/core/Annotation.sv | 6 +- .../compiler/definition/core/AspectDcl.sv | 55 +-- .../compiler/definition/core/AttributeDcl.sv | 12 +- .../compiler/definition/core/ClassDcl.sv | 46 +- .../compiler/definition/core/DclInfo.sv | 132 ++--- .../silver/compiler/definition/core/Expr.sv | 264 ++++------ .../compiler/definition/core/FunctionDcl.sv | 20 +- .../compiler/definition/core/GlobalDcl.sv | 8 +- .../compiler/definition/core/GrammarParts.sv | 2 +- .../compiler/definition/core/InstanceDcl.sv | 32 +- .../compiler/definition/core/ModuleStmts.sv | 80 ++- .../silver/compiler/definition/core/Name.sv | 9 +- .../definition/core/NonTerminalDcl.sv | 22 +- .../compiler/definition/core/OccursDcl.sv | 38 +- .../definition/core/ProductionBody.sv | 152 +++--- .../compiler/definition/core/ProductionDcl.sv | 40 +- .../silver/compiler/definition/core/QName.sv | 72 +-- .../silver/compiler/definition/core/Root.sv | 12 +- .../silver/compiler/definition/core/Type.sv | 22 +- .../compiler/definition/core/TypeDecl.sv | 10 +- .../silver/compiler/definition/env/Context.sv | 2 +- .../compiler/definition/flow/env/Expr.sv | 10 +- .../definition/flow/syntax/FlowSpec.sv | 36 +- .../definition/origins/BlockContext.sv | 25 +- .../silver/compiler/definition/type/Kind.sv | 2 +- .../silver/compiler/definition/type/Type.sv | 8 +- .../definition/type/syntax/AspectDcl.sv | 4 +- .../definition/type/syntax/ClassDcl.sv | 2 +- .../definition/type/syntax/Constraint.sv | 48 +- .../definition/type/syntax/FunctionDcl.sv | 2 +- .../definition/type/syntax/InstanceDcl.sv | 2 +- .../definition/type/syntax/KindExpr.sv | 2 +- .../definition/type/syntax/ProductionDcl.sv | 2 +- .../definition/type/syntax/TypeExpr.sv | 93 ++-- .../silver/compiler/driver/BuildProcess.sv | 18 +- .../extension/astconstruction/Syntax.sv | 6 +- .../extension/attrsection/AttrSection.sv.md | 12 +- .../compiler/extension/auto_ast/AutoAst.sv | 28 +- .../compiler/extension/autoattr/BiEquality.sv | 41 +- .../compiler/extension/autoattr/DclInfo.sv | 138 +++--- .../compiler/extension/autoattr/Destruct.sv | 61 +-- .../compiler/extension/autoattr/Equality.sv | 20 +- .../compiler/extension/autoattr/Functor.sv | 47 +- .../compiler/extension/autoattr/Inherited.sv | 18 +- .../compiler/extension/autoattr/Monoid.sv | 37 +- .../compiler/extension/autoattr/Ordering.sv | 22 +- .../compiler/extension/autoattr/Propagate.sv | 61 +-- .../compiler/extension/autoattr/Threaded.sv | 81 ++-- .../autoattr/convenience/Convenience.sv | 77 ++- .../extension/constructparser/Construct.sv | 60 +-- .../extension/convenience/Children.sv | 2 +- .../extension/convenience/Convenience.sv | 32 +- .../compiler/extension/convenience/Lists.sv | 20 +- .../extension/convenience/Productions.sv | 18 +- .../convenience/ShortLocalProdAttrDeclDef.sv | 30 +- .../convenienceaspects/AbstractSyntax.sv | 60 +-- .../convenienceaspects/ConcreteSyntax.sv | 16 +- .../silver/compiler/extension/data/DataDcl.sv | 29 +- .../extension/deprecation/BuildWith.sv | 4 +- .../extension/deprecation/Deprecation.sv | 4 +- .../extension/deprecation/NameTicks.sv | 12 +- .../extension/deprecation/ProductionSemi.sv | 4 +- .../compiler/extension/deriving/Derive.sv | 154 +++--- .../compiler/extension/do_notation/Syntax.sv | 51 +- .../extension/doc/core/CommentItem.sv | 2 +- .../compiler/extension/doc/core/DataDcl.sv | 10 +- .../compiler/extension/doc/core/DocConfig.sv | 77 +-- .../extension/doc/core/DocumentedAGDcl.sv | 6 +- .../extension/doc/core/TypeClassDcls.sv | 4 +- .../extension/doc/core/doclang/DclComment.sv | 25 +- .../extension/easyterminal/TerminalDcl.sv | 20 +- .../implicit_monads/AttributeDefs.sv | 24 +- .../extension/implicit_monads/Case.sv | 42 +- .../extension/implicit_monads/CopperExpr.sv | 20 +- .../extension/implicit_monads/DclInfo.sv | 40 +- .../extension/implicit_monads/Expr.sv | 456 +++++++++--------- .../extension/implicit_monads/Lambda.sv | 6 +- .../compiler/extension/implicit_monads/Let.sv | 22 +- .../implicit_monads/PrimitiveMatch.sv | 97 ++-- .../implicit_monads/ProductionBody.sv | 58 +-- .../extension/implicit_monads/Util.sv | 33 +- .../extension/patternmatching/Case.sv | 83 ++-- .../extension/patternmatching/PatternTypes.sv | 30 +- .../silver/compiler/extension/regex/Regex.sv | 4 +- .../compiler/extension/rewriting/Expr.sv | 65 ++- .../compiler/extension/rewriting/Pattern.sv | 13 +- .../compiler/extension/rewriting/Rewriting.sv | 26 +- .../extension/silverconstruction/Syntax.sv | 42 +- .../silverconstruction/Translation.sv | 4 +- .../extension/strategyattr/ConcreteSyntax.sv | 74 +-- .../extension/strategyattr/DclInfo.sv | 12 +- .../extension/strategyattr/Strategy.sv | 54 +-- .../extension/strategyattr/StrategyExpr.sv | 143 +++--- .../strategyattr/construction/Construction.sv | 8 +- .../strategyattr/convenience/Convenience.sv | 10 +- .../extension/templating/StringTemplating.sv | 31 +- .../extension/templating/syntax/Templating.sv | 22 +- .../extension/testing/EqualityTest.sv | 60 +-- .../compiler/extension/testing/Helper.sv | 4 +- .../extension/testing/MainTestSuite.sv | 68 ++- .../compiler/extension/testing/WrongCode.sv | 12 +- .../compiler/extension/treegen/Arbitrary.sv | 32 +- .../compiler/extension/treegen/TerminalGen.sv | 6 +- .../compiler/extension/treegen/TestFor.sv | 42 +- .../extension/tuple/PatternMatching.sv | 2 +- .../silver/compiler/extension/tuple/Tuple.sv | 8 +- .../silver/compiler/extension/tuple/Type.sv | 2 +- .../compiler/langserver/ReferenceLocations.sv | 14 +- .../compiler/metatranslation/Translation.sv | 52 +- .../modification/collection/Collection.sv | 64 +-- .../modification/collection/DclInfo.sv | 58 +-- .../modification/copper/ActionCode.sv | 13 +- .../compiler/modification/copper/DclInfo.sv | 54 +-- .../copper/DisambiguationGroup.sv | 3 +- .../compiler/modification/copper/Expr.sv | 18 +- .../modification/copper/LexerClass.sv | 14 +- .../modification/copper/ParserAttributes.sv | 4 +- .../compiler/modification/copper/ParserDcl.sv | 10 +- .../compiler/modification/copper/Prefix.sv | 20 +- .../modification/copper/ProductionStmt.sv | 46 +- .../compiler/modification/copper/TermList.sv | 14 +- .../modification/copper/TerminalDcl.sv | 40 +- .../modification/copper_mda/Analysis.sv | 4 +- .../modification/defaultattr/DefaultAttr.sv | 18 +- .../compiler/modification/ffi/FunctionDcl.sv | 8 +- .../compiler/modification/ffi/TypeDcl.sv | 14 +- .../modification/ffi/java/FunctionDcl.sv | 2 +- .../modification/lambda_fn/DclInfo.sv | 8 +- .../compiler/modification/lambda_fn/Lambda.sv | 4 +- .../compiler/modification/let_fix/DclInfo.sv | 8 +- .../compiler/modification/let_fix/Let.sv | 16 +- .../silver/compiler/modification/list/List.sv | 32 +- .../primitivepattern/PrimitiveMatch.sv | 60 +-- .../primitivepattern/VarBinders.sv | 12 +- .../translation/java/core/FunctionDcl.sv | 2 +- .../translation/java/core/ProductionDcl.sv | 2 +- grammars/silver/core/Monoid.sv | 2 +- .../reflect/concretesyntax/ConcreteSyntax.sv | 10 +- 161 files changed, 2469 insertions(+), 2803 deletions(-) diff --git a/grammars/silver/compiler/analysis/typechecking/core/AspectDcl.sv b/grammars/silver/compiler/analysis/typechecking/core/AspectDcl.sv index 8e62b515d..b63bc0c39 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/AspectDcl.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/AspectDcl.sv @@ -11,15 +11,15 @@ top::AGDcl ::= 'aspect' 'production' id::QName ns::AspectProductionSignature bod errCheck1 = check(realSig.typeScheme.typerep, namedSig.typeScheme.typerep); top.errors <- if errCheck1.typeerror - then [err(top.location, "Aspect for '" ++ id.name ++ "' does not have the right signature.\nExpected: " + then [errFromOrigin(top, "Aspect for '" ++ id.name ++ "' does not have the right signature.\nExpected: " ++ errCheck1.leftpp ++ "\nActual: " ++ errCheck1.rightpp)] else -- dcl is potentially not found, accessing it can crash. -- so check on dcls for this. case id.lookupValue.dcls of | prodDcl (_, _) :: _ -> [] - | funDcl (_) :: _ -> [err(top.location, "Production aspect for '" ++ id.name ++ "' should be a 'function' aspect instead.")] - | _ -> [err(id.location, id.name ++ " is not a production.")] + | funDcl (_) :: _ -> [errFromOrigin(top, "Production aspect for '" ++ id.name ++ "' should be a 'function' aspect instead.")] + | _ -> [errFromOrigin(id, id.name ++ " is not a production.")] end; ns.downSubst = emptySubst(); @@ -37,14 +37,14 @@ top::AGDcl ::= 'aspect' 'function' id::QName ns::AspectFunctionSignature body::P errCheck1 = check(realSig.typeScheme.typerep, namedSig.typeScheme.typerep); top.errors <- if errCheck1.typeerror - then [err(top.location, "Aspect for '" ++ id.name ++ "' does not have the right signature.\nExpected: " + then [errFromOrigin(top, "Aspect for '" ++ id.name ++ "' does not have the right signature.\nExpected: " ++ errCheck1.leftpp ++ "\nActual: " ++ errCheck1.rightpp)] else -- must be on dcls because lookup may have failed. case id.lookupValue.dcls of | funDcl (_) :: _ -> [] - | prodDcl (_, _) :: _ -> [err(top.location, "Function aspect for '" ++ id.name ++ "' should be a 'production' aspect instead.")] - | _ -> [err(id.location, id.name ++ " is not a function.")] + | prodDcl (_, _) :: _ -> [errFromOrigin(top, "Function aspect for '" ++ id.name ++ "' should be a 'production' aspect instead.")] + | _ -> [errFromOrigin(id, id.name ++ " is not a function.")] end; ns.downSubst = emptySubst(); @@ -71,7 +71,7 @@ top::AspectProductionLHS ::= id::Name t::Type errCheck1 = check(rType, t); top.errors <- if errCheck1.typeerror - then [err(top.location, "Type incorrect in aspect signature. Expected: " ++ errCheck1.leftpp ++ " Got: " ++ errCheck1.rightpp)] + then [errFromOrigin(top, "Type incorrect in aspect signature. Expected: " ++ errCheck1.leftpp ++ " Got: " ++ errCheck1.rightpp)] else []; } @@ -97,7 +97,7 @@ top::AspectRHSElem ::= id::Name t::Type errCheck1 = check(rType, t); top.errors <- if errCheck1.typeerror - then [err(top.location, "Type incorrect in aspect signature. Expected: " ++ errCheck1.leftpp ++ " Got: " ++ errCheck1.rightpp)] + then [errFromOrigin(top, "Type incorrect in aspect signature. Expected: " ++ errCheck1.leftpp ++ " Got: " ++ errCheck1.rightpp)] else []; } @@ -117,7 +117,7 @@ top::AspectFunctionLHS ::= t::TypeExpr errCheck1 = check(rType, t.typerep); top.errors <- if errCheck1.typeerror - then [err(top.location, "Type incorrect in aspect signature. Expected: " ++ errCheck1.leftpp ++ " Got: " ++ errCheck1.rightpp)] + then [errFromOrigin(top, "Type incorrect in aspect signature. Expected: " ++ errCheck1.leftpp ++ " Got: " ++ errCheck1.rightpp)] else []; } diff --git a/grammars/silver/compiler/analysis/typechecking/core/ClassDcl.sv b/grammars/silver/compiler/analysis/typechecking/core/ClassDcl.sv index 5308fa60c..e4ad97dae 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/ClassDcl.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/ClassDcl.sv @@ -8,7 +8,7 @@ top::ClassBodyItem ::= id::Name '::' cl::ConstraintList '=>' ty::TypeExpr '=' e: local errCheck1::TypeCheck = check(ty.typerep, e.typerep); top.errors <- if errCheck1.typeerror - then [err(e.location, s"Member ${id.name} has expected type ${errCheck1.leftpp}, but the expression has actual type ${errCheck1.rightpp}")] + then [errFromOrigin(e, s"Member ${id.name} has expected type ${errCheck1.leftpp}, but the expression has actual type ${errCheck1.rightpp}")] else []; e.downSubst = emptySubst(); diff --git a/grammars/silver/compiler/analysis/typechecking/core/Expr.sv b/grammars/silver/compiler/analysis/typechecking/core/Expr.sv index b121d0131..c72217f52 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/Expr.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/Expr.sv @@ -25,7 +25,7 @@ top::Expr ::= aspect production productionReference top::Expr ::= q::Decorated! QName { - contexts.contextLoc = q.location; + contexts.contextLoc = q.nameLoc; contexts.contextSource = "the use of " ++ q.name; top.errors <- contexts.contextErrors; top.contexts = typeScheme.contexts; @@ -34,7 +34,7 @@ top::Expr ::= q::Decorated! QName aspect production functionReference top::Expr ::= q::Decorated! QName { - contexts.contextLoc = q.location; + contexts.contextLoc = q.nameLoc; contexts.contextSource = "the use of " ++ q.name; top.errors <- contexts.contextErrors; top.contexts = typeScheme.contexts; @@ -43,7 +43,7 @@ top::Expr ::= q::Decorated! QName aspect production globalValueReference top::Expr ::= q::Decorated! QName { - contexts.contextLoc = q.location; + contexts.contextLoc = q.nameLoc; contexts.contextSource = "the use of " ++ q.name; top.errors <- contexts.contextErrors; top.contexts = typeScheme.contexts; @@ -52,11 +52,11 @@ top::Expr ::= q::Decorated! QName aspect production classMemberReference top::Expr ::= q::Decorated! QName { - instHead.contextLoc = q.location; + instHead.contextLoc = q.nameLoc; instHead.contextSource = "the use of " ++ q.name; top.errors <- instHead.contextErrors; - contexts.contextLoc = q.location; + contexts.contextLoc = q.nameLoc; contexts.contextSource = "the use of " ++ q.name; top.errors <- contexts.contextErrors; @@ -95,14 +95,14 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur -- But let's leave it since it's the right thing to do. top.errors <- if errCheck1.typeerror && q.found - then [err(top.location, "Access of " ++ q.name ++ " from a decorated type.")] + then [errFromOrigin(top, "Access of " ++ q.name ++ " from a decorated type.")] else []; thread downSubst, upSubst on top, errCheck1, forward; } aspect production accessBouncer -top::Expr ::= target::(Expr ::= Decorated! Expr Decorated! QNameAttrOccur Location) e::Expr q::Decorated! QNameAttrOccur +top::Expr ::= target::(Expr ::= Decorated! Expr Decorated! QNameAttrOccur) e::Expr q::Decorated! QNameAttrOccur { propagate upSubst, downSubst, finalSubst; } @@ -117,7 +117,7 @@ top::Expr ::= e::Expr '.' 'forward' top.errors <- if errCheck1.typeerror - then [err(top.location, "Attribute forward being accessed from an undecorated type.")] + then [errFromOrigin(top, "Attribute forward being accessed from an undecorated type.")] else []; } @@ -133,7 +133,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur -- But let's leave it since it's the right thing to do. top.errors <- if errCheck1.typeerror - then [err(top.location, "Attribute " ++ q.name ++ " being accessed from an undecorated type.")] + then [errFromOrigin(top, "Attribute " ++ q.name ++ " being accessed from an undecorated type.")] else []; thread downSubst, upSubst on top, errCheck1, forward; @@ -151,7 +151,7 @@ top::Expr ::= 'attachNote' note::Expr 'on' e::Expr 'end' errCheck1 = check(note.typerep, nonterminalType("silver:core:OriginNote", [], true, false)); top.errors <- if errCheck1.typeerror - then [err(top.location, "First argument to attachNote must be OriginNote, was " ++ errCheck1.leftpp)] + then [errFromOrigin(top, "First argument to attachNote must be OriginNote, was " ++ errCheck1.leftpp)] else []; } @@ -167,11 +167,11 @@ top::Expr ::= e1::Expr '&&' e2::Expr errCheck2 = check(e2.typerep, boolType()); top.errors <- if errCheck1.typeerror - then [err(e1.location, "First operand to && must be type bool. Got instead type " ++ errCheck1.leftpp)] + then [errFromOrigin(e1, "First operand to && must be type bool. Got instead type " ++ errCheck1.leftpp)] else []; top.errors <- if errCheck2.typeerror - then [err(e2.location, "First operand to && must be type bool. Got instead type " ++ errCheck2.leftpp)] + then [errFromOrigin(e2, "First operand to && must be type bool. Got instead type " ++ errCheck2.leftpp)] else []; } @@ -187,11 +187,11 @@ top::Expr ::= e1::Expr '||' e2::Expr errCheck2 = check(e2.typerep, boolType()); top.errors <- if errCheck1.typeerror - then [err(e1.location, "First operand to || must be type bool. Got instead type " ++ errCheck1.leftpp)] + then [errFromOrigin(e1, "First operand to || must be type bool. Got instead type " ++ errCheck1.leftpp)] else []; top.errors <- if errCheck2.typeerror - then [err(e2.location, "First operand to || must be type bool. Got instead type " ++ errCheck2.leftpp)] + then [errFromOrigin(e2, "First operand to || must be type bool. Got instead type " ++ errCheck2.leftpp)] else []; } @@ -205,7 +205,7 @@ top::Expr ::= '!' e1::Expr errCheck1 = check(e1.typerep, boolType()); top.errors <- if errCheck1.typeerror - then [err(e1.location, "Operand to ! must be type bool. Got instead type " ++ errCheck1.leftpp)] + then [errFromOrigin(e1, "Operand to ! must be type bool. Got instead type " ++ errCheck1.leftpp)] else []; } @@ -221,11 +221,11 @@ top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'else' e3::Expr errCheck2 = check(e1.typerep, boolType()); top.errors <- if errCheck1.typeerror - then [err(top.location, "Then and else branch must have the same type. Instead they are " ++ errCheck1.leftpp ++ " and " ++ errCheck1.rightpp)] + then [errFromOrigin(top, "Then and else branch must have the same type. Instead they are " ++ errCheck1.leftpp ++ " and " ++ errCheck1.rightpp)] else []; top.errors <- if errCheck2.typeerror - then [err(e1.location, "Condition must have the type Boolean. Instead it is " ++ errCheck2.leftpp)] + then [errFromOrigin(e1, "Condition must have the type Boolean. Instead it is " ++ errCheck2.leftpp)] else []; } @@ -239,13 +239,13 @@ top::Expr ::= e1::Expr '+' e2::Expr errCheck1 = check(e1.typerep, e2.typerep); top.errors <- if errCheck1.typeerror - then [err(top.location, "Operands to + must be the same type. Instead they are " ++ errCheck1.leftpp ++ " and " ++ errCheck1.rightpp)] + then [errFromOrigin(top, "Operands to + must be the same type. Instead they are " ++ errCheck1.leftpp ++ " and " ++ errCheck1.rightpp)] else []; top.errors <- if e1.finalType.instanceNum then [] - else [err(top.location, "Operands to + must be concrete types Integer or Float. Instead they are of type " ++ prettyType(e1.finalType))]; + else [errFromOrigin(top, "Operands to + must be concrete types Integer or Float. Instead they are of type " ++ prettyType(e1.finalType))]; } aspect production minus @@ -258,13 +258,13 @@ top::Expr ::= e1::Expr '-' e2::Expr errCheck1 = check(e1.typerep, e2.typerep); top.errors <- if errCheck1.typeerror - then [err(top.location, "Operands to - must be the same type. Instead they are " ++ errCheck1.leftpp ++ " and " ++ errCheck1.rightpp)] + then [errFromOrigin(top, "Operands to - must be the same type. Instead they are " ++ errCheck1.leftpp ++ " and " ++ errCheck1.rightpp)] else []; top.errors <- if e1.finalType.instanceNum then [] - else [err(top.location, "Operands to - must be concrete types Integer or Float. Instead they are of type " ++ prettyType(e1.finalType))]; + else [errFromOrigin(top, "Operands to - must be concrete types Integer or Float. Instead they are of type " ++ prettyType(e1.finalType))]; } aspect production multiply top::Expr ::= e1::Expr '*' e2::Expr @@ -276,13 +276,13 @@ top::Expr ::= e1::Expr '*' e2::Expr errCheck1 = check(e1.typerep, e2.typerep); top.errors <- if errCheck1.typeerror - then [err(top.location, "Operands to * must be the same type. Instead they are " ++ errCheck1.leftpp ++ " and " ++ errCheck1.rightpp)] + then [errFromOrigin(top, "Operands to * must be the same type. Instead they are " ++ errCheck1.leftpp ++ " and " ++ errCheck1.rightpp)] else []; top.errors <- if e1.finalType.instanceNum then [] - else [err(top.location, "Operands to * must be concrete types Integer or Float. Instead they are of type " ++ prettyType(e1.finalType))]; + else [errFromOrigin(top, "Operands to * must be concrete types Integer or Float. Instead they are of type " ++ prettyType(e1.finalType))]; } aspect production divide top::Expr ::= e1::Expr '/' e2::Expr @@ -294,13 +294,13 @@ top::Expr ::= e1::Expr '/' e2::Expr errCheck1 = check(e1.typerep, e2.typerep); top.errors <- if errCheck1.typeerror - then [err(top.location, "Operands to / must be the same type. Instead they are " ++ errCheck1.leftpp ++ " and " ++ errCheck1.rightpp)] + then [errFromOrigin(top, "Operands to / must be the same type. Instead they are " ++ errCheck1.leftpp ++ " and " ++ errCheck1.rightpp)] else []; top.errors <- if e1.finalType.instanceNum then [] - else [err(top.location, "Operands to / must be concrete types Integer or Float. Instead they are of type " ++ prettyType(e1.finalType))]; + else [errFromOrigin(top, "Operands to / must be concrete types Integer or Float. Instead they are of type " ++ prettyType(e1.finalType))]; } aspect production modulus top::Expr ::= e1::Expr '%' e2::Expr @@ -312,13 +312,13 @@ top::Expr ::= e1::Expr '%' e2::Expr errCheck1 = check(e1.typerep, e2.typerep); top.errors <- if errCheck1.typeerror - then [err(top.location, "Operands to % must be the same type. Instead they are " ++ errCheck1.leftpp ++ " and " ++ errCheck1.rightpp)] + then [errFromOrigin(top, "Operands to % must be the same type. Instead they are " ++ errCheck1.leftpp ++ " and " ++ errCheck1.rightpp)] else []; top.errors <- if e1.finalType.instanceNum then [] - else [err(top.location, "Operands to % must be concrete types Integer or Float. Instead they are of type " ++ prettyType(e1.finalType))]; + else [errFromOrigin(top, "Operands to % must be concrete types Integer or Float. Instead they are of type " ++ prettyType(e1.finalType))]; } aspect production neg top::Expr ::= '-' e1::Expr @@ -327,7 +327,7 @@ top::Expr ::= '-' e1::Expr top.errors <- if e1.finalType.instanceNum then [] - else [err(top.location, "Operand to unary - must be concrete types Integer or Float. Instead it is of type " ++ prettyType(e1.finalType))]; + else [errFromOrigin(top, "Operand to unary - must be concrete types Integer or Float. Instead it is of type " ++ prettyType(e1.finalType))]; } aspect production terminalConstructor @@ -342,18 +342,18 @@ top::Expr ::= 'terminal' '(' t::TypeExpr ',' es::Expr ',' el::Expr ')' errCheck2 = check(el.typerep, nonterminalType("silver:core:Location", [], true, false)); top.errors <- if errCheck1.typeerror - then [err(es.location, "Second operand to 'terminal(type,lexeme,location)' must be a String, instead it is " ++ errCheck1.leftpp)] + then [errFromOrigin(es, "Second operand to 'terminal(type,lexeme,location)' must be a String, instead it is " ++ errCheck1.leftpp)] else []; top.errors <- if errCheck2.typeerror - then [err(el.location, "Third operand to 'terminal(type,lexeme,location)' must be a Location, instead it is " ++ errCheck2.leftpp)] + then [errFromOrigin(el, "Third operand to 'terminal(type,lexeme,location)' must be a Location, instead it is " ++ errCheck2.leftpp)] else []; top.errors <- if t.typerep.isTerminal || t.typerep.isError then [] - else [err(t.location, "First operand to 'terminal(type,lexeme,location)' must be a Terminal type, instead it is " ++ prettyType(t.typerep))]; + else [errFromOrigin(t, "First operand to 'terminal(type,lexeme,location)' must be a Terminal type, instead it is " ++ prettyType(t.typerep))]; } aspect production decorateExprWith @@ -366,7 +366,7 @@ top::Expr ::= 'decorate' e::Expr 'with' '{' inh::ExprInhs '}' errCheck1 = checkDecorable(top.env, e.typerep); top.errors <- if errCheck1.typeerror - then [err(top.location, "Operand to decorate must be a decorable type. Instead it is of type " ++ errCheck1.leftpp)] + then [errFromOrigin(top, "Operand to decorate must be a decorable type. Instead it is of type " ++ errCheck1.leftpp)] else []; } @@ -380,7 +380,7 @@ top::Expr ::= '@' e::Expr errCheck1 = check(e.typerep, uniqueDecoratedType(freshType(), inhSetType([]))); top.errors <- if errCheck1.typeerror - then [err(top.location, "Operand to @ must be a unique reference with no inherited attributes. Instead it is of type " ++ errCheck1.leftpp)] + then [errFromOrigin(top, "Operand to @ must be a unique reference with no inherited attributes. Instead it is of type " ++ errCheck1.leftpp)] else []; } @@ -394,7 +394,7 @@ top::ExprInh ::= lhs::ExprLHSExpr '=' e1::Expr ';' errCheck1 = check(lhs.typerep, e1.typerep); top.errors <- if errCheck1.typeerror - then [err(top.location, lhs.name ++ " has expected type " ++ errCheck1.leftpp + then [errFromOrigin(top, lhs.name ++ " has expected type " ++ errCheck1.leftpp ++ ", but the expression has type " ++ errCheck1.rightpp)] else []; } @@ -409,7 +409,7 @@ top::AppExpr ::= e::Expr errCheck1 = check(e.typerep, top.appExprTyperep); top.errors <- if !errCheck1.typeerror then [] - else [err(top.location, "Argument " ++ toString(top.appExprIndex+1) ++ " of function '" ++ + else [errFromOrigin(top, "Argument " ++ toString(top.appExprIndex+1) ++ " of function '" ++ top.appExprApplied ++ "' expected " ++ errCheck1.rightpp ++ " but argument is of type " ++ errCheck1.leftpp)]; } diff --git a/grammars/silver/compiler/analysis/typechecking/core/GlobalDcl.sv b/grammars/silver/compiler/analysis/typechecking/core/GlobalDcl.sv index 86d5d8d45..aac857946 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/GlobalDcl.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/GlobalDcl.sv @@ -15,7 +15,7 @@ top::AGDcl ::= 'global' id::Name '::' cl::ConstraintList '=>' t::TypeExpr '=' e: errCheck1 = check(e.typerep, t.typerep); top.errors <- if errCheck1.typeerror - then [err(top.location, "Declaration of global " ++ id.name ++ " with type " ++ errCheck1.rightpp ++ " has initialization expression with type " ++ errCheck1.leftpp)] + then [errFromOrigin(top, "Declaration of global " ++ id.name ++ " with type " ++ errCheck1.rightpp ++ " has initialization expression with type " ++ errCheck1.leftpp)] else []; } diff --git a/grammars/silver/compiler/analysis/typechecking/core/InstanceDcl.sv b/grammars/silver/compiler/analysis/typechecking/core/InstanceDcl.sv index 81722e228..b5bbaeff8 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/InstanceDcl.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/InstanceDcl.sv @@ -5,9 +5,9 @@ top::AGDcl ::= 'instance' cl::ConstraintList '=>' id::QNameType ty::TypeExpr '{' { top.errors <- if ty.typerep.kindrep == id.lookupType.typeScheme.typerep.kindrep then [] - else [err(ty.location, s"${ty.unparse} has kind ${prettyKind(ty.typerep.kindrep)}, but the class ${id.name} expected kind ${prettyKind(id.lookupType.typeScheme.typerep.kindrep)}")]; + else [errFromOrigin(ty, s"${ty.unparse} has kind ${prettyKind(ty.typerep.kindrep)}, but the class ${id.name} expected kind ${prettyKind(id.lookupType.typeScheme.typerep.kindrep)}")]; - superContexts.contextLoc = id.location; + superContexts.contextLoc = id.nameLoc; superContexts.contextSource = "instance superclasses"; top.errors <- superContexts.contextErrors; } @@ -18,7 +18,7 @@ top::InstanceBodyItem ::= id::QName '=' e::Expr ';' local errCheck1::TypeCheck = check(typeScheme.typerep, e.typerep); top.errors <- if errCheck1.typeerror - then [err(e.location, s"Member ${id.name} has expected type ${errCheck1.leftpp}, but the expression has actual type ${errCheck1.rightpp}")] + then [errFromOrigin(e, s"Member ${id.name} has expected type ${errCheck1.leftpp}, but the expression has actual type ${errCheck1.rightpp}")] else []; e.downSubst = instSubst; diff --git a/grammars/silver/compiler/analysis/typechecking/core/OccursDcl.sv b/grammars/silver/compiler/analysis/typechecking/core/OccursDcl.sv index f2d35f790..4301077eb 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/OccursDcl.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/OccursDcl.sv @@ -9,6 +9,6 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: top.errors <- if at.lookupAttribute.found && at.lookupAttribute.dcl.isTranslation && checkNT.typeerror - then [err(top.location, s"Occurrence of translation attribute ${at.lookupAttribute.fullName} must have a nonterminal type. Instead it is of type " ++ checkNT.leftpp)] + then [errFromOrigin(top, s"Occurrence of translation attribute ${at.lookupAttribute.fullName} must have a nonterminal type. Instead it is of type " ++ checkNT.leftpp)] else []; } diff --git a/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv b/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv index 22fbff098..929d32f63 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv @@ -56,7 +56,7 @@ top::ProductionStmt ::= 'forwards' 'to' e::Expr ';' errCheck1 = check(e.typerep, top.frame.signature.outputElement.typerep); top.errors <- if errCheck1.typeerror - then [err(e.location, "Forward's expected type is " ++ errCheck1.rightpp ++ ", but the actual type supplied is " ++ errCheck1.leftpp)] + then [errFromOrigin(e, "Forward's expected type is " ++ errCheck1.rightpp ++ ", but the actual type supplied is " ++ errCheck1.leftpp)] else []; } @@ -70,7 +70,7 @@ top::ForwardInh ::= lhs::ForwardLHSExpr '=' e::Expr ';' errCheck1 = check(lhs.typerep, e.typerep); top.errors <- if errCheck1.typeerror - then [err(e.location, lhs.name ++ " has expected type " ++ errCheck1.leftpp + then [errFromOrigin(e, lhs.name ++ " has expected type " ++ errCheck1.leftpp ++ ", but the expression has type " ++ errCheck1.rightpp)] else []; } @@ -84,7 +84,7 @@ top::ProductionStmt ::= 'undecorates' 'to' e::Expr ';' errCheck1 = check(e.typerep, top.frame.signature.outputElement.typerep); top.errors <- if errCheck1.typeerror - then [err(e.location, "Undecorates's expected type is " ++ errCheck1.rightpp ++ ", but the actual type supplied is " ++ errCheck1.leftpp)] + then [errFromOrigin(e, "Undecorates's expected type is " ++ errCheck1.rightpp ++ ", but the actual type supplied is " ++ errCheck1.leftpp)] else []; } @@ -98,7 +98,7 @@ top::ProductionStmt ::= 'attachNote' e::Expr ';' errCheck1 = check(e.typerep, nonterminalType("silver:core:OriginNote", [], true, false)); top.errors <- if errCheck1.typeerror - then [err(top.location, "Origin note must have type silver:core:OriginNote, but the expression has actual type " ++ errCheck1.leftpp)] + then [errFromOrigin(top, "Origin note must have type silver:core:OriginNote, but the expression has actual type " ++ errCheck1.leftpp)] else []; } @@ -112,7 +112,7 @@ top::ProductionStmt ::= 'return' e::Expr ';' errCheck1 = check(e.typerep, top.frame.signature.outputElement.typerep); top.errors <- if errCheck1.typeerror - then [err(top.location, "Expected return type is " ++ errCheck1.rightpp ++ ", but the expression has actual type " ++ errCheck1.leftpp)] + then [errFromOrigin(top, "Expected return type is " ++ errCheck1.rightpp ++ ", but the expression has actual type " ++ errCheck1.leftpp)] else []; } @@ -126,7 +126,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur errCheck1 = check(attr.typerep, e.typerep); top.errors <- if errCheck1.typeerror - then [err(top.location, "Attribute " ++ attr.name ++ " has type " ++ errCheck1.leftpp ++ " but the expression being assigned to it has type " ++ errCheck1.rightpp)] + then [errFromOrigin(top, "Attribute " ++ attr.name ++ " has type " ++ errCheck1.leftpp ++ " but the expression being assigned to it has type " ++ errCheck1.rightpp)] else []; } @@ -140,7 +140,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur errCheck1 = check(attr.typerep, e.typerep); top.errors <- if errCheck1.typeerror - then [err(top.location, "Attribute " ++ attr.name ++ " has type " ++ errCheck1.leftpp ++ " but the expression being assigned to it has type " ++ errCheck1.rightpp)] + then [errFromOrigin(top, "Attribute " ++ attr.name ++ " has type " ++ errCheck1.leftpp ++ " but the expression being assigned to it has type " ++ errCheck1.rightpp)] else []; } @@ -154,14 +154,14 @@ aspect production childDefLHS top::DefLHS ::= q::Decorated! QName { top.errors <- if isDecorable(top.typerep, top.env) then [] - else [err(top.location, s"Inherited attributes can only be defined on (undecorated) nonterminal and unique decorated types, not ${prettyType(top.typerep)}.")]; + else [errFromOrigin(top, s"Inherited attributes can only be defined on (undecorated) nonterminal and unique decorated types, not ${prettyType(top.typerep)}.")]; } aspect production localDefLHS top::DefLHS ::= q::Decorated! QName { top.errors <- if isDecorable(top.typerep, top.env) then [] - else [err(top.location, s"Inherited attributes can only be defined on (undecorated) nonterminal and unique decorated types, not ${prettyType(top.typerep)}.")]; + else [errFromOrigin(top, s"Inherited attributes can only be defined on (undecorated) nonterminal and unique decorated types, not ${prettyType(top.typerep)}.")]; } aspect production localAttributeDcl @@ -186,6 +186,6 @@ top::ProductionStmt ::= val::Decorated! QName e::Expr errCheck1 = check(e.typerep, val.lookupValue.typeScheme.typerep); top.errors <- if errCheck1.typeerror - then [err(top.location, "Local " ++ val.name ++ " has type " ++ errCheck1.rightpp ++ " but the expression being assigned to it has type " ++ errCheck1.leftpp)] + then [errFromOrigin(top, "Local " ++ val.name ++ " has type " ++ errCheck1.rightpp ++ " but the expression being assigned to it has type " ++ errCheck1.leftpp)] else []; } diff --git a/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv b/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv index 5bb2e657e..bc325a8e1 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv @@ -17,7 +17,7 @@ top::ProductionLHS ::= id::Name '::' t::TypeExpr top.errors <- if checkNT.typeerror - then [err(top.location, "Production LHS type must be a nonterminal. Instead it is of type " ++ checkNT.leftpp)] + then [errFromOrigin(top, "Production LHS type must be a nonterminal. Instead it is of type " ++ checkNT.leftpp)] else []; } diff --git a/grammars/silver/compiler/analysis/uniqueness/Expr.sv b/grammars/silver/compiler/analysis/uniqueness/Expr.sv index f11274bc7..c3b932069 100644 --- a/grammars/silver/compiler/analysis/uniqueness/Expr.sv +++ b/grammars/silver/compiler/analysis/uniqueness/Expr.sv @@ -29,7 +29,7 @@ top::Expr ::= q::Decorated! QName [(top.frame.fullName ++ ":" ++ q.lookupValue.fullName, uniqueRefSite( sourceGrammar=top.grammarName, - sourceLocation=q.location, + sourceLocation=q.nameLoc, refSet=inhs, refFlowDeps=top.flowDeps ))] @@ -42,10 +42,10 @@ top::Expr ::= q::Decorated! QName | uniqueDecoratedType(_, _) when q.lookupValue.found -> -- Check that we are exported by the decoration site. if !isExportedBy(top.grammarName, [q.lookupValue.dcl.sourceGrammar], top.compiledGrammars) - then [err(top.location, s"Orphaned unique reference to ${q.lookupValue.fullName} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] + then [errFromOrigin(top, s"Orphaned unique reference to ${q.lookupValue.fullName} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] -- Check that there is at most one unique reference taken to this decoration site. else if length(lookupUniqueRefs(top.frame.fullName, q.lookupValue.fullName, top.flowEnv)) > 1 - then [err(top.location, s"Multiple unique references taken to ${q.name} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] + then [errFromOrigin(top, s"Multiple unique references taken to ${q.name} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] else [] | _ -> [] end; @@ -60,7 +60,7 @@ top::Expr ::= q::Decorated! QName [(q.lookupValue.fullName, uniqueRefSite( sourceGrammar=top.grammarName, - sourceLocation=q.location, + sourceLocation=q.nameLoc, refSet=inhs, refFlowDeps=top.flowDeps ))] @@ -73,10 +73,10 @@ top::Expr ::= q::Decorated! QName | uniqueDecoratedType(_, _) when q.lookupValue.found -> -- Check that we are exported by the decoration site. if !isExportedBy(top.grammarName, [q.lookupValue.dcl.sourceGrammar], top.compiledGrammars) - then [err(top.location, s"Orphaned unique reference to ${q.lookupValue.fullName} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] + then [errFromOrigin(top, s"Orphaned unique reference to ${q.lookupValue.fullName} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] -- Check that there is at most one unique reference taken to this decoration site. else if length(lookupLocalUniqueRefs(q.lookupValue.fullName, top.flowEnv)) > 1 - then [err(top.location, s"Multiple unique references taken to ${q.name} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] + then [errFromOrigin(top, s"Multiple unique references taken to ${q.name} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] else [] | _ -> [] end; @@ -87,7 +87,7 @@ top::Expr ::= q::Decorated! QName top.errors <- case top.finalType of | uniqueDecoratedType(_, _) -> - [err(top.location, s"Cannot take a unique reference of type ${prettyType(top.finalType)} to ${q.name}.")] + [errFromOrigin(top, s"Cannot take a unique reference of type ${prettyType(top.finalType)} to ${q.name}.")] | _ -> [] end; } @@ -97,7 +97,7 @@ top::Expr ::= q::Decorated! QName top.errors <- case top.finalType of | uniqueDecoratedType(_, _) -> - [err(top.location, s"Cannot take a unique reference of type ${prettyType(top.finalType)} to the forward tree.")] + [errFromOrigin(top, s"Cannot take a unique reference of type ${prettyType(top.finalType)} to the forward tree.")] | _ -> [] end; } @@ -107,7 +107,7 @@ top::Expr ::= q::Decorated! QName top.errors <- flatMap(\ tv::TyVar -> let substTy::Type = performSubstitution(varType(tv), top.finalSubst) in if substTy.isUniqueDecorated - then [err(top.location, s"Cannot specialize type variable ${prettyTypeWith(varType(tv), top.typerep.freeVariables)} of ${q.name}::${prettyType(top.typerep)} to a unique reference type ${prettyType(substTy)}")] + then [errFromOrigin(top, s"Cannot specialize type variable ${prettyTypeWith(varType(tv), top.typerep.freeVariables)} of ${q.name}::${prettyType(top.typerep)} to a unique reference type ${prettyType(substTy)}")] else [] end, top.typerep.freeVariables); @@ -118,7 +118,7 @@ top::Expr ::= q::Decorated! QName top.errors <- flatMap(\ tv::TyVar -> let substTy::Type = performSubstitution(varType(tv), top.finalSubst) in if substTy.isUniqueDecorated - then [err(top.location, s"Cannot specialize type variable ${prettyTypeWith(varType(tv), top.typerep.freeVariables)} of ${q.name}::${prettyType(top.typerep)} to a unique reference type ${prettyType(substTy)}")] + then [errFromOrigin(top, s"Cannot specialize type variable ${prettyTypeWith(varType(tv), top.typerep.freeVariables)} of ${q.name}::${prettyType(top.typerep)} to a unique reference type ${prettyType(substTy)}")] else [] end, top.typerep.freeVariables); @@ -129,7 +129,7 @@ top::Expr ::= q::Decorated! QName top.errors <- flatMap(\ tv::TyVar -> let substTy::Type = performSubstitution(varType(tv), top.finalSubst) in if substTy.isUniqueDecorated - then [err(top.location, s"Cannot specialize type variable ${prettyTypeWith(varType(tv), top.typerep.freeVariables)} of ${q.name}::${prettyType(top.typerep)} to a unique reference type ${prettyType(substTy)}")] + then [errFromOrigin(top, s"Cannot specialize type variable ${prettyTypeWith(varType(tv), top.typerep.freeVariables)} of ${q.name}::${prettyType(top.typerep)} to a unique reference type ${prettyType(substTy)}")] else [] end, top.typerep.freeVariables); @@ -140,7 +140,7 @@ top::Expr ::= q::Decorated! QName top.errors <- flatMap(\ tv::TyVar -> let substTy::Type = performSubstitution(varType(tv), top.finalSubst) in if substTy.isUniqueDecorated - then [err(top.location, s"Cannot specialize type variable ${prettyTypeWith(varType(tv), top.typerep.freeVariables)} of ${q.name}::${prettyType(top.typerep)} to a unique reference type ${prettyType(substTy)}")] + then [errFromOrigin(top, s"Cannot specialize type variable ${prettyTypeWith(varType(tv), top.typerep.freeVariables)} of ${q.name}::${prettyType(top.typerep)} to a unique reference type ${prettyType(substTy)}")] else [] end, top.typerep.freeVariables); @@ -230,7 +230,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur end, uniqueRefSite( sourceGrammar=top.grammarName, - sourceLocation=q.location, + sourceLocation=getParsedOriginLocationOrFallback(top), refSet=inhs, refFlowDeps=top.flowDeps ))] @@ -244,32 +244,32 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur | just(rhsVertexType(sigName)) -> -- Check that we are exported by the occurs-on or the production. if !isExportedBy(top.grammarName, [q.dcl.sourceGrammar, top.frame.sourceGrammar], top.compiledGrammars) - then [err(top.location, s"Orphaned unique reference to ${top.unparse} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] + then [errFromOrigin(top, s"Orphaned unique reference to ${top.unparse} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] -- Check that there is at most one unique reference taken to this decoration site. else (if length(lookupTransUniqueRefs(top.frame.fullName, sigName, q.attrDcl.fullName, top.flowEnv)) > 1 - then [err(top.location, s"Multiple unique references taken to ${top.unparse} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] + then [errFromOrigin(top, s"Multiple unique references taken to ${top.unparse} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] -- Check that there isn't also a unique reference taken to e else []) ++ if !null(lookupUniqueRefs(top.frame.fullName, sigName, top.flowEnv)) - then [err(top.location, s"Cannot take a unique reference to ${top.unparse} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}) since there is also a unique reference taken to ${e.unparse}.")] + then [errFromOrigin(top, s"Cannot take a unique reference to ${top.unparse} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}) since there is also a unique reference taken to ${e.unparse}.")] else [] | just(localVertexType(fName)) -> -- Check that we are exported by the occurs-on or the local. if !isExportedBy(top.grammarName, [q.dcl.sourceGrammar, head(getValueDcl(fName, top.env)).sourceGrammar], top.compiledGrammars) - then [err(top.location, s"Orphaned unique reference to ${top.unparse} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] + then [errFromOrigin(top, s"Orphaned unique reference to ${top.unparse} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] -- Check that there is at most one unique reference taken to this decoration site. else (if length(lookupLocalTransUniqueRefs(fName, q.attrDcl.fullName, top.flowEnv)) > 1 - then [err(top.location, s"Multiple unique references taken to ${top.unparse} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] + then [errFromOrigin(top, s"Multiple unique references taken to ${top.unparse} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] -- Check that there isn't also a unique reference taken to e else []) ++ case lookupLocalUniqueRefs(fName, top.flowEnv) of | u :: _ -> - [err(top.location, s"Cannot take a unique reference to ${top.unparse} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}) since there is also a unique reference taken to ${e.unparse} at ${u.sourceGrammar}:${u.sourceLocation.unparse}.")] + [errFromOrigin(top, s"Cannot take a unique reference to ${top.unparse} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}) since there is also a unique reference taken to ${e.unparse} at ${u.sourceGrammar}:${u.sourceLocation.unparse}.")] | [] -> [] end - | _ -> [err(top.location, s"Cannot take a unique reference (of type ${prettyType(top.finalType)}) to ${top.unparse}")] + | _ -> [errFromOrigin(top, s"Cannot take a unique reference (of type ${prettyType(top.finalType)}) to ${top.unparse}")] end | _ -> [] end; @@ -317,7 +317,7 @@ top::Expr ::= q::Decorated! QName refSet=top.finalType.inhSetMembers, refFlowDeps=top.flowDeps, sourceGrammar=top.grammarName, - sourceLocation=top.location + sourceLocation=q.nameLoc ))] else []; top.accessUniqueRefs = []; @@ -347,7 +347,7 @@ top::Expr ::= q::Decorated! QName fi::Maybe fd::[FlowVertex] rs:: case top.finalType, q.lookupValue.typeScheme.monoType of | uniqueDecoratedType(_, _), uniqueDecoratedType(_, _) -> [] | uniqueDecoratedType(_, _), _ -> - [err(top.location, s"${q.name} was not bound as a unique reference, but here it is used with type ${prettyType(top.finalType)}.")] + [errFromOrigin(top, s"${q.name} was not bound as a unique reference, but here it is used with type ${prettyType(top.finalType)}.")] | _, _ -> [] end; diff --git a/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv b/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv index 59b8d5548..e65862d42 100644 --- a/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv +++ b/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv @@ -8,7 +8,7 @@ top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::Pr { top.errors <- if any(map((.isUniqueDecorated), namedSig.inputTypes)) && null(body.undecorateExpr) - then [err(top.location, s"Production '${id.name}' has a unique reference in its signature but no 'undecorates to'.")] + then [errFromOrigin(top, s"Production '${id.name}' has a unique reference in its signature but no 'undecorates to'.")] else []; } diff --git a/grammars/silver/compiler/analysis/warnings/flow/FlowTypeCopyEquation.sv b/grammars/silver/compiler/analysis/warnings/flow/FlowTypeCopyEquation.sv index c951fed61..e63c55b60 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/FlowTypeCopyEquation.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/FlowTypeCopyEquation.sv @@ -31,13 +31,13 @@ top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::Pr && top.config.warnMissingInh -- Must be a forwarding production && !null(body.forwardExpr) - then flatMap(raiseImplicitFwdEqFlowTypes(top.config, top.location, lhsNt, fName, _, top.flowEnv, myGraph, myFlow), hostSyns) + then flatMap(raiseImplicitFwdEqFlowTypes(top.config, lhsNt, fName, _, top.flowEnv, myGraph, myFlow), hostSyns) else []; } function raiseImplicitFwdEqFlowTypes -[Message] ::= config::Decorated CmdArgs l::Location lhsNt::String prod::String attr::String e::FlowEnv myGraph::ProductionGraph myFlow::EnvTree +[Message] ::= config::Decorated CmdArgs lhsNt::String prod::String attr::String e::FlowEnv myGraph::ProductionGraph myFlow::EnvTree { -- The actual dependencies for `forward.attr` local fwdFlowDeps :: set:Set = onlyLhsInh(expandGraph([forwardEqVertex(), forwardSynVertex(attr)], myGraph)); @@ -50,7 +50,7 @@ function raiseImplicitFwdEqFlowTypes | eq :: _ -> [] | [] -> if null(diff) then [] - else [mwdaWrn(config, l, s"In production ${prod}, the implicit copy equation for ${attr} (due to forwarding) would exceed the attribute's flow type with dependencies on ${implode(", ", diff)}")] + else [mwdaWrnAmbientOrigin(config, s"In production ${prod}, the implicit copy equation for ${attr} (due to forwarding) would exceed the attribute's flow type with dependencies on ${implode(", ", diff)}")] end; } diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index a1695265c..b0d12f7d5 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -97,7 +97,7 @@ Boolean ::= sigName::String attrName::String e::Env - @returns Errors for missing equations -} function checkEqDeps -[Message] ::= v::FlowVertex config::Decorated CmdArgs l::Location prodName::String flowEnv::FlowEnv realEnv::Env anonResolve::[Pair] +[Message] ::= v::FlowVertex config::Decorated CmdArgs prodName::String flowEnv::FlowEnv realEnv::Env anonResolve::[Pair] { -- We're concerned with missing inherited equations on RHS, LOCAL, and ANON. (Implicitly, FORWARD.) @@ -126,7 +126,7 @@ function checkEqDeps | nothing() -> false end then [] - else [mwdaWrn(config, l, "Equation has transitive dependency on child " ++ sigName ++ "'s inherited attribute for " ++ attrName ++ " but this equation appears to be missing.")] + else [mwdaWrnAmbientOrigin(config, "Equation has transitive dependency on child " ++ sigName ++ "'s inherited attribute for " ++ attrName ++ " but this equation appears to be missing.")] | rhsSynVertex(sigName, attrName) -> [] -- A dependency on a LOCAL. Technically, local equations may not exist! -- But let's just assume they do, since `local name :: type = expr;` is the prefered syntax. @@ -144,7 +144,7 @@ function checkEqDeps | nothing() -> isForwardProdAttr(fName, realEnv) -- Inh on trans are not copied with forwarding end then [] - else [mwdaWrn(config, l, "Equation has transitive dependency on local " ++ fName ++ "'s inherited attribute for " ++ attrName ++ " but this equation appears to be missing.")] + else [mwdaWrnAmbientOrigin(config, "Equation has transitive dependency on local " ++ fName ++ "'s inherited attribute for " ++ attrName ++ " but this equation appears to be missing.")] | localSynVertex(fName, attrName) -> [] -- A dependency on a ANON. This do always exist (`decorate expr with..` always has expr.) | anonEqVertex(fName) -> [] @@ -168,14 +168,14 @@ function checkEqDeps | subtermInhVertex(parent, termProdName, sigName, attrName) -> if !remoteProdMissingInhEq(termProdName, sigName, attrName, flowEnv) then [] - else [mwdaWrn(config, l, s"Equation has transitive dependencies on a missing remote equation.\n\tRemote production: ${termProdName}\n\tChild: ${sigName}\n\tMissing inherited equations for: ${attrName}")] + else [mwdaWrnAmbientOrigin(config, s"Equation has transitive dependencies on a missing remote equation.\n\tRemote production: ${termProdName}\n\tChild: ${sigName}\n\tMissing inherited equations for: ${attrName}")] | subtermSynVertex(parent, termProdName, sigName, attrName) -> [] end; } function checkAllEqDeps -[Message] ::= v::[FlowVertex] config::Decorated CmdArgs l::Location prodName::String flowEnv::FlowEnv realEnv::Env anonResolve::[Pair] +[Message] ::= v::[FlowVertex] config::Decorated CmdArgs prodName::String flowEnv::FlowEnv realEnv::Env anonResolve::[Pair] { - return flatMap(checkEqDeps(_, config, l, prodName, flowEnv, realEnv, anonResolve), v); + return flatMap(checkEqDeps(_, config, prodName, flowEnv, realEnv, anonResolve), v); } {-- @@ -213,7 +213,7 @@ top::AGDcl ::= 'global' id::Name '::' cl::ConstraintList '=>' t::TypeExpr '=' e: top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.location, fName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) + then checkAllEqDeps(transitiveDeps, top.config, fName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) else []; } @@ -224,7 +224,7 @@ top::ClassBodyItem ::= id::Name '::' cl::ConstraintList '=>' ty::TypeExpr '=' e: top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.location, fName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) + then checkAllEqDeps(transitiveDeps, top.config, fName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) else []; } @@ -235,7 +235,7 @@ top::InstanceBodyItem ::= id::QName '=' e::Expr ';' top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.location, id.lookupValue.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) + then checkAllEqDeps(transitiveDeps, top.config, id.lookupValue.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) else []; } @@ -253,9 +253,9 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur top.errors <- if dl.found && attr.found && top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.location, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ + then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ if null(lhsInhExceedsFlowType) then [] - else [mwdaWrn(top.config, top.location, "Synthesized equation " ++ attr.name ++ " exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsFlowType))] + else [mwdaWrnFromOrigin(top, "Synthesized equation " ++ attr.name ++ " exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsFlowType))] else []; } @@ -293,16 +293,16 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.location, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) + then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) else []; top.errors <- if top.config.warnMissingInh && dl.name == "forward" && !null(lhsInhExceedsForwardFlowType) - then [mwdaWrn(top.config, top.location, "Forward inherited equation exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsForwardFlowType))] + then [mwdaWrnFromOrigin(top, "Forward inherited equation exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsForwardFlowType))] else []; top.errors <- case dl.lhsUniqueRefs of | u :: _ when top.config.warnMissingInh && !null(lhsInhExceedsRefDecSiteDeps) -> - [mwdaWrn(top.config, top.location, + [mwdaWrnFromOrigin(top, s"Inherited override equation may exceed a flow type with hidden transitive dependencies on ${implode(", ", lhsInhExceedsRefDecSiteDeps)}; " ++ s"${attr.attrDcl.fullName} on the reference taken at ${u.sourceGrammar}:${u.sourceLocation.unparse} may be expected to depend only on ${implode(", ", set:toList(refDecSiteInhDepsLhsInh.fromJust))}")] | _ -> [] @@ -413,9 +413,9 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur top.errors <- if dl.found && attr.found && top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.location, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ + then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ if null(lhsInhExceedsFlowType) then [] - else [mwdaWrn(top.config, top.location, "Synthesized equation " ++ attr.name ++ " exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsFlowType))] + else [mwdaWrnFromOrigin(top, "Synthesized equation " ++ attr.name ++ " exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsFlowType))] else []; } aspect production synAppendColAttributeDef @@ -432,9 +432,9 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur top.errors <- if dl.found && attr.found && top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.location, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ + then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ if null(lhsInhExceedsFlowType) then [] - else [mwdaWrn(top.config, top.location, "Synthesized equation " ++ attr.name ++ " exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsFlowType))] + else [mwdaWrnFromOrigin(top, "Synthesized equation " ++ attr.name ++ " exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsFlowType))] else []; } aspect production inhBaseColAttributeDef @@ -458,9 +458,9 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.location, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ + then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ if dl.name != "forward" || null(lhsInhExceedsForwardFlowType) then [] - else [mwdaWrn(top.config, top.location, "Forward inherited equation exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsForwardFlowType))] + else [mwdaWrnFromOrigin(top, "Forward inherited equation exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsForwardFlowType))] else []; } aspect production inhAppendColAttributeDef @@ -484,9 +484,9 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.location, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ + then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ if dl.name != "forward" || null(lhsInhExceedsForwardFlowType) then [] - else [mwdaWrn(top.config, top.location, "Forward inherited equation exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsForwardFlowType))] + else [mwdaWrnFromOrigin(top, "Forward inherited equation exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsForwardFlowType))] else []; } ------ END AWFUL COPY & PASTE SESSION @@ -505,9 +505,9 @@ top::ProductionStmt ::= 'forwards' 'to' e::Expr ';' top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.location, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ + then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ if null(lhsInhExceedsFlowType) then [] - else [mwdaWrn(top.config, top.location, "Forward equation exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsFlowType))] + else [mwdaWrnFromOrigin(top, "Forward equation exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsFlowType))] else []; } aspect production forwardInh @@ -533,9 +533,9 @@ top::ForwardInh ::= lhs::ForwardLHSExpr '=' e::Expr ';' top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.location, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ + then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ if null(lhsInhExceedsFlowType) then [] - else [mwdaWrn(top.config, top.location, "Forward inherited equation exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsFlowType))] + else [mwdaWrnFromOrigin(top, "Forward inherited equation exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsFlowType))] else []; } @@ -552,9 +552,9 @@ top::ProductionStmt ::= 'undecorates' 'to' e::Expr ';' top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.location, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ + then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ if null(lhsInhDeps) then [] - else [mwdaWrn(top.config, top.location, "Undecorates equation has dependencies on " ++ implode(", ", lhsInhDeps))] + else [mwdaWrnFromOrigin(top, "Undecorates equation has dependencies on " ++ implode(", ", lhsInhDeps))] else []; } @@ -567,7 +567,7 @@ top::ProductionStmt ::= val::Decorated! QName e::Expr -- check transitive deps only. No worries about flow types. top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.location, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) + then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) else []; } @@ -579,7 +579,7 @@ top::ProductionStmt ::= 'return' e::Expr ';' top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.location, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) + then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) else []; } @@ -591,7 +591,7 @@ top::ProductionStmt ::= 'attachNote' e::Expr ';' top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.location, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) + then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) else []; } @@ -618,7 +618,7 @@ top::ProductionStmt ::= val::Decorated! QName e::Expr -- We can ignore functions. We're checking LHS inhs here... functions don't have any! && top.frame.hasFullSignature then if null(lhsInhExceedsFlowType) then [] - else [mwdaWrn(top.config, top.location, "Local contribution (" ++ val.name ++ " <-) equation exceeds flow dependencies with: " ++ implode(", ", lhsInhExceedsFlowType))] + else [mwdaWrnFromOrigin(top, "Local contribution (" ++ val.name ++ " <-) equation exceeds flow dependencies with: " ++ implode(", ", lhsInhExceedsFlowType))] else []; } @@ -642,7 +642,7 @@ top::Expr ::= q::Decorated! QName if top.config.warnMissingInh && isDecorable(q.lookupValue.typeScheme.typerep, top.env) then if refSet.isJust then [] - else [mwdaWrn(top.config, top.location, s"Cannot take a reference of type ${prettyType(top.finalType)}, as the reference set is not bounded.")] + else [mwdaWrnFromOrigin(top, s"Cannot take a reference of type ${prettyType(top.finalType)}, as the reference set is not bounded.")] else []; } aspect production lhsReference @@ -651,7 +651,7 @@ top::Expr ::= q::Decorated! QName top.errors <- if top.config.warnMissingInh then if refSet.isJust then [] - else [mwdaWrn(top.config, top.location, s"Cannot take a reference of type ${prettyType(top.finalType)}, as the reference set is not bounded.")] + else [mwdaWrnFromOrigin(top, s"Cannot take a reference of type ${prettyType(top.finalType)}, as the reference set is not bounded.")] else []; } aspect production localReference @@ -661,7 +661,7 @@ top::Expr ::= q::Decorated! QName if top.config.warnMissingInh && isDecorable(q.lookupValue.typeScheme.typerep, top.env) then if refSet.isJust then [] - else [mwdaWrn(top.config, top.location, s"Cannot take a reference of type ${prettyType(top.finalType)}, as the reference set is not bounded.")] + else [mwdaWrnFromOrigin(top, s"Cannot take a reference of type ${prettyType(top.finalType)}, as the reference set is not bounded.")] else []; } aspect production forwardReference @@ -670,7 +670,7 @@ top::Expr ::= q::Decorated! QName top.errors <- if top.config.warnMissingInh then if refSet.isJust then [] - else [mwdaWrn(top.config, top.location, s"Cannot take a reference of type ${prettyType(top.finalType)}, as the reference set is not bounded.")] + else [mwdaWrnFromOrigin(top, s"Cannot take a reference of type ${prettyType(top.finalType)}, as the reference set is not bounded.")] else []; } @@ -711,7 +711,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur -- an access with unbounded inh deps only ever makes sense on a reference. | just(_) -> if deps.1.isJust then [] - else [mwdaWrn(top.config, top.location, "Access of " ++ q.name ++ " from " ++ prettyType(e.finalType) ++ " requires an unbounded set of inherited attributes")] + else [mwdaWrnFromOrigin(top, "Access of " ++ q.name ++ " from " ++ prettyType(e.finalType) ++ " requires an unbounded set of inherited attributes")] -- without a vertex, we're accessing from a reference, and so... | nothing() -> if any(map(contains(_, deps.2), acceptable.2)) then [] -- The deps are supplied as a common InhSet var @@ -720,10 +720,10 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur then if deps.fst.isJust then [] -- We have a bound on the inh deps, and they are all present -- We don't have a bound on the inh deps, flag the unsatisfied InhSet deps else if null(acceptable.2) - then [mwdaWrn(top.config, top.location, "Access of " ++ q.name ++ " from " ++ prettyType(e.finalType) ++ " requires an unbounded set of inherited attributes")] - else [mwdaWrn(top.config, top.location, "Access of " ++ q.name ++ " from reference of type " ++ prettyType(e.finalType) ++ " requires one of the following sets of inherited attributes not known to be supplied to this reference: " ++ implode(", ", map(findAbbrevFor(_, top.frame.signature.freeVariables), deps.snd)))] + then [mwdaWrnFromOrigin(top, "Access of " ++ q.name ++ " from " ++ prettyType(e.finalType) ++ " requires an unbounded set of inherited attributes")] + else [mwdaWrnFromOrigin(top, "Access of " ++ q.name ++ " from reference of type " ++ prettyType(e.finalType) ++ " requires one of the following sets of inherited attributes not known to be supplied to this reference: " ++ implode(", ", map(findAbbrevFor(_, top.frame.signature.freeVariables), deps.snd)))] -- We didn't find the inh deps - else [mwdaWrn(top.config, top.location, "Access of " ++ q.name ++ " from reference of type " ++ prettyType(e.finalType) ++ " requires inherited attributes not known to be supplied to this reference: " ++ implode(", ", diff))] + else [mwdaWrnFromOrigin(top, "Access of " ++ q.name ++ " from reference of type " ++ prettyType(e.finalType) ++ " requires inherited attributes not known to be supplied to this reference: " ++ implode(", ", diff))] end else []; @@ -754,7 +754,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur removeAll(getMinRefSet(lq.lookupValue.typeScheme.typerep, top.env), set:toList(inhDeps)))) in if null(inhs) then [] - else [mwdaWrn(top.config, top.location, "Access of syn attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] + else [mwdaWrnFromOrigin(top, "Access of syn attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] end else [] | localReference(lq) -> @@ -776,7 +776,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur removeAll(getMinRefSet(lq.lookupValue.typeScheme.typerep, top.env), set:toList(inhDeps)))) in if null(inhs) then [] - else [mwdaWrn(top.config, top.location, "Access of syn attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] + else [mwdaWrnFromOrigin(top, "Access of syn attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] end else [] | _ -> [] @@ -799,7 +799,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur | nothing() -> if contains(q.attrDcl.fullName, getMinRefSet(e.finalType, top.env)) then [] - else [mwdaWrn(top.config, top.location, "Access of inherited attribute " ++ q.name ++ " on reference of type " ++ prettyType(e.finalType) ++ " is not permitted")] + else [mwdaWrnFromOrigin(top, "Access of inherited attribute " ++ q.name ++ " on reference of type " ++ prettyType(e.finalType) ++ " is not permitted")] end else []; } @@ -822,7 +822,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur top.errors <- if top.config.warnMissingInh then if refSet.isJust then [] - else [mwdaWrn(top.config, top.location, s"Cannot take a reference of type ${prettyType(e.finalType)}, as the reference set is not bounded.")] + else [mwdaWrnFromOrigin(top, s"Cannot take a reference of type ${prettyType(e.finalType)}, as the reference set is not bounded.")] else []; -- TODO: check that reference set is only inhs? @@ -850,7 +850,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur -- an access with unbounded inh deps only ever makes sense on a reference. | just(_) -> if deps.1.isJust then [] - else [mwdaWrn(top.config, top.location, "Access of " ++ q.name ++ " from " ++ prettyType(e.finalType) ++ " requires an unbounded set of inherited attributes")] + else [mwdaWrnFromOrigin(top, "Access of " ++ q.name ++ " from " ++ prettyType(e.finalType) ++ " requires an unbounded set of inherited attributes")] -- without a vertex, we're accessing from a reference, and so... | nothing() -> if any(map(contains(_, deps.2), acceptable.2)) then [] -- The deps are supplied as a common InhSet var @@ -859,10 +859,10 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur then if deps.fst.isJust then [] -- We have a bound on the inh deps, and they are all present -- We don't have a bound on the inh deps, flag the unsatisfied InhSet deps else if null(acceptable.2) - then [mwdaWrn(top.config, top.location, "Access of " ++ q.name ++ " from " ++ prettyType(e.finalType) ++ " requires an unbounded set of inherited attributes")] - else [mwdaWrn(top.config, top.location, "Access of " ++ q.name ++ " from reference of type " ++ prettyType(e.finalType) ++ " requires one of the following sets of inherited attributes not known to be supplied to this reference: " ++ implode(", ", map(findAbbrevFor(_, top.frame.signature.freeVariables), deps.snd)))] + then [mwdaWrnFromOrigin(top, "Access of " ++ q.name ++ " from " ++ prettyType(e.finalType) ++ " requires an unbounded set of inherited attributes")] + else [mwdaWrnFromOrigin(top, "Access of " ++ q.name ++ " from reference of type " ++ prettyType(e.finalType) ++ " requires one of the following sets of inherited attributes not known to be supplied to this reference: " ++ implode(", ", map(findAbbrevFor(_, top.frame.signature.freeVariables), deps.snd)))] -- We didn't find the inh deps - else [mwdaWrn(top.config, top.location, "Access of " ++ q.name ++ " from reference of type " ++ prettyType(e.finalType) ++ " requires inherited attributes not known to be supplied to this reference: " ++ implode(", ", diff))] + else [mwdaWrnFromOrigin(top, "Access of " ++ q.name ++ " from reference of type " ++ prettyType(e.finalType) ++ " requires inherited attributes not known to be supplied to this reference: " ++ implode(", ", diff))] end else []; @@ -893,7 +893,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur removeAll(getMinRefSet(lq.lookupValue.typeScheme.typerep, top.env), set:toList(inhDeps)))) in if null(inhs) then [] - else [mwdaWrn(top.config, top.location, "Access of syn attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] + else [mwdaWrnFromOrigin(top, "Access of syn attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] end else [] | localReference(lq) -> @@ -915,7 +915,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur removeAll(getMinRefSet(lq.lookupValue.typeScheme.typerep, top.env), set:toList(inhDeps)))) in if null(inhs) then [] - else [mwdaWrn(top.config, top.location, "Access of syn attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] + else [mwdaWrnFromOrigin(top, "Access of syn attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] end else [] | _ -> [] @@ -962,7 +962,7 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr && top.config.warnMissingInh && sinkVertexName.isJust && !null(diff) - then [mwdaWrn(top.config, e.location, "Pattern match on reference of type " ++ prettyType(scrutineeType) ++ " has transitive dependencies on " ++ implode(", ", diff))] + then [mwdaWrnFromOrigin(e, "Pattern match on reference of type " ++ prettyType(scrutineeType) ++ " has transitive dependencies on " ++ implode(", ", diff))] else []; } @@ -988,7 +988,7 @@ top::VarBinder ::= n::Name if top.config.warnMissingInh && isDecorable(top.bindingType, top.env) then if refSet.isJust then [] - else [mwdaWrn(top.config, top.location, s"Cannot take a reference of type ${prettyType(finalTy)}, as the reference set is not bounded.")] + else [mwdaWrnFromOrigin(top, s"Cannot take a reference of type ${prettyType(finalTy)}, as the reference set is not bounded.")] else []; -- fName is our invented vertex name for the pattern variable @@ -1007,7 +1007,7 @@ top::VarBinder ::= n::Name && isDecorable(top.bindingType, top.env) && top.matchingAgainst.isJust && !null(missingInhs) - then [mwdaWrn(top.config, top.location, s"Pattern variable '${n.name}' has transitive dependencies with missing remote equations.\n\tRemote production: ${top.matchingAgainst.fromJust.fullName}\n\tChild: ${top.bindingName}\n\tMissing inherited equations for: ${implode(", ", missingInhs)}")] + then [mwdaWrnFromOrigin(top, s"Pattern variable '${n.name}' has transitive dependencies with missing remote equations.\n\tRemote production: ${top.matchingAgainst.fromJust.fullName}\n\tChild: ${top.bindingName}\n\tMissing inherited equations for: ${implode(", ", missingInhs)}")] else []; } diff --git a/grammars/silver/compiler/analysis/warnings/flow/MissingSynEq.sv b/grammars/silver/compiler/analysis/warnings/flow/MissingSynEq.sv index 1654d05a5..f4f63355d 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/MissingSynEq.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/MissingSynEq.sv @@ -49,7 +49,7 @@ top::AGDcl ::= 'attribute' at::QName attl::BracketedOptTypeExprs 'occurs' 'on' n -- And we can ignore any attribute that has a default equation: && null(lookupDef(nt.lookupType.fullName, at.lookupAttribute.fullName, top.flowEnv)) -- Otherwise, examine them all: - then flatMap(raiseMissingProds(top.config, top.location, at.lookupAttribute.fullName, _, top.flowEnv), nfprods) + then flatMap(raiseMissingProds(top.config, at.lookupAttribute.fullName, _, top.flowEnv), nfprods) else []; } @@ -57,21 +57,20 @@ top::AGDcl ::= 'attribute' at::QName attl::BracketedOptTypeExprs 'occurs' 'on' n - Examine a non-forwarding production `prod` to see if it is missing an equation - for the synthesized attribute `attr`. - - - @param l Location to raise the error message (of the attribute occurence) - @param attr Full name of a synthesized attribute - @param prod Full name of non-forwarding production to examine - @param e The local flow environment - @returns An error message from the attribute occurrence's perspective, if any -} function raiseMissingProds -[Message] ::= config::Decorated CmdArgs l::Location attr::String prod::String e::FlowEnv +[Message] ::= config::Decorated CmdArgs attr::String prod::String e::FlowEnv { -- Because the location is of the attribute occurrence, deliberately use the attribute's shortname local shortName :: String = substring(lastIndexOf(":", attr) + 1, length(attr), attr); return case lookupSyn(prod, attr, e) of | _ :: _ -> [] -- equation exists - | [] -> [mwdaWrn(config, l, "attribute " ++ shortName ++ " missing equation for production " ++ prod)] + | [] -> [mwdaWrnAmbientOrigin(config, "attribute " ++ shortName ++ " missing equation for production " ++ prod)] end; } @@ -95,7 +94,7 @@ top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::Pr -- Forwarding productions do not have missing synthesized equations: && null(body.forwardExpr) -- Otherwise, examine them all: - then flatMap(raiseMissingAttrs(top.config, top.location, fName, namedSig.outputElement.typerep.typeName, _, top.flowEnv), attrs) + then flatMap(raiseMissingAttrs(top.config, fName, namedSig.outputElement.typerep.typeName, _, top.flowEnv), attrs) else []; } @@ -103,7 +102,6 @@ top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::Pr - Examine a non-forwarding production `prod` to see if it is missing an equation - for the synthesized attribute `attr`. - - - @param l Location to raise the error message (of the production) - @param prod Full name of the non-forwarding production in question - @param nt Full name of prod's lhs nonterminal - @param attr Full name of a synthesized attribute @@ -111,7 +109,7 @@ top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::Pr - @returns An error message from the production's perspective, if any -} function raiseMissingAttrs -[Message] ::= config::Decorated CmdArgs l::Location prod::String nt::String attr::String e::FlowEnv +[Message] ::= config::Decorated CmdArgs prod::String nt::String attr::String e::FlowEnv { -- Because the location is of the production, deliberately use the production's shortname local shortName :: String = substring(lastIndexOf(":", prod) + 1, length(prod), prod); @@ -125,7 +123,7 @@ function raiseMissingAttrs end; return if lacks_default_equation && missing_explicit_equation - then [mwdaWrn(config, l, "production " ++ shortName ++ " lacks synthesized equation for " ++ attr)] + then [mwdaWrnAmbientOrigin(config, "production " ++ shortName ++ " lacks synthesized equation for " ++ attr)] else []; } diff --git a/grammars/silver/compiler/analysis/warnings/flow/MwdaFlag.sv b/grammars/silver/compiler/analysis/warnings/flow/MwdaFlag.sv index 7aa692438..088b98737 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/MwdaFlag.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/MwdaFlag.sv @@ -47,3 +47,16 @@ Message ::= config::Decorated CmdArgs l::Location m::String then err(l, m) else wrn(l, m); } + +function mwdaWrnFromOrigin +attribute config occurs on a => +Message ::= a::Decorated a with {config} m::String +{ + return mwdaWrn(a.config, getParsedOriginLocationOrFallback(a), m); +} + +function mwdaWrnAmbientOrigin +Message ::= config::Decorated CmdArgs m::String +{ + return mwdaWrn(config, getParsedOriginLocationOrFallback(ambientOrigin()), m); +} diff --git a/grammars/silver/compiler/analysis/warnings/flow/OrphanedEquation.sv b/grammars/silver/compiler/analysis/warnings/flow/OrphanedEquation.sv index 13367aa52..d30a0b134 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/OrphanedEquation.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/OrphanedEquation.sv @@ -38,13 +38,13 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e if dl.found && attr.found && top.config.warnEqdef && !isExportedBy(top.grammarName, exportedBy, top.compiledGrammars) - then [mwdaWrn(top.config, top.location, "Orphaned equation: " ++ attr.name ++ " (occurs from " ++ attr.dcl.sourceGrammar ++ ") in production " ++ top.frame.fullName)] + then [mwdaWrnFromOrigin(top, "Orphaned equation: " ++ attr.name ++ " (occurs from " ++ attr.dcl.sourceGrammar ++ ") in production " ++ top.frame.fullName)] else []; -- Duplicate equation check top.errors <- if length(dl.lookupEqDefLHS) > 1 - then [mwdaWrn(top.config, top.location, "Duplicate equation for " ++ attr.name ++ " in production " ++ top.frame.fullName)] + then [mwdaWrnFromOrigin(top, "Duplicate equation for " ++ attr.name ++ " in production " ++ top.frame.fullName)] else []; } @@ -70,13 +70,13 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur if dl.found && attr.found && top.config.warnEqdef && !isExportedBy(top.grammarName, exportedBy, top.compiledGrammars) - then [mwdaWrn(top.config, top.location, "Orphaned equation: " ++ attr.name ++ " on " ++ dl.name ++ " (occurs from " ++ attr.dcl.sourceGrammar ++ ") in production " ++ top.frame.fullName)] + then [mwdaWrnFromOrigin(top, "Orphaned equation: " ++ attr.name ++ " on " ++ dl.name ++ " (occurs from " ++ attr.dcl.sourceGrammar ++ ") in production " ++ top.frame.fullName)] -- Now, check for duplicate equations! else []; top.errors <- if length(dl.lookupEqDefLHS) > 1 || contains(dl.inhAttrName, getMinRefSet(dl.typerep, top.env)) - then [mwdaWrn(top.config, top.location, "Duplicate equation for " ++ attr.name ++ " on " ++ dl.name ++ " in production " ++ top.frame.fullName)] + then [mwdaWrnFromOrigin(top, "Duplicate equation for " ++ attr.name ++ " on " ++ dl.name ++ " in production " ++ top.frame.fullName)] else []; } @@ -96,13 +96,13 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur if dl.found && attr.found && top.config.warnEqdef && !isExportedBy(top.grammarName, exportedBy, top.compiledGrammars) - then [mwdaWrn(top.config, top.location, "Orphaned equation: " ++ attr.name ++ " (occurs from " ++ attr.dcl.sourceGrammar ++ ") in production " ++ top.frame.fullName)] + then [mwdaWrnFromOrigin(top, "Orphaned equation: " ++ attr.name ++ " (occurs from " ++ attr.dcl.sourceGrammar ++ ") in production " ++ top.frame.fullName)] else []; -- Duplicate equation check top.errors <- if length(dl.lookupEqDefLHS) > 1 - then [mwdaWrn(top.config, top.location, "Duplicate equation for " ++ attr.name ++ " in production " ++ top.frame.fullName)] + then [mwdaWrnFromOrigin(top, "Duplicate equation for " ++ attr.name ++ " in production " ++ top.frame.fullName)] else []; } aspect production inhBaseColAttributeDef @@ -127,13 +127,13 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur if dl.found && attr.found && top.config.warnEqdef && !isExportedBy(top.grammarName, exportedBy, top.compiledGrammars) - then [mwdaWrn(top.config, top.location, "Orphaned equation: " ++ attr.name ++ " on " ++ dl.name ++ " (occurs from " ++ attr.dcl.sourceGrammar ++ ") in production " ++ top.frame.fullName)] + then [mwdaWrnFromOrigin(top, "Orphaned equation: " ++ attr.name ++ " on " ++ dl.name ++ " (occurs from " ++ attr.dcl.sourceGrammar ++ ") in production " ++ top.frame.fullName)] -- Now, check for duplicate equations! else []; top.errors <- if length(dl.lookupEqDefLHS) > 1 || contains(dl.inhAttrName, getMinRefSet(dl.typerep, top.env)) - then [mwdaWrn(top.config, top.location, "Duplicate equation for " ++ attr.name ++ " on " ++ dl.name ++ " in production " ++ top.frame.fullName)] + then [mwdaWrnFromOrigin(top, "Duplicate equation for " ++ attr.name ++ " on " ++ dl.name ++ " in production " ++ top.frame.fullName)] else []; } @@ -143,7 +143,7 @@ top::ExprLHSExpr ::= attr::QNameAttrOccur -- Duplicate equation check top.errors <- if attr.attrFound && length(filter(eq(attr.attrDcl.fullName, _), top.allSuppliedInhs)) > 1 - then [mwdaWrn(top.config, top.location, "Duplicate equation for " ++ attr.name)] + then [mwdaWrnFromOrigin(top, "Duplicate equation for " ++ attr.name)] else []; } diff --git a/grammars/silver/compiler/analysis/warnings/flow/OrphanedOccurs.sv b/grammars/silver/compiler/analysis/warnings/flow/OrphanedOccurs.sv index e28d3523d..f4d04ebee 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/OrphanedOccurs.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/OrphanedOccurs.sv @@ -29,7 +29,7 @@ top::AGDcl ::= 'attribute' at::QName attl::BracketedOptTypeExprs 'occurs' 'on' n if nt.lookupType.found && at.lookupAttribute.found && top.config.warnOrphaned && !isExportedBy(top.grammarName, [nt.lookupType.dcl.sourceGrammar, at.lookupAttribute.dcl.sourceGrammar], top.compiledGrammars) - then [mwdaWrn(top.config, top.location, "Orphaned occurs declaration: " ++ at.lookupAttribute.fullName ++ " on " ++ nt.lookupType.fullName)] + then [mwdaWrnFromOrigin(top, "Orphaned occurs declaration: " ++ at.lookupAttribute.fullName ++ " on " ++ nt.lookupType.fullName)] -- If this is a non-closed NT, or not a synthesized attribute, then we're done. else []; @@ -38,7 +38,7 @@ top::AGDcl ::= 'attribute' at::QName attl::BracketedOptTypeExprs 'occurs' 'on' n -- For closed nt, either we're exported by only the nt, OR there MUST be a default! else if !isExportedBy(top.grammarName, [nt.lookupType.dcl.sourceGrammar], top.compiledGrammars) && null(lookupDef(nt.lookupType.fullName, at.lookupAttribute.fullName, top.flowEnv)) - then [mwdaWrn(top.config, top.location, at.lookupAttribute.fullName ++ " cannot occur on " ++ nt.lookupType.fullName ++ " because that nonterminal is closed, and this attribute does not have a default equation.")] + then [mwdaWrnFromOrigin(top, at.lookupAttribute.fullName ++ " cannot occur on " ++ nt.lookupType.fullName ++ " because that nonterminal is closed, and this attribute does not have a default equation.")] else []; } diff --git a/grammars/silver/compiler/analysis/warnings/flow/OrphanedProduction.sv b/grammars/silver/compiler/analysis/warnings/flow/OrphanedProduction.sv index c89ee9ae2..f73327994 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/OrphanedProduction.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/OrphanedProduction.sv @@ -43,7 +43,7 @@ top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::Pr && !isClosedNt -- AND this production is not exported by the nonterminal definition grammar... even including options && !isExportedBy(top.grammarName, [ntDefGram], top.compiledGrammars) - then [mwdaWrn(top.config, top.location, "Orphaned production: " ++ id.name ++ " on " ++ namedSig.outputElement.typerep.typeName)] + then [mwdaWrnFromOrigin(top, "Orphaned production: " ++ id.name ++ " on " ++ namedSig.outputElement.typerep.typeName)] else []; } diff --git a/grammars/silver/compiler/definition/concrete_syntax/NonTerminalDcl.sv b/grammars/silver/compiler/definition/concrete_syntax/NonTerminalDcl.sv index c85af5cb1..f6a9d802d 100644 --- a/grammars/silver/compiler/definition/concrete_syntax/NonTerminalDcl.sv +++ b/grammars/silver/compiler/definition/concrete_syntax/NonTerminalDcl.sv @@ -8,7 +8,7 @@ top::AGDcl ::= quals::NTDeclQualifiers 'nonterminal' id::Name tl::BracketedOptTy -- TODO: We are building this for every nonterminal declaration, when it should -- be the same for all nonterminals in the grammar local med :: ModuleExportedDefs = - moduleExportedDefs(top.location, top.compiledGrammars, top.grammarDependencies, [top.grammarName], []); + moduleExportedDefs(top.compiledGrammars, top.grammarDependencies, [top.grammarName], []); local syntax::Syntax = foldr(consSyntax, nilSyntax(), med.syntaxAst); production isThisTracked::Boolean = top.config.forceOrigins || ((!top.config.noOrigins) && quals.tracked); @@ -20,7 +20,7 @@ top::AGDcl ::= quals::NTDeclQualifiers 'nonterminal' id::Name tl::BracketedOptTy nonterminalType(fName, map((.kindrep), tl.types), quals.data, isThisTracked), nilSyntax(), exportedProds, exportedLayoutTerms, foldr(consNonterminalMod, nilNonterminalMod(), nm.nonterminalModifiers), - location=top.location, sourceGrammar=top.grammarName) + location=getParsedOriginLocationOrFallback(top), sourceGrammar=top.grammarName) ]; } diff --git a/grammars/silver/compiler/definition/concrete_syntax/ParserSpec.sv b/grammars/silver/compiler/definition/concrete_syntax/ParserSpec.sv index 8e7e5088c..7c05a0b59 100644 --- a/grammars/silver/compiler/definition/concrete_syntax/ParserSpec.sv +++ b/grammars/silver/compiler/definition/concrete_syntax/ParserSpec.sv @@ -47,7 +47,7 @@ top::ParserSpec ::= -- to all grammars imported in the env. -- This could affect which conditional imports get triggered, and thus what gets included in the parser production deps :: [String] = computeDependencies(grams, top.compiledGrammars); - production med :: ModuleExportedDefs = moduleExportedDefs(top.location, top.compiledGrammars, deps, grams, []); + production med :: ModuleExportedDefs = moduleExportedDefs(top.compiledGrammars, deps, grams, []); -- Compute the list of terminal prefixes for marking terminals here, because the set of marking -- terminals exported by a grammar depends on conditional imports that may be triggered by other @@ -62,7 +62,7 @@ top::ParserSpec ::= \ g::String -> (g, foldr(consSyntax, nilSyntax(), - moduleExportedDefs(top.location, top.compiledGrammars, deps, [g], []).syntaxAst).allMarkingTerminals), + moduleExportedDefs(top.compiledGrammars, deps, [g], []).syntaxAst).allMarkingTerminals), grams); production markingTerminalPrefixes::[Pair] = flatMap( diff --git a/grammars/silver/compiler/definition/concrete_syntax/ProductionDcl.sv b/grammars/silver/compiler/definition/concrete_syntax/ProductionDcl.sv index ae4350d02..f1e44d344 100644 --- a/grammars/silver/compiler/definition/concrete_syntax/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/concrete_syntax/ProductionDcl.sv @@ -24,18 +24,18 @@ top::AGDcl ::= 'concrete' 'production' id::Name ns::ProductionSignature pm::Prod top.syntaxAst := [ syntaxProduction(namedSig, foldr(consProductionMod, nilProductionMod(), pm.productionModifiers), - location=top.location, sourceGrammar=top.grammarName) + location=getParsedOriginLocationOrFallback(top), sourceGrammar=top.grammarName) ]; - forwards to productionDcl('abstract', $2, id, ns, body, location=top.location); + forwards to productionDcl('abstract', $2, id, ns, body); } action { - insert semantic token IdFnProdDcl_t at id.location; + insert semantic token IdFnProdDcl_t at id.nameLoc; sigNames = []; } -nonterminal ProductionModifiers with config, location, unparse, productionModifiers, errors, env, productionSig; -- 0 or some -nonterminal ProductionModifierList with config, location, unparse, productionModifiers, errors, env, productionSig; -- 1 or more -closed nonterminal ProductionModifier with config, location, unparse, productionModifiers, errors, env, productionSig; -- 1 +tracked nonterminal ProductionModifiers with config, unparse, productionModifiers, errors, env, productionSig; -- 0 or some +tracked nonterminal ProductionModifierList with config, unparse, productionModifiers, errors, env, productionSig; -- 1 or more +closed tracked nonterminal ProductionModifier with config, unparse, productionModifiers, errors, env, productionSig; -- 1 monoid attribute productionModifiers :: [SyntaxProductionModifier]; @@ -85,7 +85,7 @@ top::ProductionModifier ::= 'operator' '=' n::QNameType top.errors <- n.lookupType.errors ++ if !n.lookupType.typeScheme.isTerminal - then [err(n.location, n.unparse ++ " is not a terminal.")] + then [errFromOrigin(n, n.unparse ++ " is not a terminal.")] else []; } @@ -109,9 +109,9 @@ top::ProductionSignature ::= cl::ConstraintList '=>' lhs::ProductionLHS '::=' rh local checkSecond :: Boolean = lstType.isTerminal || !null(getOccursDcl("silver:core:location", lstType.typeName, top.env)) || lstType.isTracked; local errFirst :: [Message] = - if checkFirst then [] else [err(top.location, "Production has location annotation or is tracked, but first element of signature does not have location and is not tracked.")]; + if checkFirst then [] else [errFromOrigin(top, "Production has location annotation or is tracked, but first element of signature does not have location and is not tracked.")]; local errSecond :: [Message] = - if checkSecond then [] else [err(top.location, "Production has location annotation or is tracked, but last element of signature does not have location and is not tracked.")]; + if checkSecond then [] else [errFromOrigin(top, "Production has location annotation or is tracked, but last element of signature does not have location and is not tracked.")]; local lhsHasLocation :: Boolean = case top.namedSignature.namedInputElements of @@ -124,7 +124,7 @@ top::ProductionSignature ::= cl::ConstraintList '=>' lhs::ProductionLHS '::=' rh case top.namedSignature.namedInputElements of | [] -> [] | [namedSignatureElement("silver:core:location", _)] -> [] - | _ -> [err(top.location, "Annotation(s) on this production are not handleable by the parser generator (only a single annotation, and only silver:core:location is supported.)")] + | _ -> [errFromOrigin(top, "Annotation(s) on this production are not handleable by the parser generator (only a single annotation, and only silver:core:location is supported.)")] end; top.concreteSyntaxTypeErrors <- @@ -142,7 +142,7 @@ top::ProductionRHSElem ::= id::Name '::' t::TypeExpr { top.concreteSyntaxTypeErrors <- if t.typerep.permittedInConcreteSyntax then [] - else [err(t.location, t.unparse ++ " is not permitted on concrete productions. Only terminals and nonterminals (without type variables) can appear here")]; + else [errFromOrigin(t, t.unparse ++ " is not permitted on concrete productions. Only terminals and nonterminals (without type variables) can appear here")]; } synthesized attribute permittedInConcreteSyntax :: Boolean occurs on Type; diff --git a/grammars/silver/compiler/definition/concrete_syntax/RootSpec.sv b/grammars/silver/compiler/definition/concrete_syntax/RootSpec.sv index f5ba7f766..98419b7a0 100644 --- a/grammars/silver/compiler/definition/concrete_syntax/RootSpec.sv +++ b/grammars/silver/compiler/definition/concrete_syntax/RootSpec.sv @@ -47,7 +47,7 @@ InterfaceItems ::= r::Decorated RootSpec } aspect production moduleExportedDefs -top::ModuleExportedDefs ::= l::Location compiled::EnvTree grammarDependencies::[String] need::[String] seen::[String] +top::ModuleExportedDefs ::= compiled::EnvTree grammarDependencies::[String] need::[String] seen::[String] { top.syntaxAst := if null(need) || null(rs) then [] else (head(rs).syntaxAst ++ recurse.syntaxAst); top.parserSpecs := if null(need) || null(rs) then [] else (head(rs).parserSpecs ++ recurse.parserSpecs); diff --git a/grammars/silver/compiler/definition/concrete_syntax/TerminalDcl.sv b/grammars/silver/compiler/definition/concrete_syntax/TerminalDcl.sv index 1daeab44a..d624df277 100644 --- a/grammars/silver/compiler/definition/concrete_syntax/TerminalDcl.sv +++ b/grammars/silver/compiler/definition/concrete_syntax/TerminalDcl.sv @@ -24,22 +24,22 @@ top::AGDcl ::= t::TerminalKeywordModifier id::Name r::RegExpr tm::TerminalModifi production attribute fName :: String; fName = top.grammarName ++ ":" ++ id.name; - top.defs := [termDef(top.grammarName, id.location, fName, r.terminalRegExprSpec, r.easyName, tm.genRepeatProb)]; + top.defs := [termDef(top.grammarName, id.nameLoc, fName, r.terminalRegExprSpec, r.easyName, tm.genRepeatProb)]; top.errors <- if length(getTypeDclAll(fName, top.env)) > 1 - then [err(id.location, "Type '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(id, "Type '" ++ fName ++ "' is already bound.")] else []; top.errors <- if isLower(substring(0,1,id.name)) - then [err(id.location, "Types must be capitalized. Invalid terminal name " ++ id.name)] + then [errFromOrigin(id, "Types must be capitalized. Invalid terminal name " ++ id.name)] else []; -- This is a crude check, but effective. top.errors <- if indexOf("\n", unescapeString(r.unparse)) != -1 && indexOf("\r", unescapeString(r.unparse)) == -1 - then [wrn(r.location, "Regex contains '\\n' but not '\\r'. This is your reminder about '\\r\\n' newlines.")] + then [wrnFromOrigin(r, "Regex contains '\\n' but not '\\r'. This is your reminder about '\\r\\n' newlines.")] else []; propagate config, grammarName, compiledGrammars, env, errors; @@ -47,30 +47,30 @@ top::AGDcl ::= t::TerminalKeywordModifier id::Name r::RegExpr tm::TerminalModifi top.syntaxAst := [ syntaxTerminal(fName, r.terminalRegExprSpec, foldr(consTerminalMod, nilTerminalMod(), t.terminalModifiers ++ tm.terminalModifiers), - location=top.location, sourceGrammar=top.grammarName)]; + location=getParsedOriginLocationOrFallback(top), sourceGrammar=top.grammarName)]; } concrete production terminalDclKwdModifiers top::AGDcl ::= t::TerminalKeywordModifier 'terminal' id::Name r::RegExpr ';' { - forwards to terminalDclDefault(t, id, r, terminalModifiersNone(location=$5.location), location=top.location); + forwards to terminalDclDefault(t, id, r, terminalModifiersNone()); } action { - insert semantic token IdTypeDcl_t at id.location; + insert semantic token IdTypeDcl_t at id.nameLoc; } concrete production terminalDclAllModifiers top::AGDcl ::= t::TerminalKeywordModifier 'terminal' id::Name r::RegExpr tm::TerminalModifiers ';' { - forwards to terminalDclDefault(t, id, r, tm, location=top.location); + forwards to terminalDclDefault(t, id, r, tm); } action { - insert semantic token IdTypeDcl_t at id.location; + insert semantic token IdTypeDcl_t at id.nameLoc; } {-- - This exists as a catch-all for representing regular expressions for terminals. - There's only one option here, but it's an extension point. -} -nonterminal RegExpr with config, location, grammarName, unparse, terminalRegExprSpec, easyName; +tracked nonterminal RegExpr with config, grammarName, unparse, terminalRegExprSpec, easyName; synthesized attribute terminalRegExprSpec :: abs:Regex; synthesized attribute easyName :: Maybe; @@ -82,7 +82,7 @@ top::RegExpr ::= '/' r::Regex '/' layout {} { top.unparse = "/" ++ r.unparse ++ "/"; - forwards to regExpr(r.ast, location=top.location); + forwards to regExpr(r.ast); } abstract production regExpr @@ -94,7 +94,7 @@ top::RegExpr ::= r::abs:Regex } -closed nonterminal TerminalKeywordModifier with unparse, location, terminalModifiers; +closed tracked nonterminal TerminalKeywordModifier with unparse, terminalModifiers; concrete production terminalKeywordModifierIgnore top::TerminalKeywordModifier ::= 'ignore' @@ -121,8 +121,8 @@ top::TerminalKeywordModifier ::= } -nonterminal TerminalModifiers with config, location, unparse, terminalModifiers, genRepeatProb, errors, env, grammarName, compiledGrammars, flowEnv; -closed nonterminal TerminalModifier with config, location, unparse, terminalModifiers, genRepeatProb, errors, env, grammarName, compiledGrammars, flowEnv; +tracked nonterminal TerminalModifiers with config, unparse, terminalModifiers, genRepeatProb, errors, env, grammarName, compiledGrammars, flowEnv; +closed tracked nonterminal TerminalModifier with config, unparse, terminalModifiers, genRepeatProb, errors, env, grammarName, compiledGrammars, flowEnv; monoid attribute terminalModifiers :: [SyntaxTerminalModifier]; monoid attribute genRepeatProb :: Maybe with nothing(), orElse; @@ -197,7 +197,7 @@ top::TerminalModifier ::= 'repeatProb' '=' f::Float_t top.genRepeatProb := just(toFloat(f.lexeme)); top.errors := if toFloat(f.lexeme) >= 1.0 - then [err(f.location, "Repeat probability must be < 1.0")] + then [errFromOrigin(f, "Repeat probability must be < 1.0")] else []; } diff --git a/grammars/silver/compiler/definition/core/AGDcl.sv b/grammars/silver/compiler/definition/core/AGDcl.sv index 3134a55f9..7516b7212 100644 --- a/grammars/silver/compiler/definition/core/AGDcl.sv +++ b/grammars/silver/compiler/definition/core/AGDcl.sv @@ -3,8 +3,8 @@ grammar silver:compiler:definition:core; {-- - Top-level declarations of a Silver grammar. The "meat" of a file. -} -nonterminal AGDcls with config, grammarName, env, location, unparse, errors, defs, occursDefs, moduleNames, compiledGrammars, grammarDependencies, jarName; -nonterminal AGDcl with config, grammarName, env, location, unparse, errors, defs, occursDefs, moduleNames, compiledGrammars, grammarDependencies, jarName; +tracked nonterminal AGDcls with config, grammarName, env, unparse, errors, defs, occursDefs, moduleNames, compiledGrammars, grammarDependencies, jarName; +tracked nonterminal AGDcl with config, grammarName, env, unparse, errors, defs, occursDefs, moduleNames, compiledGrammars, grammarDependencies, jarName; flowtype decorate {config, grammarName, env, flowEnv, compiledGrammars, grammarDependencies} on AGDcls, AGDcl; flowtype forward {} on AGDcls; @@ -29,7 +29,7 @@ top::AGDcls ::= h::AGDcl t::AGDcls { top.unparse = h.unparse ++ "\n" ++ t.unparse; - top.errors <- warnIfMultJarName(h.jarName, t.jarName, top.location); + top.errors <- warnIfMultJarName(h.jarName, t.jarName); } -------- @@ -68,15 +68,15 @@ top::AGDcl ::= h::AGDcl t::AGDcl top.unparse = h.unparse ++ "\n" ++ t.unparse; propagate env, defs, occursDefs; - top.errors <- warnIfMultJarName(h.jarName, t.jarName, top.location); + top.errors <- warnIfMultJarName(h.jarName, t.jarName); } function makeAppendAGDclOfAGDcls AGDcl ::= dcls::AGDcls { return case dcls of - | nilAGDcls(location=l) -> emptyAGDcl(location=l) - | consAGDcls(dcl, rest, location=l) -> appendAGDcl(dcl, makeAppendAGDclOfAGDcls(rest), location=l) + | nilAGDcls() -> emptyAGDcl() + | consAGDcls(dcl, rest) -> appendAGDcl(dcl, makeAppendAGDclOfAGDcls(rest)) end; } @@ -94,11 +94,12 @@ top::AGDcl ::= } function warnIfMultJarName -[Message] ::= n1::Maybe n2::Maybe loc::Location +[Message] ::= n1::Maybe n2::Maybe { return if n1.isJust && n2.isJust - then [wrn(loc, "Duplicate specification of jar name: " ++ - n1.fromJust ++ " and " ++ n2.fromJust)] + then [wrnFromOrigin(ambientOrigin(), + "Duplicate specification of jar name: " ++ + n1.fromJust ++ " and " ++ n2.fromJust)] else []; } diff --git a/grammars/silver/compiler/definition/core/Annotation.sv b/grammars/silver/compiler/definition/core/Annotation.sv index 7109688d9..56c8055f3 100644 --- a/grammars/silver/compiler/definition/core/Annotation.sv +++ b/grammars/silver/compiler/definition/core/Annotation.sv @@ -11,7 +11,7 @@ top::AGDcl ::= 'annotation' a::QName tl::BracketedOptTypeExprs '::' te::TypeExpr production fName :: String = top.grammarName ++ ":" ++ a.name; - top.defs := [annoDef(top.grammarName, a.location, fName, tl.freeVariables, te.typerep)]; + top.defs := [annoDef(top.grammarName, getParsedOriginLocationOrFallback(a), fName, tl.freeVariables, te.typerep)]; tl.initialEnv = top.env; tl.env = tl.envBindingTyVars; @@ -19,11 +19,11 @@ top::AGDcl ::= 'annotation' a::QName tl::BracketedOptTypeExprs '::' te::TypeExpr top.errors <- if length(getAttrDclAll(fName, top.env)) > 1 - then [err(a.location, "The name '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(a, "The name '" ++ fName ++ "' is already bound.")] else []; top.errors <- if indexOf(":", a.name) == -1 then [] - else [err(a.location, "The name '" ++ a.name ++ "' must not be qualified.")]; + else [errFromOrigin(a, "The name '" ++ a.name ++ "' must not be qualified.")]; top.errors <- tl.errorsTyVars; } diff --git a/grammars/silver/compiler/definition/core/AspectDcl.sv b/grammars/silver/compiler/definition/core/AspectDcl.sv index 18a9e8937..218490f16 100644 --- a/grammars/silver/compiler/definition/core/AspectDcl.sv +++ b/grammars/silver/compiler/definition/core/AspectDcl.sv @@ -1,13 +1,13 @@ grammar silver:compiler:definition:core; -nonterminal AspectProductionSignature with config, grammarName, env, location, unparse, errors, defs, realSignature, namedSignature, signatureName; -nonterminal AspectProductionLHS with config, grammarName, env, location, unparse, errors, defs, outputElement, realSignature; +tracked nonterminal AspectProductionSignature with config, grammarName, env, unparse, errors, defs, realSignature, namedSignature, signatureName; +tracked nonterminal AspectProductionLHS with config, grammarName, env, unparse, errors, defs, outputElement, realSignature; -nonterminal AspectFunctionSignature with config, grammarName, env, location, unparse, errors, defs, realSignature, namedSignature, signatureName; -nonterminal AspectFunctionLHS with config, grammarName, env, location, unparse, errors, defs, realSignature, outputElement; +tracked nonterminal AspectFunctionSignature with config, grammarName, env, unparse, errors, defs, realSignature, namedSignature, signatureName; +tracked nonterminal AspectFunctionLHS with config, grammarName, env, unparse, errors, defs, realSignature, outputElement; -nonterminal AspectRHS with config, grammarName, env, location, unparse, errors, defs, inputElements, realSignature; -nonterminal AspectRHSElem with config, grammarName, env, location, unparse, errors, defs, realSignature, inputElements, deterministicCount; +tracked nonterminal AspectRHS with config, grammarName, env, unparse, errors, defs, inputElements, realSignature; +tracked nonterminal AspectRHSElem with config, grammarName, env, unparse, errors, defs, realSignature, inputElements, deterministicCount; flowtype forward {realSignature, grammarName, env, flowEnv} on AspectProductionSignature, AspectProductionLHS, AspectFunctionSignature, AspectFunctionLHS, AspectRHS; flowtype forward {deterministicCount, realSignature, grammarName, env, flowEnv} on AspectRHSElem; @@ -28,7 +28,7 @@ top::AGDcl ::= 'aspect' 'production' id::QName ns::AspectProductionSignature bod top.defs := if null(body.productionAttributes) then [] - else [prodOccursDef(top.grammarName, id.location, namedSig, body.productionAttributes)]; + else [prodOccursDef(top.grammarName, id.nameLoc, namedSig, body.productionAttributes)]; production namedSig :: NamedSignature = ns.namedSignature; @@ -73,7 +73,7 @@ top::AGDcl ::= 'aspect' 'production' id::QName ns::AspectProductionSignature bod newScopeEnv(prodAtts, top.env))); body.frame = aspectProductionContext(namedSig, myFlowGraph, sourceGrammar=sourceGrammar); -- graph from flow:env } action { - insert semantic token IdFnProd_t at id.location; + insert semantic token IdFnProd_t at id.nameLoc; sigNames = []; } @@ -85,7 +85,7 @@ top::AGDcl ::= 'aspect' 'function' id::QName ns::AspectFunctionSignature body::P top.defs := if null(body.productionAttributes) then [] - else [prodOccursDef(top.grammarName, id.location, namedSig, body.productionAttributes)]; + else [prodOccursDef(top.grammarName, id.nameLoc, namedSig, body.productionAttributes)]; production namedSig :: NamedSignature = ns.namedSignature; @@ -130,7 +130,7 @@ top::AGDcl ::= 'aspect' 'function' id::QName ns::AspectFunctionSignature body::P newScopeEnv(prodAtts, top.env))); body.frame = aspectFunctionContext(namedSig, myFlowGraph, sourceGrammar=sourceGrammar); -- graph from flow:env } action { - insert semantic token IdFnProd_t at id.location; + insert semantic token IdFnProd_t at id.nameLoc; sigNames = []; } @@ -158,7 +158,7 @@ concrete production aspectProductionLHSNone top::AspectProductionLHS ::= '_' { top.unparse = "_"; - forwards to aspectProductionLHSId(name("p_top", top.location), location=top.location); + forwards to aspectProductionLHSId(name("p_top")); } concrete production aspectProductionLHSId @@ -169,9 +169,9 @@ top::AspectProductionLHS ::= id::Name production attribute rType :: Type; rType = if null(top.realSignature) then errorType() else head(top.realSignature).typerep; - forwards to aspectProductionLHSFull(id, rType, location=top.location); + forwards to aspectProductionLHSFull(id, rType); } action { - insert semantic token IdSigNameDcl_t at id.location; + insert semantic token IdSigNameDcl_t at id.nameLoc; } concrete production aspectProductionLHSTyped @@ -182,9 +182,9 @@ top::AspectProductionLHS ::= id::Name '::' t::TypeExpr top.errors <- t.errors; - forwards to aspectProductionLHSFull(id, t.typerep, location=top.location); + forwards to aspectProductionLHSFull(id, t.typerep); } action { - insert semantic token IdSigNameDcl_t at id.location; + insert semantic token IdSigNameDcl_t at id.nameLoc; } abstract production aspectProductionLHSFull @@ -199,10 +199,10 @@ top::AspectProductionLHS ::= id::Name t::Type top.outputElement = namedSignatureElement(id.name, t); - top.defs := [aliasedLhsDef(top.grammarName, id.location, fName, performSubstitution(t, top.upSubst), id.name)]; + top.defs := [aliasedLhsDef(top.grammarName, id.nameLoc, fName, performSubstitution(t, top.upSubst), id.name)]; top.errors <- if length(getValueDclInScope(id.name, top.env)) > 1 - then [err(id.location, "Value '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(id, "Value '" ++ fName ++ "' is already bound.")] else []; } @@ -237,10 +237,7 @@ top::AspectRHSElem ::= '_' production attribute rType :: Type; rType = if null(top.realSignature) then errorType() else head(top.realSignature).typerep; - forwards to aspectRHSElemFull( - name("p_" ++ toString(top.deterministicCount), $1.location), - rType, - location=top.location); + forwards to aspectRHSElemFull(name("p_" ++ toString(top.deterministicCount)), rType); } concrete production aspectRHSElemId @@ -251,11 +248,11 @@ top::AspectRHSElem ::= id::Name production attribute rType :: Type; rType = if null(top.realSignature) then errorType() else head(top.realSignature).typerep; - top.errors <- [wrn(top.location, "Giving just a name '" ++ id.name ++ "' is deprecated in aspect signature. Please explicitly use a name and type.")]; + top.errors <- [wrnFromOrigin(top, "Giving just a name '" ++ id.name ++ "' is deprecated in aspect signature. Please explicitly use a name and type.")]; - forwards to aspectRHSElemFull(id, rType, location=top.location); + forwards to aspectRHSElemFull(id, rType); } action { - insert semantic token IdSigNameDcl_t at id.location; + insert semantic token IdSigNameDcl_t at id.nameLoc; } concrete production aspectRHSElemTyped @@ -266,9 +263,9 @@ top::AspectRHSElem ::= id::Name '::' t::TypeExpr top.errors <- t.errors; - forwards to aspectRHSElemFull(id, t.typerep, location=top.location); + forwards to aspectRHSElemFull(id, t.typerep); } action { - insert semantic token IdSigNameDcl_t at id.location; + insert semantic token IdSigNameDcl_t at id.nameLoc; } abstract production aspectRHSElemFull @@ -283,10 +280,10 @@ top::AspectRHSElem ::= id::Name t::Type top.inputElements = [namedSignatureElement(id.name, t)]; - top.defs := [aliasedChildDef(top.grammarName, id.location, fName, performSubstitution(t, top.upSubst), id.name)]; + top.defs := [aliasedChildDef(top.grammarName, id.nameLoc, fName, performSubstitution(t, top.upSubst), id.name)]; top.errors <- if length(getValueDclInScope(id.name, top.env)) > 1 - then [err(id.location, "Value '" ++ id.name ++ "' is already bound.")] + then [errFromOrigin(id, "Value '" ++ id.name ++ "' is already bound.")] else []; } @@ -322,5 +319,5 @@ top::AspectFunctionLHS ::= t::TypeExpr top.outputElement = namedSignatureElement(fName, t.typerep); -- TODO: this needs thinking. is it broken? maybe __return? or wait, it's doing that automatically isnt it... - top.defs := [aliasedLhsDef(top.grammarName, t.location, fName, performSubstitution(t.typerep, top.upSubst), fName)]; + top.defs := [aliasedLhsDef(top.grammarName, getParsedOriginLocationOrFallback(t), fName, performSubstitution(t.typerep, top.upSubst), fName)]; } diff --git a/grammars/silver/compiler/definition/core/AttributeDcl.sv b/grammars/silver/compiler/definition/core/AttributeDcl.sv index 36ac70eac..7ce9a0239 100644 --- a/grammars/silver/compiler/definition/core/AttributeDcl.sv +++ b/grammars/silver/compiler/definition/core/AttributeDcl.sv @@ -8,7 +8,7 @@ top::AGDcl ::= 'inherited' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te production attribute fName :: String; fName = top.grammarName ++ ":" ++ a.name; - top.defs := [inhDef(top.grammarName, a.location, fName, tl.freeVariables, te.typerep)]; + top.defs := [inhDef(top.grammarName, a.nameLoc, fName, tl.freeVariables, te.typerep)]; tl.initialEnv = top.env; tl.env = tl.envBindingTyVars; @@ -16,7 +16,7 @@ top::AGDcl ::= 'inherited' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te top.errors <- if length(getAttrDclAll(fName, top.env)) > 1 - then [err(a.location, "Attribute '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(a, "Attribute '" ++ fName ++ "' is already bound.")] else []; top.errors <- tl.errorsTyVars; @@ -30,7 +30,7 @@ top::AGDcl ::= 'synthesized' 'attribute' a::Name tl::BracketedOptTypeExprs '::' production attribute fName :: String; fName = top.grammarName ++ ":" ++ a.name; - top.defs := [synDef(top.grammarName, a.location, fName, tl.freeVariables, te.typerep)]; + top.defs := [synDef(top.grammarName, a.nameLoc, fName, tl.freeVariables, te.typerep)]; tl.initialEnv = top.env; tl.env = tl.envBindingTyVars; @@ -38,7 +38,7 @@ top::AGDcl ::= 'synthesized' 'attribute' a::Name tl::BracketedOptTypeExprs '::' top.errors <- if length(getAttrDclAll(fName, top.env)) > 1 - then [err(a.location, "Attribute '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(a, "Attribute '" ++ fName ++ "' is already bound.")] else []; top.errors <- tl.errorsTyVars; @@ -52,7 +52,7 @@ top::AGDcl ::= 'translation' 'attribute' a::Name tl::BracketedOptTypeExprs '::' production attribute fName :: String; fName = top.grammarName ++ ":" ++ a.name; - top.defs := [transDef(top.grammarName, a.location, fName, tl.freeVariables, te.typerep)]; + top.defs := [transDef(top.grammarName, a.nameLoc, fName, tl.freeVariables, te.typerep)]; tl.initialEnv = top.env; tl.env = tl.envBindingTyVars; @@ -60,7 +60,7 @@ top::AGDcl ::= 'translation' 'attribute' a::Name tl::BracketedOptTypeExprs '::' top.errors <- if length(getAttrDclAll(fName, top.env)) > 1 - then [err(a.location, "Attribute '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(a, "Attribute '" ++ fName ++ "' is already bound.")] else []; top.errors <- tl.errorsTyVars; diff --git a/grammars/silver/compiler/definition/core/ClassDcl.sv b/grammars/silver/compiler/definition/core/ClassDcl.sv index 1ef30993f..a83f16f09 100644 --- a/grammars/silver/compiler/definition/core/ClassDcl.sv +++ b/grammars/silver/compiler/definition/core/ClassDcl.sv @@ -16,12 +16,12 @@ top::AGDcl ::= 'class' cl::ConstraintList '=>' id::QNameType var::TypeExpr '{' b production supers::[Context] = cl.contexts; -- *Direct* super classes only, not transitive production boundVars::[TyVar] = [tv]; - top.defs := classDef(top.grammarName, id.location, fName, supers, tv, var.typerep.kindrep, body.classMembers) :: body.defs; + top.defs := classDef(top.grammarName, id.nameLoc, fName, supers, tv, var.typerep.kindrep, body.classMembers) :: body.defs; -- id *should* be just a Name, but it has to be a QNameType to avoid a reduce/reduce conflict top.errors <- if indexOf(":", id.name) == -1 then [] - else [err(id.location, "Class name must be unqualified.")]; + else [errFromOrigin(id, "Class name must be unqualified.")]; -- Here we ensure that the type is just a type *variable* top.errors <- var.errorsTyVars; @@ -29,17 +29,17 @@ top::AGDcl ::= 'class' cl::ConstraintList '=>' id::QNameType var::TypeExpr '{' b -- Redefinition check of the name top.errors <- if length(getTypeDclAll(fName, top.env)) > 1 - then [err(id.location, "Type '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(id, "Type '" ++ fName ++ "' is already bound.")] else []; top.errors <- if isLower(substring(0,1,id.name)) - then [err(id.location, "Types must be capitalized. Invalid class name " ++ id.name)] + then [errFromOrigin(id, "Types must be capitalized. Invalid class name " ++ id.name)] else []; top.errors <- if contains(fName, catMaybes(map((.contextClassName), transitiveSuperContexts(top.env, var.typerep, [], fName)))) - then [err(top.location, "Cycle exists in superclass relationships.")] + then [errFromOrigin(top, "Cycle exists in superclass relationships.")] else []; production attribute headPreDefs :: [Def] with ++; @@ -47,7 +47,7 @@ top::AGDcl ::= 'class' cl::ConstraintList '=>' id::QNameType var::TypeExpr '{' b production attribute headDefs :: [Def] with ++; headDefs := cl.defs; - headDefs <- [currentInstDef(top.grammarName, id.location, fName, var.typerep)]; + headDefs <- [currentInstDef(top.grammarName, id.nameLoc, fName, var.typerep)]; cl.constraintPos = classPos(fName, var.freeVariables); cl.env = newScopeEnv(headPreDefs, top.env); @@ -60,7 +60,7 @@ top::AGDcl ::= 'class' cl::ConstraintList '=>' id::QNameType var::TypeExpr '{' b body.classHead = instContext(fName, var.typerep); body.frameContexts = supers; } action { - insert semantic token IdTypeClassDcl_t at id.baseNameLoc; + insert semantic token IdTypeClassDcl_t at id.nameLoc; } concrete production typeClassDclNoCL @@ -68,19 +68,19 @@ top::AGDcl ::= 'class' id::QNameType var::TypeExpr '{' body::ClassBody '}' { top.unparse = s"class ${id.unparse} ${var.unparse}\n{\n${body.unparse}\n}"; - forwards to typeClassDcl($1, nilConstraint(location=top.location), '=>', id, var, $4, body, $6, location=top.location); + forwards to typeClassDcl($1, nilConstraint(), '=>', id, var, $4, body, $6); } action { - insert semantic token IdTypeClassDcl_t at id.baseNameLoc; + insert semantic token IdTypeClassDcl_t at id.nameLoc; } inherited attribute classHead::Context; inherited attribute constraintEnv::Env; inherited attribute frameContexts::[Context]; -- Only used for computing frame in members -nonterminal ClassBody with - config, grammarName, env, defs, location, unparse, errors, lexicalTypeVariables, lexicalTyVarKinds, classHead, constraintEnv, frameContexts, compiledGrammars, classMembers; -nonterminal ClassBodyItem with - config, grammarName, env, defs, location, unparse, errors, lexicalTypeVariables, lexicalTyVarKinds, classHead, constraintEnv, frameContexts, compiledGrammars, classMembers; +tracked nonterminal ClassBody with + config, grammarName, env, defs, unparse, errors, lexicalTypeVariables, lexicalTyVarKinds, classHead, constraintEnv, frameContexts, compiledGrammars, classMembers; +tracked nonterminal ClassBodyItem with + config, grammarName, env, defs, unparse, errors, lexicalTypeVariables, lexicalTyVarKinds, classHead, constraintEnv, frameContexts, compiledGrammars, classMembers; propagate config, grammarName, errors, lexicalTypeVariables, lexicalTyVarKinds, classHead, constraintEnv, frameContexts, compiledGrammars @@ -103,9 +103,9 @@ top::ClassBody ::= concrete production classBodyItem top::ClassBodyItem ::= id::Name '::' ty::TypeExpr ';' { - forwards to constraintClassBodyItem(id, $2, nilConstraint(location=top.location), '=>', ty, $4, location=top.location); + forwards to constraintClassBodyItem(id, $2, nilConstraint(), '=>', ty, $4); } action { - insert semantic token IdTypeClassMemberDcl_t at id.location; + insert semantic token IdTypeClassMemberDcl_t at id.nameLoc; } concrete production constraintClassBodyItem @@ -127,22 +127,22 @@ top::ClassBodyItem ::= id::Name '::' cl::ConstraintList '=>' ty::TypeExpr ';' ty.env = top.env; - top.defs := [classMemberDef(top.grammarName, top.location, fName, boundVars, top.classHead, cl.contexts, ty.typerep)]; + top.defs := [classMemberDef(top.grammarName, id.nameLoc, fName, boundVars, top.classHead, cl.contexts, ty.typerep)]; top.errors <- if length(getValueDclAll(fName, top.env)) > 1 - then [err(id.location, "Value '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(id, "Value '" ++ fName ++ "' is already bound.")] else []; } action { - insert semantic token IdTypeClassMemberDcl_t at id.location; + insert semantic token IdTypeClassMemberDcl_t at id.nameLoc; } concrete production defaultClassBodyItem top::ClassBodyItem ::= id::Name '::' ty::TypeExpr '=' e::Expr ';' { - forwards to defaultConstraintClassBodyItem(id, $2, nilConstraint(location=top.location), '=>', ty, $4, e, $6, location=top.location); + forwards to defaultConstraintClassBodyItem(id, $2, nilConstraint(), '=>', ty, $4, e, $6); } action { - insert semantic token IdTypeClassMemberDcl_t at id.location; + insert semantic token IdTypeClassMemberDcl_t at id.nameLoc; } concrete production defaultConstraintClassBodyItem @@ -176,14 +176,14 @@ top::ClassBodyItem ::= id::Name '::' cl::ConstraintList '=>' ty::TypeExpr '=' e: e.frame = globalExprContext(fName, foldContexts(top.frameContexts ++ cl.contexts), ty.typerep, myFlowGraph, sourceGrammar=top.grammarName); e.env = occursEnv(cl.occursDefs, newScopeEnv(cl.defs, top.env)); - top.defs := [classMemberDef(top.grammarName, top.location, fName, boundVars, top.classHead, cl.contexts, ty.typerep)]; + top.defs := [classMemberDef(top.grammarName, id.nameLoc, fName, boundVars, top.classHead, cl.contexts, ty.typerep)]; top.errors <- if length(getValueDclAll(fName, top.env)) > 1 - then [err(id.location, "Value '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(id, "Value '" ++ fName ++ "' is already bound.")] else []; } action { - insert semantic token IdTypeClassMemberDcl_t at id.location; + insert semantic token IdTypeClassMemberDcl_t at id.nameLoc; } -- TODO: Defaults diff --git a/grammars/silver/compiler/definition/core/DclInfo.sv b/grammars/silver/compiler/definition/core/DclInfo.sv index b7153079a..0f714696a 100644 --- a/grammars/silver/compiler/definition/core/DclInfo.sv +++ b/grammars/silver/compiler/definition/core/DclInfo.sv @@ -5,68 +5,68 @@ import silver:compiler:modification:copper only terminalIdReference; {-- - The production a variable reference should forward to for this type of value -} -synthesized attribute refDispatcher :: (Expr ::= Decorated! QName Location) occurs on ValueDclInfo; +synthesized attribute refDispatcher :: (Expr ::= Decorated! QName) occurs on ValueDclInfo; {-- - The production an "assignment" should forward to for this type of value -} -synthesized attribute defDispatcher :: (ProductionStmt ::= Decorated! QName Expr Location) occurs on ValueDclInfo; +synthesized attribute defDispatcher :: (ProductionStmt ::= Decorated! QName Expr) occurs on ValueDclInfo; {-- - The production an "equation" left hand side should forward to for this type of value (i.e. the 'x' in 'x.a = e') -} -synthesized attribute defLHSDispatcher :: (DefLHS ::= Decorated! QName Location) occurs on ValueDclInfo; +synthesized attribute defLHSDispatcher :: (DefLHS ::= Decorated! QName) occurs on ValueDclInfo; {-- - The production a translation attribute left hand side should forward to, for this type of value (i.e. the 'x.a' in 'x.a.b = e') -} -synthesized attribute transDefLHSDispatcher :: (DefLHS ::= Decorated! QName Decorated! QNameAttrOccur Location) occurs on ValueDclInfo; +synthesized attribute transDefLHSDispatcher :: (DefLHS ::= Decorated! QName Decorated! QNameAttrOccur) occurs on ValueDclInfo; {-- - The handler for 'x.a' for 'a', given that 'x' is DECORATED. - @see decoratedAccessHandler production for where this is used -} -synthesized attribute decoratedAccessHandler :: (Expr ::= Decorated! Expr Decorated! QNameAttrOccur Location) occurs on AttributeDclInfo; +synthesized attribute decoratedAccessHandler :: (Expr ::= Decorated! Expr Decorated! QNameAttrOccur) occurs on AttributeDclInfo; {-- - The handler for 'x.a' for 'a', given that 'x' is UNdecorated. - @see undecoratedAccessHandler production for where this is used -} -synthesized attribute undecoratedAccessHandler :: (Expr ::= Decorated! Expr Decorated! QNameAttrOccur Location) occurs on AttributeDclInfo; +synthesized attribute undecoratedAccessHandler :: (Expr ::= Decorated! Expr Decorated! QNameAttrOccur) occurs on AttributeDclInfo; {-- - The handler for 'x.a' for 'a', given that 'x' is data. - @see dataAccessHandler production for where this is used -} -synthesized attribute dataAccessHandler :: (Expr ::= Decorated! Expr Decorated! QNameAttrOccur Location) occurs on AttributeDclInfo; +synthesized attribute dataAccessHandler :: (Expr ::= Decorated! Expr Decorated! QNameAttrOccur) occurs on AttributeDclInfo; {-- - The production an "equation" should forward to for this type of attribute (i.e. the 'a' in 'x.a = e') -} -synthesized attribute attrDefDispatcher :: (ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr Location) occurs on AttributeDclInfo; +synthesized attribute attrDefDispatcher :: (ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr) occurs on AttributeDclInfo; {-- - The production an "occurs on" decl should forward to for this type of attribute (for extension use, defaultAttributionDcl for all syn/inh attrs.) -} -synthesized attribute attributionDispatcher :: (AGDcl ::= Decorated! QName BracketedOptTypeExprs QName BracketedOptTypeExprs Location) occurs on AttributeDclInfo; +synthesized attribute attributionDispatcher :: (AGDcl ::= Decorated! QName BracketedOptTypeExprs QName BracketedOptTypeExprs) occurs on AttributeDclInfo; -- -- non-interface values aspect production childDcl top::ValueDclInfo ::= fn::String ty::Type { - top.refDispatcher = childReference(_, location=_); - top.defDispatcher = errorValueDef(_, _, location=_); -- TODO: we should be smarted about error messages, and mention its a child - top.defLHSDispatcher = childDefLHS(_, location=_); - top.transDefLHSDispatcher = childTransAttrDefLHS(_, _, location=_); + top.refDispatcher = childReference; + top.defDispatcher = errorValueDef; -- TODO: we should be smarted about error messages, and mention its a child + top.defLHSDispatcher = childDefLHS; + top.transDefLHSDispatcher = childTransAttrDefLHS; } aspect production lhsDcl top::ValueDclInfo ::= fn::String ty::Type { - top.refDispatcher = lhsReference(_, location=_); - top.defDispatcher = errorValueDef(_, _, location=_); -- TODO: be smarter about the error message - top.defLHSDispatcher = lhsDefLHS(_, location=_); - top.transDefLHSDispatcher = errorTransAttrDefLHS(_, _, location=_); + top.refDispatcher = lhsReference; + top.defDispatcher = errorValueDef; -- TODO: be smarter about the error message + top.defLHSDispatcher = lhsDefLHS; + top.transDefLHSDispatcher = errorTransAttrDefLHS; } aspect production localDcl top::ValueDclInfo ::= fn::String ty::Type _ { - top.refDispatcher = localReference(_, location=_); - top.defDispatcher = localValueDef(_, _, location=_); - top.defLHSDispatcher = localDefLHS(_, location=_); - top.transDefLHSDispatcher = localTransAttrDefLHS(_, _, location=_); + top.refDispatcher = localReference; + top.defDispatcher = localValueDef; + top.defLHSDispatcher = localDefLHS; + top.transDefLHSDispatcher = localTransAttrDefLHS; } @@ -74,92 +74,92 @@ top::ValueDclInfo ::= fn::String ty::Type _ aspect production prodDcl top::ValueDclInfo ::= ns::NamedSignature hasForward::Boolean { - top.refDispatcher = productionReference(_, location=_); + top.refDispatcher = productionReference; -- Note that we still need production references, even though bug #16 removes the production type. - top.defDispatcher = errorValueDef(_, _, location=_); - top.defLHSDispatcher = errorDefLHS(_, location=_); - top.transDefLHSDispatcher = errorTransAttrDefLHS(_, _, location=_); + top.defDispatcher = errorValueDef; + top.defLHSDispatcher = errorDefLHS; + top.transDefLHSDispatcher = errorTransAttrDefLHS; } aspect production funDcl top::ValueDclInfo ::= ns::NamedSignature { - top.refDispatcher = functionReference(_, location=_); - top.defDispatcher = errorValueDef(_, _, location=_); - top.defLHSDispatcher = errorDefLHS(_, location=_); - top.transDefLHSDispatcher = errorTransAttrDefLHS(_, _, location=_); + top.refDispatcher = functionReference; + top.defDispatcher = errorValueDef; + top.defLHSDispatcher = errorDefLHS; + top.transDefLHSDispatcher = errorTransAttrDefLHS; } aspect production globalValueDcl top::ValueDclInfo ::= fn::String bound::[TyVar] contexts::[Context] ty::Type { - top.refDispatcher = globalValueReference(_, location=_); - top.defDispatcher = errorValueDef(_, _, location=_); - top.defLHSDispatcher = errorDefLHS(_, location=_); - top.transDefLHSDispatcher = errorTransAttrDefLHS(_, _, location=_); + top.refDispatcher = globalValueReference; + top.defDispatcher = errorValueDef; + top.defLHSDispatcher = errorDefLHS; + top.transDefLHSDispatcher = errorTransAttrDefLHS; } aspect production classMemberDcl top::ValueDclInfo ::= fn::String bound::[TyVar] head::Context contexts::[Context] ty::Type { - top.refDispatcher = classMemberReference(_, location=_); - top.defDispatcher = errorValueDef(_, _, location=_); - top.defLHSDispatcher = errorDefLHS(_, location=_); - top.transDefLHSDispatcher = errorTransAttrDefLHS(_, _, location=_); + top.refDispatcher = classMemberReference; + top.defDispatcher = errorValueDef; + top.defLHSDispatcher = errorDefLHS; + top.transDefLHSDispatcher = errorTransAttrDefLHS; } -- -- interface Production attr (values) aspect production forwardDcl top::ValueDclInfo ::= ty::Type { - top.refDispatcher = forwardReference(_, location=_); - top.defDispatcher = errorValueDef(_, _, location=_); -- TODO: better error message - top.defLHSDispatcher = forwardDefLHS(_, location=_); - top.transDefLHSDispatcher = errorTransAttrDefLHS(_, _, location=_); + top.refDispatcher = forwardReference; + top.defDispatcher = errorValueDef; -- TODO: better error message + top.defLHSDispatcher = forwardDefLHS; + top.transDefLHSDispatcher = errorTransAttrDefLHS; } aspect production termIdDcl top::ValueDclInfo ::= fn::String { - top.refDispatcher = terminalIdReference(_, location=_); - top.defDispatcher = errorValueDef(_, _, location=_); - top.defLHSDispatcher = errorDefLHS(_, location=_); - top.transDefLHSDispatcher = errorTransAttrDefLHS(_, _, location=_); + top.refDispatcher = terminalIdReference; + top.defDispatcher = errorValueDef; + top.defLHSDispatcher = errorDefLHS; + top.transDefLHSDispatcher = errorTransAttrDefLHS; } -- -- interface Attributes aspect production synDcl top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type { - top.decoratedAccessHandler = synDecoratedAccessHandler(_, _, location=_); - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _, location=_), _, _, _); - top.dataAccessHandler = synDataAccessHandler(_, _, location=_); - top.attrDefDispatcher = synthesizedAttributeDef(_, _, _, location=_); - top.attributionDispatcher = defaultAttributionDcl(_, _, _, _, location=_); + top.decoratedAccessHandler = synDecoratedAccessHandler; + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); + top.dataAccessHandler = synDataAccessHandler; + top.attrDefDispatcher = synthesizedAttributeDef; + top.attributionDispatcher = defaultAttributionDcl; } aspect production inhDcl top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type { - top.decoratedAccessHandler = inhDecoratedAccessHandler(_, _, location=_); - top.undecoratedAccessHandler = inhUndecoratedAccessErrorHandler(_, _, location=_); - top.dataAccessHandler = inhUndecoratedAccessErrorHandler(_, _, location=_); - top.attrDefDispatcher = inheritedAttributeDef(_, _, _, location=_); - top.attributionDispatcher = defaultAttributionDcl(_, _, _, _, location=_); + top.decoratedAccessHandler = inhDecoratedAccessHandler; + top.undecoratedAccessHandler = inhUndecoratedAccessErrorHandler; + top.dataAccessHandler = inhUndecoratedAccessErrorHandler; + top.attrDefDispatcher = inheritedAttributeDef; + top.attributionDispatcher = defaultAttributionDcl; } aspect production transDcl top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type { - top.decoratedAccessHandler = transDecoratedAccessHandler(_, _, location=_); - top.undecoratedAccessHandler = transUndecoratedAccessErrorHandler(_, _, location=_); - top.dataAccessHandler = transUndecoratedAccessErrorHandler(_, _, location=_); - top.attrDefDispatcher = synthesizedAttributeDef(_, _, _, location=_); - top.attributionDispatcher = defaultAttributionDcl(_, _, _, _, location=_); + top.decoratedAccessHandler = transDecoratedAccessHandler; + top.undecoratedAccessHandler = transUndecoratedAccessErrorHandler; + top.dataAccessHandler = transUndecoratedAccessErrorHandler; + top.attrDefDispatcher = synthesizedAttributeDef; + top.attributionDispatcher = defaultAttributionDcl; } aspect production annoDcl top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type { - top.decoratedAccessHandler = accessBounceUndecorate(annoAccessHandler(_, _, location=_), _, _, _); - top.undecoratedAccessHandler = annoAccessHandler(_, _, location=_); - top.dataAccessHandler = annoAccessHandler(_, _, location=_); + top.decoratedAccessHandler = accessBounceUndecorate(annoAccessHandler, _, _); + top.undecoratedAccessHandler = annoAccessHandler; + top.dataAccessHandler = annoAccessHandler; top.attrDefDispatcher = - \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr l::Location -> - errorAttributeDef([err(l, "Annotations are not defined as equations within productions")], dl, attr, e, location=l); - top.attributionDispatcher = defaultAttributionDcl(_, _, _, _, location=_); + \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr -> + errorAttributeDef([errFromOrigin(ambientOrigin(), "Annotations are not defined as equations within productions")], dl, attr, e); + top.attributionDispatcher = defaultAttributionDcl; } \ No newline at end of file diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index c3f8a5743..b128c5d0d 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -3,17 +3,17 @@ grammar silver:compiler:definition:core; --import silver:compiler:analysis:typechecking:core; import silver:util:treeset as ts; -nonterminal Expr with - config, grammarName, env, location, unparse, errors, freeVars, frame, compiledGrammars, typerep, isRoot, originRules; -nonterminal Exprs with - config, grammarName, env, location, unparse, errors, freeVars, frame, compiledGrammars, exprs, rawExprs, originRules; - -nonterminal ExprInhs with - config, grammarName, env, location, unparse, errors, freeVars, frame, compiledGrammars, decoratingnt, suppliedInhs, allSuppliedInhs, originRules; -nonterminal ExprInh with - config, grammarName, env, location, unparse, errors, freeVars, frame, compiledGrammars, decoratingnt, suppliedInhs, allSuppliedInhs, originRules; -nonterminal ExprLHSExpr with - config, grammarName, env, location, unparse, errors, freeVars, frame, name, typerep, decoratingnt, suppliedInhs, allSuppliedInhs, originRules; +tracked nonterminal Expr with + config, grammarName, env, unparse, errors, freeVars, frame, compiledGrammars, typerep, isRoot, originRules; +tracked nonterminal Exprs with + config, grammarName, env, unparse, errors, freeVars, frame, compiledGrammars, exprs, rawExprs, originRules; + +tracked nonterminal ExprInhs with + config, grammarName, env, unparse, errors, freeVars, frame, compiledGrammars, decoratingnt, suppliedInhs, allSuppliedInhs, originRules; +tracked nonterminal ExprInh with + config, grammarName, env, unparse, errors, freeVars, frame, compiledGrammars, decoratingnt, suppliedInhs, allSuppliedInhs, originRules; +tracked nonterminal ExprLHSExpr with + config, grammarName, env, unparse, errors, freeVars, frame, name, typerep, decoratingnt, suppliedInhs, allSuppliedInhs, originRules; flowtype unparse {} on Expr, Exprs, ExprInhs, ExprInh, ExprLHSExpr; flowtype freeVars {frame} on Expr, Exprs, ExprInhs, ExprInh, ExprLHSExpr; @@ -89,19 +89,19 @@ top::Expr ::= q::QName top.freeVars := ts:fromList([q.name]); propagate env; - forwards to (if null(q.lookupValue.dcls) - then errorReference(q.lookupValue.errors, _, location=_) - else q.lookupValue.dcl.refDispatcher)(q, top.location); + forwards to if null(q.lookupValue.dcls) + then errorReference(q.lookupValue.errors, q) + else q.lookupValue.dcl.refDispatcher(q); } action { if (contains(q.name, sigNames)) { - insert semantic token IdSigName_t at q.baseNameLoc; + insert semantic token IdSigName_t at q.nameLoc; } } abstract production errorReference top::Expr ::= msg::[Message] q::Decorated! QName { - undecorates to errorExpr(msg, location=top.location); -- TODO: Should this be baseExpr? + undecorates to errorExpr(msg); -- TODO: Should this be baseExpr? top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); @@ -113,7 +113,7 @@ top::Expr ::= msg::[Message] q::Decorated! QName abstract production childReference top::Expr ::= q::Decorated! QName { - undecorates to baseExpr(q, location=top.location); + undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); @@ -125,7 +125,7 @@ top::Expr ::= q::Decorated! QName abstract production lhsReference top::Expr ::= q::Decorated! QName { - undecorates to baseExpr(q, location=top.location); + undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); @@ -136,7 +136,7 @@ top::Expr ::= q::Decorated! QName abstract production localReference top::Expr ::= q::Decorated! QName { - undecorates to baseExpr(q, location=top.location); + undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); @@ -148,7 +148,7 @@ top::Expr ::= q::Decorated! QName abstract production forwardReference top::Expr ::= q::Decorated! QName { - undecorates to baseExpr(q, location=top.location); + undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); @@ -162,7 +162,7 @@ top::Expr ::= q::Decorated! QName abstract production productionReference top::Expr ::= q::Decorated! QName { - undecorates to baseExpr(q, location=top.location); + undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); @@ -181,7 +181,7 @@ top::Expr ::= q::Decorated! QName abstract production functionReference top::Expr ::= q::Decorated! QName { - undecorates to baseExpr(q, location=top.location); + undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); @@ -200,7 +200,7 @@ top::Expr ::= q::Decorated! QName abstract production classMemberReference top::Expr ::= q::Decorated! QName { - undecorates to baseExpr(q, location=top.location); + undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); @@ -232,7 +232,7 @@ top::Expr ::= q::Decorated! QName abstract production globalValueReference top::Expr ::= q::Decorated! QName { - undecorates to baseExpr(q, location=top.location); + undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); @@ -258,7 +258,7 @@ top::Expr ::= q::'forward' -- TODO: we're forwarding to baseExpr just to decorate the tree we create. -- That's a bit weird. - forwards to baseExpr(qName(q.location, "forward"), location=top.location); + forwards to baseExpr(qName("forward")); } concrete production application @@ -289,41 +289,41 @@ top::Expr ::= e::Expr '(' es::AppExprs ',' anns::AnnoAppExprs ')' if !t.isApplicable then [] else if length(t.inputTypes) > es.appExprSize - then [err(top.location, "Too few arguments provided to function '" ++ e.unparse ++ "'")] + then [errFromOrigin(top, "Too few arguments provided to function '" ++ e.unparse ++ "'")] else if length(t.inputTypes) < es.appExprSize - then [err(top.location, "Too many arguments provided to function '" ++ e.unparse ++ "'")] + then [errFromOrigin(top, "Too many arguments provided to function '" ++ e.unparse ++ "'")] else []; -- TODO: You know, since the rule is we can't access .typerep without "first" supplying -- .downSubst, perhaps we should just... report .typerep after substitution in the first place! - forwards to t.applicationDispatcher(e, es, anns, top.location); + forwards to t.applicationDispatcher(e, es, anns); } concrete production applicationAnno top::Expr ::= e::Expr '(' anns::AnnoAppExprs ')' { - forwards to application(e, $2, emptyAppExprs(location=$2.location), ',', anns, $4, location=top.location); + forwards to application(e, $2, emptyAppExprs(), ',', anns, $4); } concrete production applicationExpr top::Expr ::= e::Expr '(' es::AppExprs ')' { - forwards to application(e, $2, es, ',', emptyAnnoAppExprs(location=$4.location), $4, location=top.location); + forwards to application(e, $2, es, ',', emptyAnnoAppExprs(), $4); } concrete production applicationEmpty top::Expr ::= e::Expr '(' ')' { - forwards to application(e, $2, emptyAppExprs(location=$2.location), ',', emptyAnnoAppExprs(location=$3.location), $3, location=top.location); + forwards to application(e, $2, emptyAppExprs(), ',', emptyAnnoAppExprs(), $3); } abstract production errorApplication top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs { - undecorates to application(e, '(', es, ',', anns, ')', location=top.location); + undecorates to application(e, '(', es, ',', anns, ')'); top.unparse = e.unparse ++ "(" ++ es.unparse ++ "," ++ anns.unparse ++ ")"; top.errors <- if e.typerep.isError then [] else - [err(top.location, e.unparse ++ " has type " ++ prettyType(performSubstitution(e.typerep, e.upSubst)) ++ + [errFromOrigin(top, e.unparse ++ " has type " ++ prettyType(performSubstitution(e.typerep, e.upSubst)) ++ " and cannot be invoked as a function.")]; -- TODO This error message is cumbersomely generated... @@ -336,20 +336,20 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp abstract production functionApplication top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs { - undecorates to application(e, '(', es, ',', anns, ')', location=top.location); + undecorates to application(e, '(', es, ',', anns, ')'); top.unparse = e.unparse ++ "(" ++ es.unparse ++ "," ++ anns.unparse ++ ")"; top.freeVars := e.freeVars ++ es.freeVars ++ anns.freeVars; forwards to (if es.isPartial || anns.isPartial then partialApplication - else functionInvocation)(e, es, anns, location=top.location); + else functionInvocation)(e, es, anns); } abstract production functionInvocation top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs { - undecorates to application(e, '(', es, ',', anns, ')', location=top.location); + undecorates to application(e, '(', es, ',', anns, ')'); top.unparse = e.unparse ++ "(" ++ es.unparse ++ "," ++ anns.unparse ++ ")"; local ety :: Type = performSubstitution(e.typerep, e.upSubst); @@ -360,7 +360,7 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp abstract production partialApplication top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs { - undecorates to application(e, '(', es, ',', anns, ')', location=top.location); + undecorates to application(e, '(', es, ',', anns, ')'); top.unparse = e.unparse ++ "(" ++ es.unparse ++ "," ++ anns.unparse ++ ")"; local ety :: Type = performSubstitution(e.typerep, e.upSubst); @@ -406,7 +406,7 @@ top::Expr ::= e::Expr '.' q::QNameAttrOccur q.attrFor = if eTy.isDecorated then eTy.decoratedType else eTy; -- Note: we're first consulting the TYPE of the LHS. - forwards to eTy.accessHandler(e, q, top.location); + forwards to eTy.accessHandler(e, q); -- This jumps to: -- errorAccessHandler (e.g. 1.unparse) -- undecoratedAccessHandler @@ -418,7 +418,7 @@ top::Expr ::= e::Expr '.' q::QNameAttrOccur abstract production errorAccessHandler top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur { - undecorates to access(e, '.', q, location=top.location); + undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; top.typerep = errorType(); @@ -427,14 +427,14 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur if e.typerep.isError then [] else let ref :: String = if length(e.unparse) < 12 then "'" ++ e.unparse ++ "' has" else "LHS of '.' is" - in [err(top.location, ref ++ " type " ++ prettyType(q.attrFor) ++ " and cannot have attributes.")] + in [errFromOrigin(top, ref ++ " type " ++ prettyType(q.attrFor) ++ " and cannot have attributes.")] end; } abstract production terminalAccessHandler top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur { - undecorates to access(e, '.', q, location=top.location); + undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; -- NO use of q.errors, as that become nonsensical here. @@ -444,7 +444,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur if q.name == "lexeme" || q.name == "location" || q.name == "filename" || q.name == "line" || q.name == "column" then [] - else [err(q.location, q.name ++ " is not a terminal attribute")]; + else [errFromOrigin(q, q.name ++ " is not a terminal attribute")]; top.typerep = if q.name == "lexeme" || q.name == "filename" @@ -459,12 +459,12 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur abstract production undecoratedAccessHandler top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur { - undecorates to access(e, '.', q, location=top.location); + undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; -- Note: LHS is UNdecorated, here we dispatch based on the kind of attribute. - forwards to (if !q.found then unknownDclAccessHandler(_, _, location=_) - else q.attrDcl.undecoratedAccessHandler)(e, q, top.location); + forwards to if !q.found then unknownDclAccessHandler(e, q) + else q.attrDcl.undecoratedAccessHandler(e, q); -- annoAccessHandler -- accessBouncer -- transUndecoratedAccessErrorHandler @@ -474,12 +474,12 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur abstract production dataAccessHandler top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur { - undecorates to access(e, '.', q, location=top.location); + undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; -- Note: LHS is data, here we dispatch based on the kind of attribute. - forwards to (if !q.found then unknownDclAccessHandler(_, _, location=_) - else q.attrDcl.dataAccessHandler)(e, q, top.location); + forwards to if !q.found then unknownDclAccessHandler(e, q) + else q.attrDcl.dataAccessHandler(e, q); -- annoAccessHandler -- synDataAccessHandler -- unknownDclAccessHandler -- unknown attribute error raised already. @@ -490,45 +490,43 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur - This production is intended to permit that. -} abstract production accessBouncer -top::Expr ::= target::(Expr ::= Decorated! Expr Decorated! QNameAttrOccur Location) e::Expr q::Decorated! QNameAttrOccur +top::Expr ::= target::(Expr ::= Decorated! Expr Decorated! QNameAttrOccur) e::Expr q::Decorated! QNameAttrOccur { - undecorates to access(e, '.', q, location=top.location); + undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; propagate config, grammarName, env, freeVars, frame, originRules, compiledGrammars; e.isRoot = false; -- Basically the only purpose here is to decorate 'e'. - forwards to target(e, q, top.location); + forwards to target(e, q); } function accessBounceDecorate -Expr ::= target::(Expr ::= Decorated! Expr Decorated! QNameAttrOccur Location) e::Decorated! Expr q::Decorated! QNameAttrOccur loc::Location +Expr ::= target::(Expr ::= Decorated! Expr Decorated! QNameAttrOccur) e::Decorated! Expr q::Decorated! QNameAttrOccur { - return accessBouncer(target, decorateExprWithEmpty('decorate', @e, 'with', '{', '}', location=loc), q, location=loc); + return accessBouncer(target, decorateExprWithEmpty('decorate', @e, 'with', '{', '}'), q); } -- Note that this performs the access on the term that was originally decorated, rather than properly undecorating. function accessBounceUndecorate -Expr ::= target::(Expr ::= Decorated! Expr Decorated! QNameAttrOccur Location) e::Decorated! Expr q::Decorated! QNameAttrOccur loc::Location +Expr ::= target::(Expr ::= Decorated! Expr Decorated! QNameAttrOccur) e::Decorated! Expr q::Decorated! QNameAttrOccur { return accessBouncer(target, application( - baseExpr(qName(loc, "silver:core:getTermThatWasDecorated"), location=loc), '(', + baseExpr(qName("silver:core:getTermThatWasDecorated")), '(', oneAppExprs( - presentAppExpr(@e, location=loc), - location=loc), ',', - emptyAnnoAppExprs(location=loc), ')', - location=loc), - q, location=loc); + presentAppExpr(@e)), ',', + emptyAnnoAppExprs(), ')'), + q); } abstract production decoratedAccessHandler top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur { - undecorates to access(e, '.', q, location=top.location); + undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; -- Note: LHS is decorated, here we dispatch based on the kind of attribute. - forwards to (if !q.found then unknownDclAccessHandler(_, _, location=_) - else q.attrDcl.decoratedAccessHandler)(e, q, top.location); + forwards to if !q.found then unknownDclAccessHandler(e, q) + else q.attrDcl.decoratedAccessHandler(e, q); -- From here we go to: -- synDecoratedAccessHandler -- inhDecoratedAccessHandler @@ -538,7 +536,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur abstract production synDecoratedAccessHandler top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur { - undecorates to access(e, '.', q, location=top.location); + undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; top.typerep = q.typerep; @@ -547,7 +545,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur abstract production inhDecoratedAccessHandler top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur { - undecorates to access(e, '.', q, location=top.location); + undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; top.typerep = q.typerep; @@ -556,7 +554,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur abstract production transDecoratedAccessHandler top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur { - undecorates to access(e, '.', q, location=top.location); + undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; top.typerep = q.typerep.asNtOrDecType; @@ -565,7 +563,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur abstract production annoAccessHandler top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur { - undecorates to access(e, '.', q, location=top.location); + undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; production index :: Integer = @@ -577,7 +575,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur abstract production synDataAccessHandler top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur { - undecorates to access(e, '.', q, location=top.location); + undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; top.typerep = q.typerep; @@ -586,29 +584,29 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur abstract production inhUndecoratedAccessErrorHandler top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur { - undecorates to access(e, '.', q, location=top.location); + undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; top.typerep = q.typerep.asNtOrDecType; - top.errors <- [err(top.location, s"Cannot access inherited attribute ${q.attrDcl.fullName} from an undecorated type")]; + top.errors <- [errFromOrigin(top, s"Cannot access inherited attribute ${q.attrDcl.fullName} from an undecorated type")]; } abstract production transUndecoratedAccessErrorHandler top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur { - undecorates to access(e, '.', q, location=top.location); + undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; top.typerep = q.typerep.asNtOrDecType; - top.errors <- [err(top.location, s"Cannot access translation attribute ${q.attrDcl.fullName} from an undecorated type")]; + top.errors <- [errFromOrigin(top, s"Cannot access translation attribute ${q.attrDcl.fullName} from an undecorated type")]; } abstract production unknownDclAccessHandler top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur { - undecorates to access(e, '.', q, location=top.location); + undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; top.typerep = errorType(); @@ -620,7 +618,7 @@ top::Expr ::= 'decorate' e::Expr 'with' '{' '}' { top.unparse = "decorate " ++ e.unparse ++ " with {}"; - forwards to decorateExprWith($1, @e, $3, $4, exprInhsEmpty(location=top.location), $5, location=top.location); + forwards to decorateExprWith($1, @e, $3, $4, exprInhsEmpty(), $5); } concrete production decorateExprWith @@ -748,15 +746,7 @@ top::Expr ::= e1::Expr op::'>' e2::Expr { top.unparse = e1.unparse ++ " > " ++ e2.unparse; - forwards to - -- silver:core:gt(e1, e2) - applicationExpr( - baseExpr(qName(op.location, "silver:core:gt"), location=op.location), '(', - snocAppExprs( - oneAppExprs(presentAppExpr(e1, location=top.location), location=top.location), ',', - presentAppExpr(e2, location=top.location), - location=top.location),')', - location=top.location); + forwards to Silver_Expr { silver:core:gt($Expr{e1}, $Expr{e2}) }; } concrete production ltOp @@ -764,15 +754,7 @@ top::Expr ::= e1::Expr op::'<' e2::Expr { top.unparse = e1.unparse ++ " < " ++ e2.unparse; - forwards to - -- silver:core:lt(e1, e2) - applicationExpr( - baseExpr(qName(op.location, "silver:core:lt"), location=op.location), '(', - snocAppExprs( - oneAppExprs(presentAppExpr(e1, location=top.location), location=top.location), ',', - presentAppExpr(e2, location=top.location), - location=top.location),')', - location=top.location); + forwards to Silver_Expr { silver:core:lt($Expr{e1}, $Expr{e2}) }; } concrete production gteOp @@ -780,15 +762,7 @@ top::Expr ::= e1::Expr op::'>=' e2::Expr { top.unparse = e1.unparse ++ " >= " ++ e2.unparse; - forwards to - -- silver:core:gte(e1, e2) - applicationExpr( - baseExpr(qName(op.location, "silver:core:gte"), location=op.location), '(', - snocAppExprs( - oneAppExprs(presentAppExpr(e1, location=top.location), location=top.location), ',', - presentAppExpr(e2, location=top.location), - location=top.location),')', - location=top.location); + forwards to Silver_Expr { silver:core:gte($Expr{e1}, $Expr{e2}) }; } concrete production lteOp @@ -796,15 +770,7 @@ top::Expr ::= e1::Expr op::'<=' e2::Expr { top.unparse = e1.unparse ++ " <= " ++ e2.unparse; - forwards to - -- silver:core:lte(e1, e2) - applicationExpr( - baseExpr(qName(op.location, "silver:core:lte"), location=op.location), '(', - snocAppExprs( - oneAppExprs(presentAppExpr(e1, location=top.location), location=top.location), ',', - presentAppExpr(e2, location=top.location), - location=top.location),')', - location=top.location); + forwards to Silver_Expr { silver:core:lte($Expr{e1}, $Expr{e2}) }; } concrete production eqOp @@ -812,15 +778,7 @@ top::Expr ::= e1::Expr op::'==' e2::Expr { top.unparse = e1.unparse ++ " == " ++ e2.unparse; - forwards to - -- silver:core:eq(e1, e2) - applicationExpr( - baseExpr(qName(op.location, "silver:core:eq"), location=op.location), '(', - snocAppExprs( - oneAppExprs(presentAppExpr(e1, location=top.location), location=top.location), ',', - presentAppExpr(e2, location=top.location), - location=top.location),')', - location=top.location); + forwards to Silver_Expr { silver:core:eq($Expr{e1}, $Expr{e2}) }; } concrete production neqOp @@ -828,15 +786,7 @@ top::Expr ::= e1::Expr op::'!=' e2::Expr { top.unparse = e1.unparse ++ " != " ++ e2.unparse; - forwards to - -- silver:core:neq(e1, e2) - applicationExpr( - baseExpr(qName(op.location, "silver:core:neq"), location=op.location), '(', - snocAppExprs( - oneAppExprs(presentAppExpr(e1, location=top.location), location=top.location), ',', - presentAppExpr(e2, location=top.location), - location=top.location),')', - location=top.location); + forwards to Silver_Expr { silver:core:neq($Expr{e1}, $Expr{e2}) }; } concrete production ifThenElse @@ -947,15 +897,7 @@ top::Expr ::= e1::Expr op::'++' e2::Expr { top.unparse = e1.unparse ++ " ++ " ++ e2.unparse; - forwards to - -- silver:core:append(e1, e2) - applicationExpr( - baseExpr(qName(op.location, "silver:core:append"), location=op.location), '(', - snocAppExprs( - oneAppExprs(presentAppExpr(e1, location=top.location), location=top.location), ',', - presentAppExpr(e2, location=top.location), - location=top.location),')', - location=top.location); + forwards to Silver_Expr { silver:core:append($Expr{e1}, $Expr{e2}) }; } concrete production terminalConstructor @@ -975,12 +917,12 @@ top::Expr ::= 'terminal' '(' t::TypeExpr ',' e::Expr ')' -- So, *maybe* this is deprecated? But let's not complain for now, because -- it's too widely used. - --top.errors <- [wrn(t.location, "terminal(type,lexeme) is deprecated. Use terminal(type,lexeme,location) instead.")]; + --top.errors <- [wrnFromOrigin(t, "terminal(type,lexeme) is deprecated. Use terminal(type,lexeme,location) instead.")]; local bogus :: Expr = mkStrFunctionInvocation($6.location, "silver:core:bogusLoc", []); - forwards to terminalConstructor($1, $2, t, $4, e, ',', bogus, $6, location=top.location); + forwards to terminalConstructor($1, $2, t, $4, e, ',', bogus, $6); } -- These sorta seem obsolete, but there are some important differences from AppExprs. @@ -1020,8 +962,8 @@ top::Exprs ::= e1::Expr ',' e2::Exprs - Exprs with optional underscores omitting parameters. Used exclusively for - (partial) function application. -} -nonterminal AppExprs with - config, grammarName, env, location, unparse, errors, freeVars, frame, compiledGrammars, exprs, rawExprs, +tracked nonterminal AppExprs with + config, grammarName, env, unparse, errors, freeVars, frame, compiledGrammars, exprs, rawExprs, isPartial, missingTypereps, appExprIndicies, appExprSize, appExprTypereps, appExprApplied, originRules; flowtype AppExprs = decorate { @@ -1029,8 +971,8 @@ flowtype AppExprs = downSubst, finalSubst, flowEnv }; -nonterminal AppExpr with - config, grammarName, env, location, unparse, errors, freeVars, frame, compiledGrammars, exprs, rawExprs, +tracked nonterminal AppExpr with + config, grammarName, env, unparse, errors, freeVars, frame, compiledGrammars, exprs, rawExprs, isPartial, missingTypereps, appExprIndicies, appExprIndex, appExprTyperep, appExprApplied, originRules; propagate config, grammarName, env, freeVars, frame, compiledGrammars, errors, originRules on AppExprs, AppExpr; @@ -1121,17 +1063,17 @@ top::AppExprs ::= -- Assumption: We only get here when we're looking at () -- i.e. we can't ever have 'too many' provided error top.errors <- if null(top.appExprTypereps) then [] - else [err(top.location, "Too few arguments provided to function '" ++ top.appExprApplied ++ "'")]; + else [errFromOrigin(top, "Too few arguments provided to function '" ++ top.appExprApplied ++ "'")]; } -nonterminal AnnoAppExprs with - config, grammarName, env, location, unparse, errors, freeVars, frame, compiledGrammars, +tracked nonterminal AnnoAppExprs with + config, grammarName, env, unparse, errors, freeVars, frame, compiledGrammars, isPartial, appExprApplied, exprs, remainingFuncAnnotations, funcAnnotations, missingAnnotations, partialAnnoTypereps, annoIndexConverted, annoIndexSupplied, originRules; -nonterminal AnnoExpr with - config, grammarName, env, location, unparse, errors, freeVars, frame, compiledGrammars, +tracked nonterminal AnnoExpr with + config, grammarName, env, unparse, errors, freeVars, frame, compiledGrammars, isPartial, appExprApplied, exprs, remainingFuncAnnotations, funcAnnotations, missingAnnotations, partialAnnoTypereps, annoIndexConverted, annoIndexSupplied, originRules; @@ -1181,7 +1123,7 @@ top::AnnoExpr ::= qn::QName '=' e::AppExpr top.errors <- if fq.fst.isJust then [] - else [err(qn.location, "Named parameter '" ++ qn.name ++ "' is not appropriate for '" ++ top.appExprApplied ++ "'")]; + else [errFromOrigin(qn, "Named parameter '" ++ qn.name ++ "' is not appropriate for '" ++ top.appExprApplied ++ "'")]; top.isPartial = e.isPartial; top.annoIndexConverted = if e.isPartial then [e.appExprIndex] else []; @@ -1213,7 +1155,7 @@ top::AnnoAppExprs ::= e::AnnoExpr top.isPartial = e.isPartial; top.errors <- if null(top.missingAnnotations) then [] - else [err(top.location, "Missing named parameters for function '" ++ top.appExprApplied ++ "': " + else [errFromOrigin(top, "Missing named parameters for function '" ++ top.appExprApplied ++ "': " ++ implode(", ", map(fst, top.missingAnnotations)))]; e.remainingFuncAnnotations = top.remainingFuncAnnotations; @@ -1232,7 +1174,7 @@ top::AnnoAppExprs ::= top.isPartial = false; top.errors <- if null(top.missingAnnotations) then [] - else [err(top.location, "Missing named parameters for function '" ++ top.appExprApplied ++ "': " + else [errFromOrigin(top, "Missing named parameters for function '" ++ top.appExprApplied ++ "': " ++ implode(", ", map(fst, top.missingAnnotations)))]; top.missingAnnotations = top.remainingFuncAnnotations; @@ -1276,31 +1218,31 @@ Integer ::= s::String l::[(String, Type)] z::Integer - This makes no assumptions, use it any way you wish! -} function mkStrFunctionInvocation -Expr ::= l::Location e::String es::[Expr] +Expr ::= e::String es::[Expr] { - return mkFullFunctionInvocation(l, baseExpr(qName(l, e), location=l), es, []); + return mkFullFunctionInvocation(baseExpr(qName(e)), es, []); } function mkFunctionInvocation -Expr ::= l::Location e::Expr es::[Expr] +Expr ::= e::Expr es::[Expr] { - return mkFullFunctionInvocation(l, e, es, []); + return mkFullFunctionInvocation(e, es, []); } function mkFullFunctionInvocation -Expr ::= l::Location e::Expr es::[Expr] ans::[Pair] +Expr ::= e::Expr es::[Expr] ans::[Pair] { return application(e, '(', - foldl(snocAppExprs(_, ',', _, location=l), emptyAppExprs(location=l), - map(presentAppExpr(_, location=l), es)), + foldl(snocAppExprs(_, ',', _), emptyAppExprs(), + map(presentAppExpr, es)), ',', - foldl(snocAnnoAppExprs(_, ',', _, location=l), emptyAnnoAppExprs(location=l), + foldl(snocAnnoAppExprs(_, ',', _), emptyAnnoAppExprs(), map(mkAnnoExpr, ans)), - ')', location=l); + ')'); } -- Internal helper function function mkAnnoExpr AnnoExpr ::= p::Pair { - return annoExpr(qName(p.snd.location, p.fst), '=', presentAppExpr(p.snd, location=p.snd.location), location=p.snd.location); + return annoExpr(qName(p.fst), '=', presentAppExpr(p.snd)); } {-- diff --git a/grammars/silver/compiler/definition/core/FunctionDcl.sv b/grammars/silver/compiler/definition/core/FunctionDcl.sv index ae6269bf0..453444010 100644 --- a/grammars/silver/compiler/definition/core/FunctionDcl.sv +++ b/grammars/silver/compiler/definition/core/FunctionDcl.sv @@ -1,7 +1,7 @@ grammar silver:compiler:definition:core; -nonterminal FunctionSignature with config, grammarName, env, location, unparse, errors, defs, constraintDefs, occursDefs, namedSignature, signatureName; -nonterminal FunctionLHS with config, grammarName, env, location, unparse, errors, defs, outputElement; +tracked nonterminal FunctionSignature with config, grammarName, env, unparse, errors, defs, constraintDefs, occursDefs, namedSignature, signatureName; +tracked nonterminal FunctionLHS with config, grammarName, env, unparse, errors, defs, outputElement; propagate config, grammarName, errors on FunctionSignature, FunctionLHS; @@ -13,20 +13,20 @@ top::AGDcl ::= 'function' id::Name ns::FunctionSignature body::ProductionBody production fName :: String = top.grammarName ++ ":" ++ id.name; production namedSig :: NamedSignature = ns.namedSignature; - top.defs := funDef(top.grammarName, id.location, namedSig) :: + top.defs := funDef(top.grammarName, id.nameLoc, namedSig) :: if null(body.productionAttributes) then [] - else [prodOccursDef(top.grammarName, id.location, namedSig, body.productionAttributes)]; + else [prodOccursDef(top.grammarName, id.nameLoc, namedSig, body.productionAttributes)]; top.errors <- if length(getValueDclAll(fName, top.env)) > 1 - then [err(id.location, "Value '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(id, "Value '" ++ fName ++ "' is already bound.")] else []; top.errors <- if null(body.returnExpr) - then [err(top.location, "Function '" ++ id.name ++ "' does not have a return value.")] + then [errFromOrigin(top, "Function '" ++ id.name ++ "' does not have a return value.")] else if length(body.returnExpr) > 1 - then [err(top.location, "Function '" ++ id.name ++ "' has more than one declared return value.")] + then [errFromOrigin(top, "Function '" ++ id.name ++ "' has more than one declared return value.")] else []; production attribute sigDefs :: [Def] with ++; @@ -41,7 +41,7 @@ top::AGDcl ::= 'function' id::Name ns::FunctionSignature body::ProductionBody body.env = occursEnv(ns.occursDefs, newScopeEnv(body.defs ++ sigDefs ++ ns.constraintDefs, newScopeEnv(prodAtts, top.env))); body.frame = functionContext(namedSig, myFlowGraph, sourceGrammar=top.grammarName); -- graph from flow:env } action { - insert semantic token IdFnProdDcl_t at id.location; + insert semantic token IdFnProdDcl_t at id.nameLoc; sigNames = []; } @@ -76,7 +76,7 @@ top::FunctionSignature ::= lhs::FunctionLHS '::=' rhs::ProductionRHS { top.unparse = s"${lhs.unparse} ::= ${rhs.unparse}"; - forwards to functionSignature(nilConstraint(location=top.location), '=>', lhs, $2, rhs, location=top.location); + forwards to functionSignature(nilConstraint(), '=>', lhs, $2, rhs); } action { sigNames = foldNamedSignatureElements(rhs.inputElements).elementNames; } @@ -93,6 +93,6 @@ top::FunctionLHS ::= t::TypeExpr top.outputElement = namedSignatureElement(fName, t.typerep); -- TODO: think about this. lhs doesn't really have an fName. - top.defs := [lhsDef(top.grammarName, t.location, fName, t.typerep)]; + top.defs := [lhsDef(top.grammarName, getParsedOriginLocationOrFallback(t), fName, t.typerep)]; } diff --git a/grammars/silver/compiler/definition/core/GlobalDcl.sv b/grammars/silver/compiler/definition/core/GlobalDcl.sv index 67e827709..317586dc7 100644 --- a/grammars/silver/compiler/definition/core/GlobalDcl.sv +++ b/grammars/silver/compiler/definition/core/GlobalDcl.sv @@ -16,7 +16,7 @@ top::AGDcl ::= 'global' id::Name '::' cl::ConstraintList '=>' t::TypeExpr '=' e: allLexicalTyVars = nub(t.lexicalTypeVariables); production attribute typeExprDefs :: [Def] with ++; - typeExprDefs := addNewLexicalTyVars(top.grammarName, top.location, t.lexicalTyVarKinds, allLexicalTyVars); + typeExprDefs := addNewLexicalTyVars(top.grammarName, t.lexicalTyVarKinds, allLexicalTyVars); -- The following environments require the definitions from the type -- expression, as constructed above in typeExprDefs using its lexical @@ -26,11 +26,11 @@ top::AGDcl ::= 'global' id::Name '::' cl::ConstraintList '=>' t::TypeExpr '=' e: -- The expression also requires the constraint list definitions in its env e.env = occursEnv(cl.occursDefs, newScopeEnv(cl.defs, cl.env)); - top.defs := [globalDef(top.grammarName, id.location, fName, boundVars, cl.contexts, t.typerep)]; + top.defs := [globalDef(top.grammarName, id.nameLoc, fName, boundVars, cl.contexts, t.typerep)]; top.errors <- if length(getValueDclAll(fName, top.env)) > 1 - then [err(id.location, "Value '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(id, "Value '" ++ fName ++ "' is already bound.")] else []; e.originRules = []; @@ -55,5 +55,5 @@ top::AGDcl ::= 'global' id::Name '::' t::TypeExpr '=' e::Expr ';' { top.unparse = "global " ++ id.unparse ++ " :: " ++ t.unparse ++ " = " ++ e.unparse ++ ";\n"; - forwards to globalValueDclConcrete($1, id, $3, nilConstraint(location=top.location), '=>', t, $5, e, $7, location=top.location); + forwards to globalValueDclConcrete($1, id, $3, nilConstraint(), '=>', t, $5, e, $7); } \ No newline at end of file diff --git a/grammars/silver/compiler/definition/core/GrammarParts.sv b/grammars/silver/compiler/definition/core/GrammarParts.sv index 74857097b..a52bf1e3f 100644 --- a/grammars/silver/compiler/definition/core/GrammarParts.sv +++ b/grammars/silver/compiler/definition/core/GrammarParts.sv @@ -61,7 +61,7 @@ top::Grammar ::= h::Root t::Grammar production attribute rootErrors::[Message] with ++; rootErrors := h.errors; - top.allFileErrors = (h.location.filename, rootErrors) :: t.allFileErrors; + top.allFileErrors = (getParsedOriginLocationOrFallback(h).filename, rootErrors) :: t.allFileErrors; rootErrors <- warnIfMultJarName(h.jarName, t.jarName, h.location); } diff --git a/grammars/silver/compiler/definition/core/InstanceDcl.sv b/grammars/silver/compiler/definition/core/InstanceDcl.sv index 7174dd16e..c098a4fb9 100644 --- a/grammars/silver/compiler/definition/core/InstanceDcl.sv +++ b/grammars/silver/compiler/definition/core/InstanceDcl.sv @@ -26,28 +26,28 @@ top::AGDcl ::= 'instance' cl::ConstraintList '=>' id::QNameType ty::TypeExpr '{' local myFlowGraph :: ProductionGraph = constructAnonymousGraph(body.flowDefs, top.env, myProds, myFlow); superContexts.frame = globalExprContext(fName, foldContexts(body.frameContexts), ty.typerep, myFlowGraph, sourceGrammar=top.grammarName); - top.defs := [instDef(top.grammarName, id.location, fName, boundVars, cl.contexts, ty.typerep, body.definedMembers)]; + top.defs := [instDef(top.grammarName, id.nameLoc, fName, boundVars, cl.contexts, ty.typerep, body.definedMembers)]; top.errors <- id.lookupType.errors; top.errors <- if !id.lookupType.found || dcl.isClass then [] - else [err(id.location, id.name ++ " is not a type class.")]; + else [errFromOrigin(id, id.name ++ " is not a type class.")]; top.errors <- if !ty.typerep.isError && length(getInstanceDcl(fName, ty.typerep, top.env)) > 1 - then [err(id.location, "Overlapping instances exist for " ++ id.unparse ++ " " ++ ty.unparse)] + then [errFromOrigin(id, "Overlapping instances exist for " ++ id.unparse ++ " " ++ ty.unparse)] else []; top.errors <- case ty.typerep of -- Default instance, must be exported by the class declaration | skolemType(_) when id.lookupType.found && !isExportedBy(top.grammarName, [dcl.sourceGrammar], top.compiledGrammars) -> - [wrn(top.location, "Orphaned default instance declaration for " ++ fName)] + [wrnFromOrigin(top, "Orphaned default instance declaration for " ++ fName)] -- Regular instance, must be exported by the class or type declaration | t when id.lookupType.found && !isExportedBy( top.grammarName, dcl.sourceGrammar :: map(\ d::TypeDclInfo -> d.sourceGrammar, getTypeDcl(t.typeName, top.env)), top.compiledGrammars) -> - [wrn(top.location, s"Orphaned instance declaration for ${fName} ${prettyType(t)}")] + [wrnFromOrigin(top, s"Orphaned instance declaration for ${fName} ${prettyType(t)}")] | _ -> [] end; @@ -58,7 +58,7 @@ top::AGDcl ::= 'instance' cl::ConstraintList '=>' id::QNameType ty::TypeExpr '{' production attribute headDefs :: [Def] with ++; headDefs := cl.defs; - headDefs <- [currentInstDef(top.grammarName, id.location, fName, ty.typerep)]; + headDefs <- [currentInstDef(top.grammarName, id.nameLoc, fName, ty.typerep)]; cl.env = newScopeEnv(headPreDefs, top.env); id.env = cl.env; @@ -70,7 +70,7 @@ top::AGDcl ::= 'instance' cl::ConstraintList '=>' id::QNameType ty::TypeExpr '{' body.expectedClassMembers = if id.lookupType.found then dcl.classMembers else []; body.frameContexts = superContexts.contexts ++ cl.contexts; } action { - insert semantic token IdTypeClass_t at id.baseNameLoc; + insert semantic token IdTypeClass_t at id.nameLoc; } concrete production instanceDclNoCL @@ -78,19 +78,19 @@ top::AGDcl ::= 'instance' id::QNameType ty::TypeExpr '{' body::InstanceBody '}' { top.unparse = s"instance ${id.unparse} ${ty.unparse}\n{\n${body.unparse}\n}"; - forwards to instanceDcl($1, nilConstraint(location=top.location), '=>', id, ty, $4, body, $6, location=top.location); + forwards to instanceDcl($1, nilConstraint(), '=>', id, ty, $4, body, $6); } action { - insert semantic token IdTypeClass_t at id.baseNameLoc; + insert semantic token IdTypeClass_t at id.nameLoc; } inherited attribute className::String; inherited attribute instanceType::Type; inherited attribute expectedClassMembers::[Pair]; -nonterminal InstanceBody with - config, grammarName, env, defs, location, unparse, errors, compiledGrammars, className, instanceType, frameContexts, expectedClassMembers, definedMembers; -nonterminal InstanceBodyItem with - config, grammarName, env, defs, location, unparse, errors, compiledGrammars, className, instanceType, frameContexts, expectedClassMembers, fullName; +tracked nonterminal InstanceBody with + config, grammarName, env, defs, unparse, errors, compiledGrammars, className, instanceType, frameContexts, expectedClassMembers, definedMembers; +tracked nonterminal InstanceBodyItem with + config, grammarName, env, defs, unparse, errors, compiledGrammars, className, instanceType, frameContexts, expectedClassMembers, fullName; propagate config, grammarName, compiledGrammars, className, instanceType, @@ -117,7 +117,7 @@ top::InstanceBody ::= top.errors <- flatMap( \ m::Pair -> - if m.snd then [] else [err(top.location, s"Missing instance member ${m.fst} for class ${top.className}")], + if m.snd then [] else [errFromOrigin(top, s"Missing instance member ${m.fst} for class ${top.className}")], top.expectedClassMembers); } @@ -148,7 +148,7 @@ top::InstanceBodyItem ::= id::QName '=' e::Expr ';' top.errors <- id.lookupValue.errors; top.errors <- if !id.lookupValue.found || lookup(top.fullName, top.expectedClassMembers).isJust then [] - else [err(id.location, s"Unexpected instance member ${id.name} for class ${top.className}")]; + else [errFromOrigin(id, s"Unexpected instance member ${id.name} for class ${top.className}")]; top.fullName = id.lookupValue.fullName; @@ -179,5 +179,5 @@ top::InstanceBodyItem ::= id::QName '=' e::Expr ';' e.frame = globalExprContext(top.fullName, foldContexts(top.frameContexts), typeScheme.typerep, myFlowGraph, sourceGrammar=top.grammarName); } action { - insert semantic token IdTypeClassMember_t at id.baseNameLoc; + insert semantic token IdTypeClassMember_t at id.nameLoc; } diff --git a/grammars/silver/compiler/definition/core/ModuleStmts.sv b/grammars/silver/compiler/definition/core/ModuleStmts.sv index e83c976e0..9c06591b3 100644 --- a/grammars/silver/compiler/definition/core/ModuleStmts.sv +++ b/grammars/silver/compiler/definition/core/ModuleStmts.sv @@ -2,19 +2,19 @@ grammar silver:compiler:definition:core; imports silver:compiler:driver:util; -nonterminal ModuleStmts with config, grammarName, location, unparse, errors, moduleNames, defs, occursDefs, exportedGrammars, optionalGrammars, condBuild, compiledGrammars, grammarDependencies; -nonterminal ModuleStmt with config, grammarName, location, unparse, errors, moduleNames, defs, occursDefs, exportedGrammars, optionalGrammars, condBuild, compiledGrammars, grammarDependencies; +tracked nonterminal ModuleStmts with config, grammarName, unparse, errors, moduleNames, defs, occursDefs, exportedGrammars, optionalGrammars, condBuild, compiledGrammars, grammarDependencies; +tracked nonterminal ModuleStmt with config, grammarName, unparse, errors, moduleNames, defs, occursDefs, exportedGrammars, optionalGrammars, condBuild, compiledGrammars, grammarDependencies; -nonterminal ImportStmt with config, grammarName, location, unparse, errors, moduleNames, defs, occursDefs, compiledGrammars, grammarDependencies; -nonterminal ImportStmts with config, grammarName, location, unparse, errors, moduleNames, defs, occursDefs, compiledGrammars, grammarDependencies; +tracked nonterminal ImportStmt with config, grammarName, unparse, errors, moduleNames, defs, occursDefs, compiledGrammars, grammarDependencies; +tracked nonterminal ImportStmts with config, grammarName, unparse, errors, moduleNames, defs, occursDefs, compiledGrammars, grammarDependencies; -nonterminal ModuleExpr with config, grammarName, location, unparse, errors, moduleNames, defs, occursDefs, compiledGrammars, grammarDependencies; -nonterminal ModuleName with config, grammarName, location, unparse, errors, moduleNames, defs, occursDefs, compiledGrammars, grammarDependencies; +tracked nonterminal ModuleExpr with config, grammarName, unparse, errors, moduleNames, defs, occursDefs, compiledGrammars, grammarDependencies; +tracked nonterminal ModuleName with config, grammarName, unparse, errors, moduleNames, defs, occursDefs, compiledGrammars, grammarDependencies; -nonterminal NameList with config, grammarName, location, unparse, names, env; +tracked nonterminal NameList with config, grammarName, unparse, names, env; -nonterminal WithElems with config, grammarName, location, unparse, envMaps; -nonterminal WithElem with config, grammarName, location, unparse, envMaps; +tracked nonterminal WithElems with config, grammarName, unparse, envMaps; +tracked nonterminal WithElem with config, grammarName, unparse, envMaps; propagate config, grammarName, errors, moduleNames, defs, occursDefs, compiledGrammars, grammarDependencies on ModuleStmts, ModuleStmt, ImportStmt, ImportStmts; @@ -31,11 +31,10 @@ synthesized attribute names :: [String]; synthesized attribute envMaps :: [Pair]; -- TODO: eliminate, fold into ModuleName, make filter parameters inh attrs. -nonterminal Module with defs, occursDefs, errors; +tracked nonterminal Module with defs, occursDefs, errors; abstract production module -top::Module ::= l::Location - need::[String] +top::Module ::= need::[String] seen::[String] compiledGrammars::EnvTree grammarDependencies::[String] @@ -47,7 +46,7 @@ top::Module ::= l::Location -- TODO: the use of 'seen' below is a not fully fleshed out. -- what we really need is some way to eliminate duplicate imports. production med :: ModuleExportedDefs = - moduleExportedDefs(l, compiledGrammars, grammarDependencies, need, seen); + moduleExportedDefs(compiledGrammars, grammarDependencies, need, seen); local defs :: Defs = foldr(consDefs, nilDefs(), med.defs); defs.filterItems = onlyFilter; @@ -73,11 +72,10 @@ top::Module ::= l::Location } -- recurses through exportedGrammars, grabbing all definitions -nonterminal ModuleExportedDefs with defs, occursDefs, errors; +tracked nonterminal ModuleExportedDefs with defs, occursDefs, errors; {-- - Computes the set of defs we get from an import - - @param l The location of the import, to raise an error if a module is missing - @param compiledGrammars Way to look up modules by name - @param grammarDependencies All imports of this grammar, closed over exports and triggers already. - @param need List of grammars we need to find and include in 'defs'. @@ -85,10 +83,10 @@ nonterminal ModuleExportedDefs with defs, occursDefs, errors; - (ALWAYS INITIALLY the importing grammar.) -} abstract production moduleExportedDefs -top::ModuleExportedDefs ::= l::Location compiledGrammars::EnvTree grammarDependencies::[String] need::[String] seen::[String] +top::ModuleExportedDefs ::= compiledGrammars::EnvTree grammarDependencies::[String] need::[String] seen::[String] { production recurse :: ModuleExportedDefs = - moduleExportedDefs(l, compiledGrammars, grammarDependencies, new_need, new_seen); + moduleExportedDefs(compiledGrammars, grammarDependencies, new_need, new_seen); local gram :: String = head(need); production rs :: [Decorated RootSpec] = searchEnvTree(gram, compiledGrammars); @@ -112,7 +110,7 @@ top::ModuleExportedDefs ::= l::Location compiledGrammars::EnvTree 1 - then [err(id.location, "Type '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(id, "Type '" ++ fName ++ "' is already bound.")] else []; top.errors <- if isLower(substring(0,1,id.name)) - then [err(id.location, "Types must be capitalized. Invalid nonterminal name " ++ id.name)] + then [errFromOrigin(id, "Types must be capitalized. Invalid nonterminal name " ++ id.name)] else []; } action { - insert semantic token IdTypeDcl_t at id.location; + insert semantic token IdTypeDcl_t at id.nameLoc; } -nonterminal NTDeclQualifiers with location, errors, data, closed, tracked; +tracked nonterminal NTDeclQualifiers with errors, data, closed, tracked; propagate errors, data, closed, tracked on NTDeclQualifiers; monoid attribute data :: Boolean with false, ||; @@ -63,26 +63,26 @@ concrete production dataNTQualifier top::NTDeclQualifiers ::= 'data' rest::NTDeclQualifiers { top.data <- true; - top.errors <- if rest.data then [err(top.location, "Duplicate 'data' qualifier")] else []; + top.errors <- if rest.data then [errFromOrigin(top, "Duplicate 'data' qualifier")] else []; } concrete production closedNTQualifier top::NTDeclQualifiers ::= 'closed' rest::NTDeclQualifiers { top.closed <- true; - top.errors <- if rest.closed then [err(top.location, "Duplicate 'closed' qualifier")] else []; + top.errors <- if rest.closed then [errFromOrigin(top, "Duplicate 'closed' qualifier")] else []; } concrete production trackedNTQualifier top::NTDeclQualifiers ::= 'tracked' rest::NTDeclQualifiers { top.tracked <- true; - top.errors <- if rest.tracked then [err(top.location, "Duplicate 'tracked' qualifier")] else []; + top.errors <- if rest.tracked then [errFromOrigin(top, "Duplicate 'tracked' qualifier")] else []; } -nonterminal NonterminalModifiers with config, location, unparse, errors, env, nonterminalName; -- 0 or some -nonterminal NonterminalModifierList with config, location, unparse, errors, env, nonterminalName; -- 1 or more -closed nonterminal NonterminalModifier with config, location, unparse, errors, env, nonterminalName; -- 1 +tracked nonterminal NonterminalModifiers with config, unparse, errors, env, nonterminalName; -- 0 or some +tracked nonterminal NonterminalModifierList with config, unparse, errors, env, nonterminalName; -- 1 or more +closed tracked nonterminal NonterminalModifier with config, unparse, errors, env, nonterminalName; -- 1 propagate config, errors, env, nonterminalName on NonterminalModifiers, NonterminalModifierList, NonterminalModifier; diff --git a/grammars/silver/compiler/definition/core/OccursDcl.sv b/grammars/silver/compiler/definition/core/OccursDcl.sv index 0787d65bb..086fa8433 100644 --- a/grammars/silver/compiler/definition/core/OccursDcl.sv +++ b/grammars/silver/compiler/definition/core/OccursDcl.sv @@ -3,7 +3,7 @@ grammar silver:compiler:definition:core; abstract production defaultAttributionDcl top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs { - undecorates to attributionDcl('attribute', at, attl, 'occurs', 'on', nt, nttl, ';', location=top.location); + undecorates to attributionDcl('attribute', at, attl, 'occurs', 'on', nt, nttl, ';'); top.unparse = "attribute " ++ at.unparse ++ attl.unparse ++ " occurs on " ++ nt.unparse ++ nttl.unparse ++ ";"; -- TODO: this location is highly unreliable. @@ -18,7 +18,7 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: if ntParamKinds == map((.kindrep), nttl.types) && map((.kindrep), atTypeScheme.boundVars) == map((.kindrep), attl.types) then protoatty else errorType(), - sourceGrammar=top.grammarName, sourceLocation=at.location)]; + sourceGrammar=top.grammarName, sourceLocation=at.nameLoc)]; -- binding errors in looking up these names. top.errors <- nt.lookupType.errors ++ @@ -27,7 +27,7 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: top.errors <- if attl.missingCount > 0 - then [err(attl.location, "Attribute type arguments cannot contain _")] + then [errFromOrigin(attl, "Attribute type arguments cannot contain _")] else []; nttl.initialEnv = top.env; @@ -48,12 +48,12 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: if null(nt.lookupType.dcls) then [] else if length(ntParamKinds) != length(nttl.types) then - [err(nt.location, + [errFromOrigin(nt, nt.name ++ " expects " ++ toString(length(ntParamKinds)) ++ " type variables, but " ++ toString(length(nttl.types)) ++ " were provided.")] else if ntParamKinds != map((.kindrep), nttl.types) then - [err(nt.location, + [errFromOrigin(nt, nt.name ++ " had kind " ++ foldr(arrowKind, starKind(), ntParamKinds).typepp ++ " but type variable(s) have kind(s) " ++ implode(", ", map(compose(prettyKind, (.kindrep)), nttl.types)) ++ ".")] else []; @@ -61,11 +61,11 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: -- Make sure we get the number and kind of type variables correct for the ATTR top.errors <- if length(atTypeScheme.boundVars) != length(attl.types) - then [err(at.location, + then [errFromOrigin(at, at.name ++ " expects " ++ toString(length(atTypeScheme.boundVars)) ++ " type variables, but " ++ toString(length(attl.types)) ++ " were provided.")] else if map((.kindrep), atTypeScheme.boundVars) != map((.kindrep), attl.types) - then [err(at.location, + then [errFromOrigin(at, at.name ++ " has kind " ++ prettyKind(foldr(arrowKind, starKind(), map((.kindrep), atTypeScheme.boundVars))) ++ " but type variable(s) have kind(s) " ++ implode(", ", map(compose(prettyKind, (.kindrep)), attl.types)) ++ ".")] else []; @@ -112,26 +112,26 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: top.errors <- if length(occursCheck) > 1 - then [err(at.location, "Attribute '" ++ at.name ++ "' already occurs on '" ++ nt.name ++ "'.")] + then [errFromOrigin(at, "Attribute '" ++ at.name ++ "' already occurs on '" ++ nt.name ++ "'.")] else []; top.errors <- if nt.lookupType.found && (!nt.lookupType.dcl.isType || !ntTypeScheme.typerep.isNonterminal) - then [err(nt.location, nt.name ++ " is not a nonterminal. Attributes can only occur on nonterminals.")] + then [errFromOrigin(nt, nt.name ++ " is not a nonterminal. Attributes can only occur on nonterminals.")] else []; top.errors <- if !nt.lookupType.found || !at.lookupAttribute.found || !at.lookupAttribute.dcl.isAnnotation || isExportedBy(top.grammarName, [nt.lookupType.dcl.sourceGrammar], top.compiledGrammars) then [] - else [err(top.location, "Annotations for a nonterminal must be in a module exported by the nonterminal's declaring grammar.")]; + else [errFromOrigin(top, "Annotations for a nonterminal must be in a module exported by the nonterminal's declaring grammar.")]; top.errors <- if nt.lookupType.found && ntTypeScheme.isData && at.lookupAttribute.found then if at.lookupAttribute.dcl.isInherited - then [err(top.location, "Inherited attributes may not occur on data nonterminals.")] + then [errFromOrigin(top, "Inherited attributes may not occur on data nonterminals.")] else if at.lookupAttribute.dcl.isTranslation - then [err(top.location, "Translation attributes may not occur on data nonterminals.")] + then [errFromOrigin(top, "Translation attributes may not occur on data nonterminals.")] else [] else []; } @@ -139,7 +139,7 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: abstract production errorAttributionDcl top::AGDcl ::= msg::[Message] at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs { - undecorates to errorAGDcl(msg, location=top.location); + undecorates to errorAGDcl(msg); top.unparse = "attribute " ++ at.unparse ++ attl.unparse ++ " occurs on " ++ nt.unparse ++ nttl.unparse ++ ";"; top.occursDefs := []; top.errors <- msg; @@ -160,11 +160,11 @@ top::AGDcl ::= msg::[Message] at::Decorated! QName attl::BracketedOptTypeExprs n top.errors <- case nt.lookupType.dcls of | ntDcl(_, ks, _, _, _) :: _ when length(ks) != length(nttl.types) -> - [err(nt.location, + [errFromOrigin(nt, nt.name ++ " expects " ++ toString(length(ks)) ++ " type variables, but " ++ toString(length(nttl.types)) ++ " were provided.")] | ntDcl(_, ks, _, _, _) :: _ when ks != map((.kindrep), nttl.types) -> - [err(nt.location, + [errFromOrigin(nt, nt.name ++ " had kind " ++ foldr(arrowKind, starKind(), ks).typepp ++ " but type variable(s) have kind(s) " ++ implode(", ", map(compose(prettyKind, (.kindrep)), nttl.types)) ++ ".")] | _ -> [] @@ -188,14 +188,14 @@ top::AGDcl ::= 'attribute' at::QName attl::BracketedOptTypeExprs 'occurs' 'on' n top.moduleNames := []; forwards to - (if !at.lookupAttribute.found - then errorAttributionDcl(at.lookupAttribute.errors, _, _, _, _, location=_) - else at.lookupAttribute.dcl.attributionDispatcher)(at, attl, nt, nttl, top.location); + if !at.lookupAttribute.found + then errorAttributionDcl(at.lookupAttribute.errors, at, attl, nt, nttl) + else at.lookupAttribute.dcl.attributionDispatcher(at, attl, nt, nttl); } concrete production annotateDcl top::AGDcl ::= 'annotation' at::QName attl::BracketedOptTypeExprs 'occurs' 'on' nt::QName nttl::BracketedOptTypeExprs ';' { - forwards to attributionDcl('attribute', at, attl, $4, $5, nt, nttl, $8, location=top.location); + forwards to attributionDcl('attribute', at, attl, $4, $5, nt, nttl, $8); } diff --git a/grammars/silver/compiler/definition/core/ProductionBody.sv b/grammars/silver/compiler/definition/core/ProductionBody.sv index e9045fb09..2a227a1e6 100644 --- a/grammars/silver/compiler/definition/core/ProductionBody.sv +++ b/grammars/silver/compiler/definition/core/ProductionBody.sv @@ -1,13 +1,13 @@ grammar silver:compiler:definition:core; -nonterminal ProductionBody with - config, grammarName, env, location, unparse, errors, defs, frame, compiledGrammars, +tracked nonterminal ProductionBody with + config, grammarName, env, unparse, errors, defs, frame, compiledGrammars, productionAttributes, forwardExpr, returnExpr, undecorateExpr; -nonterminal ProductionStmts with - config, grammarName, env, location, unparse, errors, defs, frame, compiledGrammars, +tracked nonterminal ProductionStmts with + config, grammarName, env, unparse, errors, defs, frame, compiledGrammars, productionAttributes, forwardExpr, returnExpr, undecorateExpr, originRules; -nonterminal ProductionStmt with - config, grammarName, env, location, unparse, errors, defs, frame, compiledGrammars, +tracked nonterminal ProductionStmt with + config, grammarName, env, unparse, errors, defs, frame, compiledGrammars, productionAttributes, forwardExpr, returnExpr, undecorateExpr, originRules; flowtype decorate {frame, grammarName, compiledGrammars, config, env, flowEnv, downSubst} @@ -18,18 +18,18 @@ flowtype decorate {frame, grammarName, compiledGrammars, config, env, flowEnv, d on ProductionStmt; flowtype forward {decorate} on ProductionBody, ProductionStmts, ProductionStmt; -nonterminal DefLHS with - config, grammarName, env, location, unparse, errors, frame, compiledGrammars, name, typerep, defLHSattr, found, originRules; +tracked nonterminal DefLHS with + config, grammarName, env, unparse, errors, frame, compiledGrammars, name, typerep, defLHSattr, found, originRules; flowtype decorate {frame, grammarName, compiledGrammars, config, env, flowEnv, defLHSattr, originRules} on DefLHS; -nonterminal ForwardInhs with - config, grammarName, env, location, unparse, errors, frame, compiledGrammars, originRules; -nonterminal ForwardInh with - config, grammarName, env, location, unparse, errors, frame, compiledGrammars, originRules; -nonterminal ForwardLHSExpr with - config, grammarName, env, location, unparse, errors, frame, name, typerep, originRules; +tracked nonterminal ForwardInhs with + config, grammarName, env, unparse, errors, frame, compiledGrammars, originRules; +tracked nonterminal ForwardInh with + config, grammarName, env, unparse, errors, frame, compiledGrammars, originRules; +tracked nonterminal ForwardLHSExpr with + config, grammarName, env, unparse, errors, frame, name, typerep, originRules; {-- - Context for ProductionStmt blocks. (Indicates function, production, aspect, etc) @@ -141,7 +141,7 @@ top::ProductionStmt ::= 'return' e::Expr ';' top.returnExpr := [e]; top.errors <- if !top.frame.permitReturn - then [err(top.location, "Return is not valid in this context. (They are only permitted in function declarations.)")] + then [errFromOrigin(top, "Return is not valid in this context. (They are only permitted in function declarations.)")] else []; e.isRoot = true; @@ -153,17 +153,17 @@ top::ProductionStmt ::= 'local' 'attribute' a::Name '::' te::TypeExpr ';' top.unparse = "\tlocal attribute " ++ a.unparse ++ "::" ++ te.unparse ++ ";"; production attribute fName :: String; - fName = s"${top.frame.fullName}:local:${top.grammarName}:${implode("_", filter(isAlpha, explode(".", top.location.filename)))}:${toString(top.location.line)}:${toString(top.location.column)}:${a.name}"; + fName = s"${top.frame.fullName}:local:${top.grammarName}:${implode("_", filter(isAlpha, explode(".", a.nameLoc.filename)))}:${toString(a.nameLoc.line)}:${toString(a.nameLoc.column)}:${a.name}"; - top.defs := [localDef(top.grammarName, a.location, fName, te.typerep, false)]; + top.defs := [localDef(top.grammarName, a.nameLoc, fName, te.typerep, false)]; top.errors <- if length(getValueDclInScope(a.name, top.env)) > 1 - then [err(a.location, "Value '" ++ a.name ++ "' is already bound.")] + then [errFromOrigin(a, "Value '" ++ a.name ++ "' is already bound.")] else []; top.errors <- if !top.frame.permitLocalAttributes - then [err(top.location, "Local attributes are not valid in this context.")] + then [errFromOrigin(top, "Local attributes are not valid in this context.")] else []; } @@ -175,15 +175,15 @@ top::ProductionStmt ::= 'production' 'attribute' a::Name '::' te::TypeExpr ';' production attribute fName :: String; fName = top.frame.fullName ++ ":local:" ++ top.grammarName ++ ":" ++ a.name; - top.productionAttributes := [localDef(top.grammarName, a.location, fName, te.typerep, false)]; + top.productionAttributes := [localDef(top.grammarName, a.nameLoc, fName, te.typerep, false)]; top.errors <- if length(getValueDclAll(fName, top.env)) > 1 - then [err(a.location, "Value '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(a, "Value '" ++ fName ++ "' is already bound.")] else []; top.errors <- if !top.frame.permitProductionAttributes - then [err(top.location, "Production attributes are not valid in this context.")] + then [errFromOrigin(top, "Production attributes are not valid in this context.")] else []; } @@ -195,15 +195,15 @@ top::ProductionStmt ::= 'forward' 'production' 'attribute' a::Name ';' production attribute fName :: String; fName = top.frame.fullName ++ ":local:" ++ top.grammarName ++ ":" ++ a.name; - top.productionAttributes := [localDef(top.grammarName, a.location, fName, top.frame.signature.outputElement.typerep, true)]; + top.productionAttributes := [localDef(top.grammarName, a.nameLoc, fName, top.frame.signature.outputElement.typerep, true)]; top.errors <- if length(getValueDclAll(fName, top.env)) > 1 - then [err(a.location, "Value '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(a, "Value '" ++ fName ++ "' is already bound.")] else []; top.errors <- if !top.frame.permitForwardProductionAttributes - then [err(top.location, "Forward production attributes are not valid in this context.")] + then [errFromOrigin(top, "Forward production attributes are not valid in this context.")] else []; } @@ -214,11 +214,11 @@ top::ProductionStmt ::= 'forwards' 'to' e::Expr ';' e.isRoot = true; - top.productionAttributes := [forwardDef(top.grammarName, top.location, top.frame.signature.outputElement.typerep)]; + top.productionAttributes := [forwardDef(top.grammarName, getParsedOriginLocationOrFallback(top), top.frame.signature.outputElement.typerep)]; top.forwardExpr := [e]; top.errors <- if !top.frame.permitForward - then [err(top.location, "Forwarding is not permitted in this context. (Only permitted in non-aspect productions.)")] + then [errFromOrigin(top, "Forwarding is not permitted in this context. (Only permitted in non-aspect productions.)")] else []; } @@ -228,9 +228,8 @@ top::ProductionStmt ::= 'forwards' 'to' e::Expr 'with' '{' inh::ForwardInhs '}' top.unparse = "\tforwards to " ++ e.unparse ++ " with {" ++ inh.unparse ++ "};"; forwards to productionStmtAppend( - forwardsTo($1, $2, $3, $8, location=top.location), - forwardingWith('forwarding', $4, $5, inh, $7, $8, location=top.location), - location=top.location); + forwardsTo($1, $2, $3, $8), + forwardingWith('forwarding', $4, $5, inh, $7, $8)); } concrete production forwardingWith @@ -242,7 +241,7 @@ top::ProductionStmt ::= 'forwarding' 'with' '{' inh::ForwardInhs '}' ';' fwdDcls = getValueDcl("forward", top.env); top.errors <- if null(fwdDcls) - then [err(top.location, "'forwarding with' clause for a production that does not forward!")] + then [errFromOrigin(top, "'forwarding with' clause for a production that does not forward!")] else []; } @@ -289,7 +288,7 @@ top::ProductionStmt ::= 'undecorates' 'to' e::Expr ';' top.errors <- if !top.frame.permitForward -- Permitted in the same place as forwards to - then [err(top.location, "Undecorates is not permitted in this context. (Only permitted in non-aspect productions.)")] + then [errFromOrigin(top, "Undecorates is not permitted in this context. (Only permitted in non-aspect productions.)")] else []; } @@ -308,7 +307,7 @@ top::ProductionStmt ::= dl::DefLHS '.' attr::QNameAttrOccur '=' e::Expr ';' local problems :: [Message] = if attr.found && attr.attrDcl.isAnnotation - then [err(attr.location, attr.name ++ " is an annotation, which are supplied to productions as arguments, not defined as equations.")] + then [errFromOrigin(attr, attr.name ++ " is an annotation, which are supplied to productions as arguments, not defined as equations.")] else dl.errors ++ attr.errors; forwards to @@ -316,9 +315,9 @@ top::ProductionStmt ::= dl::DefLHS '.' attr::QNameAttrOccur '=' e::Expr ';' -- consider "production foo top::DoesNotExist ::= { top.errors = ...; }" -- where top is a valid reference to a type that is an error type -- so there is an error elsewhere - (if !dl.found || !attr.found || !null(problems) - then errorAttributeDef(problems, _, _, _, location=_) - else attr.attrDcl.attrDefDispatcher)(dl, attr, e, top.location); + if !dl.found || !attr.found || !null(problems) + then errorAttributeDef(problems, dl, attr, e) + else attr.attrDcl.attrDefDispatcher(dl, attr, e); } {- This is a helper that exist primarily to decorate 'e' and add its error messages to the list. @@ -326,18 +325,18 @@ top::ProductionStmt ::= dl::DefLHS '.' attr::QNameAttrOccur '=' e::Expr ';' abstract production errorAttributeDef top::ProductionStmt ::= msg::[Message] dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr { - undecorates to errorProductionStmt(msg, location=top.location); + undecorates to errorProductionStmt(msg); top.unparse = "\t" ++ dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; propagate grammarName, config, env, frame, compiledGrammars, originRules; e.isRoot = true; - forwards to errorProductionStmt(msg ++ e.errors, location=top.location); + forwards to errorProductionStmt(msg ++ e.errors); } abstract production synthesizedAttributeDef top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr { - undecorates to attributeDef(dl, '.', attr, '=', e, ';', location=top.location); + undecorates to attributeDef(dl, '.', attr, '=', e, ';'); top.unparse = "\t" ++ dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; e.isRoot = true; @@ -345,7 +344,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur top.errors <- case getValueDcl(top.frame.fullName, top.env) of | dcl :: _ when dcl.hasForward && attr.found && attr.attrDcl.isTranslation -> - [err(top.location, s"Overriding translation attribute ${attr.attrDcl.fullName} in a forwarding production is not currently supported.")] + [errFromOrigin(top, s"Overriding translation attribute ${attr.attrDcl.fullName} in a forwarding production is not currently supported.")] | _ -> [] end; } @@ -353,7 +352,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur abstract production inheritedAttributeDef top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr { - undecorates to attributeDef(dl, '.', attr, '=', e, ';', location=top.location); + undecorates to attributeDef(dl, '.', attr, '=', e, ';'); top.unparse = "\t" ++ dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; e.isRoot = true; @@ -373,9 +372,8 @@ top::ProductionStmt ::= dl::DefLHS '.' transAttr::QNameAttrOccur '.' attr::QName case dl of | concreteDefLHS(q) -> q | _ -> error("Unexpected concrete DefLHS") - end, transAttr, location=top.location), - $4, attr, $6, e, $8, - location=top.location); + end, transAttr), + $4, attr, $6, e, $8); } concrete production concreteDefLHS @@ -385,39 +383,39 @@ top::DefLHS ::= q::QName top.unparse = q.unparse; propagate env; - forwards to (if null(q.lookupValue.dcls) - then errorDefLHS(_, location=_) - else q.lookupValue.dcl.defLHSDispatcher)(q, top.location); + forwards to if null(q.lookupValue.dcls) + then errorDefLHS(q) + else q.lookupValue.dcl.defLHSDispatcher(q); } action { if (contains(q.name, sigNames)) { - insert semantic token IdSigName_t at q.baseNameLoc; + insert semantic token IdSigName_t at q.nameLoc; } } abstract production errorDefLHS top::DefLHS ::= q::Decorated! QName { - undecorates to concreteDefLHS(q, location=top.location); + undecorates to concreteDefLHS(q); top.name = q.name; top.unparse = q.unparse; top.found = false; top.errors <- q.lookupValue.errors; top.errors <- - if top.typerep.isError then [] else [err(q.location, "Cannot define attributes on " ++ q.name)]; + if top.typerep.isError then [] else [errFromOrigin(q, "Cannot define attributes on " ++ q.name)]; top.typerep = q.lookupValue.typeScheme.typerep; } concrete production concreteDefLHSfwd -top::DefLHS ::= q::'forward' +top::DefLHS ::= 'forward' { - forwards to concreteDefLHS(qName(q.location, "forward"), location=top.location); + forwards to concreteDefLHS(qName("forward")); } abstract production childDefLHS top::DefLHS ::= q::Decorated! QName { - undecorates to concreteDefLHS(q, location=top.location); + undecorates to concreteDefLHS(q); top.name = q.name; top.unparse = q.unparse; top.found = !existingProblems && top.defLHSattr.attrDcl.isInherited; @@ -426,7 +424,7 @@ top::DefLHS ::= q::Decorated! QName top.errors <- if existingProblems || top.found then [] - else [err(q.location, "Cannot define synthesized attribute '" ++ top.defLHSattr.name ++ "' on child '" ++ q.name ++ "'")]; + else [errFromOrigin(q, "Cannot define synthesized attribute '" ++ top.defLHSattr.name ++ "' on child '" ++ q.name ++ "'")]; top.typerep = q.lookupValue.typeScheme.monoType; } @@ -434,7 +432,7 @@ top::DefLHS ::= q::Decorated! QName abstract production lhsDefLHS top::DefLHS ::= q::Decorated! QName { - undecorates to concreteDefLHS(q, location=top.location); + undecorates to concreteDefLHS(q); top.name = q.name; top.unparse = q.unparse; top.found = !existingProblems && top.defLHSattr.attrDcl.isSynthesized; @@ -443,7 +441,7 @@ top::DefLHS ::= q::Decorated! QName top.errors <- if existingProblems || top.found then [] - else [err(q.location, "Cannot define inherited attribute '" ++ top.defLHSattr.name ++ "' on the lhs '" ++ q.name ++ "'")]; + else [errFromOrigin(q, "Cannot define inherited attribute '" ++ top.defLHSattr.name ++ "' on the lhs '" ++ q.name ++ "'")]; top.typerep = q.lookupValue.typeScheme.monoType; } @@ -451,7 +449,7 @@ top::DefLHS ::= q::Decorated! QName abstract production localDefLHS top::DefLHS ::= q::Decorated! QName { - undecorates to concreteDefLHS(q, location=top.location); + undecorates to concreteDefLHS(q); top.name = q.name; top.unparse = q.unparse; top.found = !existingProblems && top.defLHSattr.attrDcl.isInherited; @@ -460,7 +458,7 @@ top::DefLHS ::= q::Decorated! QName top.errors <- if existingProblems || top.found then [] - else [err(q.location, "Cannot define synthesized attribute '" ++ top.defLHSattr.name ++ "' on local '" ++ q.name ++ "'")]; + else [errFromOrigin(q, "Cannot define synthesized attribute '" ++ top.defLHSattr.name ++ "' on local '" ++ q.name ++ "'")]; top.typerep = q.lookupValue.typeScheme.monoType; } @@ -468,7 +466,7 @@ top::DefLHS ::= q::Decorated! QName abstract production forwardDefLHS top::DefLHS ::= q::Decorated! QName { - undecorates to concreteDefLHS(q, location=top.location); + undecorates to concreteDefLHS(q); top.name = q.name; top.unparse = q.unparse; top.found = !existingProblems && top.defLHSattr.attrDcl.isInherited; @@ -477,7 +475,7 @@ top::DefLHS ::= q::Decorated! QName top.errors <- if existingProblems || top.found then [] - else [err(q.location, "Cannot define synthesized attribute '" ++ top.defLHSattr.name ++ "' on forward")]; + else [errFromOrigin(q, "Cannot define synthesized attribute '" ++ top.defLHSattr.name ++ "' on forward")]; top.typerep = q.lookupValue.typeScheme.monoType; } @@ -493,29 +491,29 @@ top::DefLHS ::= q::QName attr::QNameAttrOccur attr.config = top.config; attr.attrFor = q.lookupValue.typeScheme.monoType; - forwards to (if null(q.lookupValue.dcls) || !attr.found || !attr.attrDcl.isTranslation - then errorTransAttrDefLHS(_, _, location=_) - else q.lookupValue.dcl.transDefLHSDispatcher)(q, attr, top.location); + forwards to if null(q.lookupValue.dcls) || !attr.found || !attr.attrDcl.isTranslation + then errorTransAttrDefLHS(q, attr) + else q.lookupValue.dcl.transDefLHSDispatcher(q, attr); } abstract production errorTransAttrDefLHS top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur { - undecorates to transAttrDefLHS(q, attr, location=top.location); + undecorates to transAttrDefLHS(q, attr); top.name = q.name; top.unparse = s"${q.unparse}.${attr.unparse}"; top.found = false; top.errors <- q.lookupValue.errors; top.errors <- - if top.typerep.isError then [] else [err(q.location, "Cannot define attributes on " ++ top.unparse)]; + if top.typerep.isError then [] else [errFromOrigin(q, "Cannot define attributes on " ++ top.unparse)]; top.typerep = attr.typerep; } abstract production childTransAttrDefLHS top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur { - undecorates to transAttrDefLHS(q, attr, location=top.location); + undecorates to transAttrDefLHS(q, attr); top.name = q.name; top.unparse = s"${q.unparse}.${attr.unparse}"; top.found = !existingProblems && attr.attrDcl.isSynthesized && top.defLHSattr.attrDcl.isInherited; @@ -525,13 +523,13 @@ top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur top.errors <- if existingProblems then [] else if !top.defLHSattr.attrDcl.isInherited - then [err(attr.location, s"Attribute '${attr.name}' is not inherited and cannot be defined on '${top.unparse}'")] + then [errFromOrigin(attr, s"Attribute '${attr.name}' is not inherited and cannot be defined on '${top.unparse}'")] else []; local ty::Type = q.lookupValue.typeScheme.monoType; top.errors <- if attr.found && !ty.isNonterminal && !ty.isUniqueDecorated - then [err(q.location, s"Inherited equations on translation attributes on child ${q.name} of type ${prettyType(ty)} are not supported")] + then [errFromOrigin(q, s"Inherited equations on translation attributes on child ${q.name} of type ${prettyType(ty)} are not supported")] else []; top.typerep = attr.typerep; @@ -540,7 +538,7 @@ top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur abstract production localTransAttrDefLHS top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur { - undecorates to transAttrDefLHS(q, attr, location=top.location); + undecorates to transAttrDefLHS(q, attr); top.name = q.name; top.unparse = s"${q.unparse}.${attr.unparse}"; top.found = !existingProblems && attr.attrDcl.isSynthesized && top.defLHSattr.attrDcl.isInherited; @@ -550,13 +548,13 @@ top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur top.errors <- if existingProblems then [] else if !top.defLHSattr.attrDcl.isInherited - then [err(attr.location, s"Attribute '${attr.name}' is not inherited and cannot be defined on '${top.unparse}'")] + then [errFromOrigin(attr, s"Attribute '${attr.name}' is not inherited and cannot be defined on '${top.unparse}'")] else []; local ty::Type = q.lookupValue.typeScheme.monoType; top.errors <- if attr.found && !ty.isNonterminal && !ty.isUniqueDecorated - then [err(q.location, s"Inherited equations on translation attributes on local ${q.name} of type ${prettyType(ty)} are not supported")] + then [errFromOrigin(q, s"Inherited equations on translation attributes on local ${q.name} of type ${prettyType(ty)} are not supported")] else []; top.typerep = attr.typerep; @@ -576,28 +574,28 @@ top::ProductionStmt ::= val::QName '=' e::Expr ';' top.productionAttributes := []; top.defs := []; - forwards to (if null(val.lookupValue.dcls) - then errorValueDef(_, _, location=_) - else val.lookupValue.dcl.defDispatcher)(val, e, top.location); + forwards to if null(val.lookupValue.dcls) + then errorValueDef(val, e) + else val.lookupValue.dcl.defDispatcher(val, e); } abstract production errorValueDef top::ProductionStmt ::= val::Decorated! QName e::Expr { - undecorates to valueEq(val, '=', e, ';', location=top.location); + undecorates to valueEq(val, '=', e, ';'); top.unparse = "\t" ++ val.unparse ++ " = " ++ e.unparse ++ ";"; e.isRoot = true; top.errors <- if val.lookupValue.typeScheme.isError then [] - else [err(val.location, val.name ++ " cannot be assigned to.")]; + else [errFromOrigin(val, val.name ++ " cannot be assigned to.")]; } abstract production localValueDef top::ProductionStmt ::= val::Decorated! QName e::Expr { - undecorates to valueEq(val, '=', e, ';', location=top.location); + undecorates to valueEq(val, '=', e, ';'); top.unparse = "\t" ++ val.unparse ++ " = " ++ e.unparse ++ ";"; -- val is already valid here diff --git a/grammars/silver/compiler/definition/core/ProductionDcl.sv b/grammars/silver/compiler/definition/core/ProductionDcl.sv index a69ae6d9a..f9f375ec0 100644 --- a/grammars/silver/compiler/definition/core/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/core/ProductionDcl.sv @@ -1,9 +1,9 @@ grammar silver:compiler:definition:core; -nonterminal ProductionSignature with config, grammarName, env, location, unparse, errors, defs, constraintDefs, occursDefs, namedSignature, signatureName; -nonterminal ProductionLHS with config, grammarName, env, location, unparse, errors, defs, outputElement; -nonterminal ProductionRHS with config, grammarName, env, location, unparse, errors, defs, inputElements, elementCount; -nonterminal ProductionRHSElem with config, grammarName, env, location, unparse, errors, defs, inputElements, deterministicCount; +tracked nonterminal ProductionSignature with config, grammarName, env, unparse, errors, defs, constraintDefs, occursDefs, namedSignature, signatureName; +tracked nonterminal ProductionLHS with config, grammarName, env, unparse, errors, defs, outputElement; +tracked nonterminal ProductionRHS with config, grammarName, env, unparse, errors, defs, inputElements, elementCount; +tracked nonterminal ProductionRHSElem with config, grammarName, env, unparse, errors, defs, inputElements, deterministicCount; flowtype forward {env, signatureName} on ProductionSignature; flowtype forward {env} on ProductionLHS, ProductionRHS; @@ -45,9 +45,9 @@ top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::Pr production fName :: String = top.grammarName ++ ":" ++ id.name; production namedSig :: NamedSignature = ns.namedSignature; - top.defs := prodDef(top.grammarName, id.location, namedSig, length(body.forwardExpr) > 0) :: + top.defs := prodDef(top.grammarName, id.nameLoc, namedSig, length(body.forwardExpr) > 0) :: if null(body.productionAttributes) then [] - else [prodOccursDef(top.grammarName, id.location, namedSig, body.productionAttributes)]; + else [prodOccursDef(top.grammarName, id.nameLoc, namedSig, body.productionAttributes)]; -- Other productions on the same nonterminal with the same name: local sameNTProds::[ValueDclInfo] = filter( @@ -59,24 +59,24 @@ top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::Pr getValueDclAll(id.name, top.env)); top.errors <- if length(getValueDclAll(fName, top.env)) > 1 - then [err(id.location, "Value '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(id, "Value '" ++ fName ++ "' is already bound.")] else if length(sameNTProds) > 1 - then [err(top.location, "Production " ++ id.name ++ " shares a name with another production from an imported grammar. Either this production is meant to be an aspect, or you should use 'import ... with " ++ id.name ++ " as ...' to change the other production's apparent name.")] + then [errFromOrigin(top, "Production " ++ id.name ++ " shares a name with another production from an imported grammar. Either this production is meant to be an aspect, or you should use 'import ... with " ++ id.name ++ " as ...' to change the other production's apparent name.")] else []; top.errors <- if length(body.forwardExpr) > 1 - then [err(top.location, "Production '" ++ id.name ++ "' has more than one forward declaration.")] + then [errFromOrigin(top, "Production '" ++ id.name ++ "' has more than one forward declaration.")] else []; top.errors <- if length(body.undecorateExpr) > 1 - then [err(top.location, "Production '" ++ id.name ++ "' has more than one undecorate declaration.")] + then [errFromOrigin(top, "Production '" ++ id.name ++ "' has more than one undecorate declaration.")] else []; top.errors <- if isLower(substring(0,1,id.name)) then [] - else [wrn(id.location, s"(future) ${id.name}: productions may be required to begin with a lower-case letter.")]; + else [wrnFromOrigin(id, s"(future) ${id.name}: productions may be required to begin with a lower-case letter.")]; production attribute sigDefs :: [Def] with ++; sigDefs := ns.defs; @@ -90,7 +90,7 @@ top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::Pr body.env = occursEnv(ns.occursDefs, newScopeEnv(body.defs ++ sigDefs ++ ns.constraintDefs ++ prodAtts, top.env)); body.frame = productionContext(namedSig, myFlowGraph, sourceGrammar=top.grammarName); -- graph from flow:env } action { - insert semantic token IdFnProdDcl_t at id.location; + insert semantic token IdFnProdDcl_t at id.nameLoc; sigNames = []; } @@ -123,7 +123,7 @@ top::ProductionSignature ::= lhs::ProductionLHS '::=' rhs::ProductionRHS { top.unparse = s"${lhs.unparse} ::= ${rhs.unparse}"; - forwards to productionSignature(nilConstraint(location=top.location), '=>', lhs, $2, rhs, location=top.location); + forwards to productionSignature(nilConstraint(), '=>', lhs, $2, rhs); } action { sigNames = foldNamedSignatureElements(lhs.outputElement :: rhs.inputElements).elementNames; } @@ -136,14 +136,14 @@ top::ProductionLHS ::= id::Name '::' t::TypeExpr top.outputElement = namedSignatureElement(id.name, t.typerep); - top.defs := [lhsDef(top.grammarName, id.location, id.name, t.typerep)]; + top.defs := [lhsDef(top.grammarName, id.nameLoc, id.name, t.typerep)]; top.errors <- if length(getValueDclInScope(id.name, top.env)) > 1 - then [err(id.location, "Value '" ++ id.name ++ "' is already bound.")] + then [errFromOrigin(id, "Value '" ++ id.name ++ "' is already bound.")] else []; } action { - insert semantic token IdSigNameDcl_t at id.location; + insert semantic token IdSigNameDcl_t at id.nameLoc; } concrete production productionRHSNil @@ -173,14 +173,14 @@ top::ProductionRHSElem ::= id::Name '::' t::TypeExpr top.inputElements = [namedSignatureElement(id.name, t.typerep)]; - top.defs := [childDef(top.grammarName, id.location, id.name, t.typerep)]; + top.defs := [childDef(top.grammarName, id.nameLoc, id.name, t.typerep)]; top.errors <- if length(getValueDclInScope(id.name, top.env)) > 1 - then [err(id.location, "Value '" ++ id.name ++ "' is already bound.")] + then [errFromOrigin(id, "Value '" ++ id.name ++ "' is already bound.")] else []; } action { - insert semantic token IdSigNameDcl_t at id.location; + insert semantic token IdSigNameDcl_t at id.nameLoc; } concrete production productionRHSElemType @@ -188,6 +188,6 @@ top::ProductionRHSElem ::= t::TypeExpr { top.unparse = t.unparse; - forwards to productionRHSElem(name("_G_" ++ toString(top.deterministicCount), t.location), '::', t, location=top.location); + forwards to productionRHSElem(name("_G_" ++ toString(top.deterministicCount)), '::', t); } diff --git a/grammars/silver/compiler/definition/core/QName.sv b/grammars/silver/compiler/definition/core/QName.sv index bfcf99879..4453cfe77 100644 --- a/grammars/silver/compiler/definition/core/QName.sv +++ b/grammars/silver/compiler/definition/core/QName.sv @@ -3,11 +3,11 @@ grammar silver:compiler:definition:core; {-- - Qualified names of the form 'a:b:c:d...' -} -nonterminal QName with config, name, location, grammarName, env, unparse, qNameType, baseNameLoc; +tracked nonterminal QName with config, name, grammarName, env, unparse, qNameType, nameLoc; {-- - Qualified names where the LAST name has an upper case first letter. -} -nonterminal QNameType with config, name, location, grammarName, env, unparse, baseNameLoc; +tracked nonterminal QNameType with config, name, grammarName, env, unparse, nameLoc; flowtype decorate {env} on QName, QNameType; @@ -17,13 +17,13 @@ flowtype decorate {env} on QName, QNameType; synthesized attribute dcls :: [a]; synthesized attribute qNameType::QNameType; -synthesized attribute baseNameLoc::Location; +synthesized attribute nameLoc::Location; --- TODO: for consistency, the order of these args should be flipped: function qName -QName ::= l::Location s::String +QName ::= s::String { - return qNameId(nameIdLower(terminal(IdLower_t, s, l), location=l), location=l); + local loc::Location = getParsedOriginLocationOrFallback(ambientOrigin()); + return qNameId(nameIdLower(terminal(IdLower_t, s, loc))); } concrete production qNameId @@ -31,12 +31,12 @@ top::QName ::= id::Name { top.name = id.name; top.unparse = id.unparse; - top.qNameType = qNameTypeId(terminal(IdUpper_t, id.name, id.location), location=id.location); - top.baseNameLoc = id.location; + top.qNameType = qNameTypeId(terminal(IdUpper_t, id.name, id.nameLoc)); + top.nameLoc = id.nameLoc; - top.lookupValue = customLookup("value", getValueDcl(top.name, top.env), top.name, top.location); - top.lookupType = customLookup("type", getTypeDcl(top.name, top.env), top.name, top.location); - top.lookupAttribute = customLookup("attribute", getAttrDcl(top.name, top.env), top.name, top.location); + top.lookupValue = customLookup("value", getValueDcl(top.name, top.env), top.name); + top.lookupType = customLookup("type", getTypeDcl(top.name, top.env), top.name); + top.lookupAttribute = customLookup("attribute", getAttrDcl(top.name, top.env), top.name); } concrete production qNameCons @@ -44,14 +44,14 @@ top::QName ::= id::Name ':' qn::QName { top.name = id.name ++ ":" ++ qn.name; top.unparse = id.unparse ++ ":" ++ qn.unparse; - top.qNameType = qNameTypeCons(id, ':', qn.qNameType, location=top.location); - top.baseNameLoc = qn.baseNameLoc; + top.qNameType = qNameTypeCons(id, ':', qn.qNameType); + top.nameLoc = qn.nameLoc; - top.lookupValue = customLookup("value", getValueDcl(top.name, top.env), top.name, top.location); - top.lookupType = customLookup("type", getTypeDcl(top.name, top.env), top.name, top.location); - top.lookupAttribute = customLookup("attribute", getAttrDcl(top.name, top.env), top.name, top.location); + top.lookupValue = customLookup("value", getValueDcl(top.name, top.env), top.name); + top.lookupType = customLookup("type", getTypeDcl(top.name, top.env), top.name); + top.lookupAttribute = customLookup("attribute", getAttrDcl(top.name, top.env), top.name); } action { - insert semantic token IdGrammarName_t at id.location; + insert semantic token IdGrammarName_t at id.nameLoc; } abstract production qNameError @@ -59,8 +59,8 @@ top::QName ::= msg::[Message] { top.name = "err"; top.unparse = ""; - top.qNameType = qNameTypeId(terminal(IdUpper_t, "Err", top.location), location=top.location); - top.baseNameLoc = top.location; + top.qNameType = qNameTypeId(terminal(IdUpper_t, "Err", top.nameLoc)); + top.nameLoc = getParsedOriginLocationOrFallback(top); top.lookupValue = errorLookup(msg); top.lookupType = errorLookup(msg); @@ -79,13 +79,15 @@ abstract production customLookup attribute fullName {} occurs on a, attribute typeScheme {} occurs on a, annotation sourceLocation occurs on a => -top::QNameLookup ::= kindOfLookup::String dcls::[a] name::String l::Location +top::QNameLookup ::= kindOfLookup::String dcls::[a] name::String { + production loc::Location = getParsedOriginLocationOrFallback(ambientOrigin()); + top.dcls = dcls; top.found = !null(top.dcls); -- currently accurate top.dcl = if top.found then head(top.dcls) - else error("INTERNAL ERROR: Accessing dcl of " ++ kindOfLookup ++ " " ++ name ++ " at " ++ l.unparse); + else error("INTERNAL ERROR: Accessing dcl of " ++ kindOfLookup ++ " " ++ name ++ " at " ++ loc.unparse); top.fullName = if top.found then top.dcl.fullName else "undeclared:value:" ++ name; @@ -93,9 +95,9 @@ top::QNameLookup ::= kindOfLookup::String dcls::[a] name::String l::Location top.errors := (if top.found then [] - else [err(l, "Undeclared " ++ kindOfLookup ++ " '" ++ name ++ "'.")]) ++ + else [err(loc, "Undeclared " ++ kindOfLookup ++ " '" ++ name ++ "'.")]) ++ (if length(top.dcls) <= 1 then [] - else [err(l, "Ambiguous reference to " ++ kindOfLookup ++ " '" ++ name ++ "'. Possibilities are:\n" ++ printPossibilities(top.dcls))]); + else [err(loc, "Ambiguous reference to " ++ kindOfLookup ++ " '" ++ name ++ "'. Possibilities are:\n" ++ printPossibilities(top.dcls))]); } abstract production errorLookup @@ -134,27 +136,27 @@ top::QNameType ::= id::IdUpper_t { top.name = id.lexeme; top.unparse = id.lexeme; - top.baseNameLoc = id.location; + top.nameLoc = id.location; - top.lookupType = customLookup("type", getTypeDcl(top.name, top.env), top.name, top.location); + top.lookupType = customLookup("type", getTypeDcl(top.name, top.env), top.name); } concrete production qNameTypeCons top::QNameType ::= id::Name ':' qn::QNameType { top.name = id.name ++ ":" ++ qn.name; - top.baseNameLoc = qn.baseNameLoc; + top.nameLoc = qn.nameLoc; top.unparse = id.unparse ++ ":" ++ qn.unparse; - top.lookupType = customLookup("type", getTypeDcl(top.name, top.env), top.name, top.location); + top.lookupType = customLookup("type", getTypeDcl(top.name, top.env), top.name); } action { - insert semantic token IdGrammarName_t at id.location; + insert semantic token IdGrammarName_t at id.nameLoc; } {-- - Qualified name looked up CONTEXTUALLY -} -nonterminal QNameAttrOccur with config, name, location, grammarName, env, unparse, attrFor, errors, typerep, dcl, attrDcl, found, attrFound; +tracked nonterminal QNameAttrOccur with config, name, grammarName, env, unparse, attrFor, errors, typerep, dcl, attrDcl, found, attrFound; flowtype QNameAttrOccur = decorate {grammarName, config, env, attrFor}, dcl {grammarName, env, attrFor}, attrDcl {grammarName, env, attrFor}; @@ -215,22 +217,22 @@ top::QNameAttrOccur ::= at::QName -- This is a heuristic error message for the situation where you have a type, but haven't imported -- the grammar declaring that type. (if lastIndexOf(":", top.attrFor.typeName) > 0 && null(getTypeDcl(top.attrFor.typeName, top.env)) then - [err(at.location, "Attribute '" ++ at.name ++ "' does not occur on '" ++ prettyType(top.attrFor) ++ "'. Perhaps import '" ++ substring(0, lastIndexOf(":", top.attrFor.typeName), top.attrFor.typeName) ++ "'?")] + [errFromOrigin(at, "Attribute '" ++ at.name ++ "' does not occur on '" ++ prettyType(top.attrFor) ++ "'. Perhaps import '" ++ substring(0, lastIndexOf(":", top.attrFor.typeName), top.attrFor.typeName) ++ "'?")] else - [err(at.location, "Attribute '" ++ at.name ++ "' does not occur on '" ++ prettyType(top.attrFor) ++ "'. Looked at:\n" ++ printPossibilities(at.lookupAttribute.dcls))] + [errFromOrigin(at, "Attribute '" ++ at.name ++ "' does not occur on '" ++ prettyType(top.attrFor) ++ "'. Looked at:\n" ++ printPossibilities(at.lookupAttribute.dcls))] ) -- If more than one attribute on the same _short name_ occurs, raise ambiguity else if length(attrs) > 1 then - [err(at.location, "Ambiguous reference to attribute occurring on '" ++ prettyType(top.attrFor) ++ "'. Possibilities are:\n" ++ printPossibilities(attrs))] + [errFromOrigin(at, "Ambiguous reference to attribute occurring on '" ++ prettyType(top.attrFor) ++ "'. Possibilities are:\n" ++ printPossibilities(attrs))] -- If this same attribute has multiple occurences (must be due to orphaned occurs) else []; {-if length(dcls) > 1 then - [err(at.location, "There are erroneously multiple attribute occurrences for '" ++ at.name ++ "'. Possibilities are:\n" ++ printPossibilities(dcls))] + [errFromOrigin(at, "There are erroneously multiple attribute occurrences for '" ++ at.name ++ "'. Possibilities are:\n" ++ printPossibilities(dcls))] else [];-} -- TODO: This last bit is disabled because we have problems with importing grammars multiple times. -- TODO FIXME: enable this, and fix the grammar import issues! production resolvedDcl::OccursDclInfo = if top.found then head(dcls) else - error("INTERNAL ERROR: Accessing dcl of occurrence " ++ at.name ++ " at " ++ top.grammarName ++ " " ++ top.location.unparse); + error("INTERNAL ERROR: Accessing dcl of occurrence " ++ at.name ++ " at " ++ top.grammarName ++ " " ++ at.nameLoc.unparse); resolvedDcl.givenNonterminalType = top.attrFor; production resolvedTypeScheme::PolyType = resolvedDcl.typeScheme; production requiredContexts::Contexts = foldContexts(resolvedTypeScheme.contexts); @@ -241,7 +243,7 @@ top::QNameAttrOccur ::= at::QName top.attrDcl = if top.found then head(attrs) else -- Workaround fix for proper error reporting - appairently there are some places where this is still demanded. if at.lookupAttribute.found then at.lookupAttribute.dcl else - error("INTERNAL ERROR: Accessing dcl of attribute " ++ at.name ++ " at " ++ top.grammarName ++ " " ++ top.location.unparse); + error("INTERNAL ERROR: Accessing dcl of attribute " ++ at.name ++ " at " ++ top.grammarName ++ " " ++ at.nameLoc.unparse); } {-- diff --git a/grammars/silver/compiler/definition/core/Root.sv b/grammars/silver/compiler/definition/core/Root.sv index a2126ec8d..963a2bb55 100644 --- a/grammars/silver/compiler/definition/core/Root.sv +++ b/grammars/silver/compiler/definition/core/Root.sv @@ -3,20 +3,20 @@ grammar silver:compiler:definition:core; {-- - Root represents one textual file of Silver source. -} -nonterminal Root with +tracked nonterminal Root with -- Global-level inherited attributes config, compiledGrammars, -- Grammar-level inherited attributes grammarName, env, globalImports, grammarDependencies, -- File-level inherited attributes -- Synthesized attributes - declaredName, unparse, location, errors, defs, occursDefs, moduleNames, importedDefs, importedOccursDefs, + declaredName, unparse, errors, defs, occursDefs, moduleNames, importedDefs, importedOccursDefs, exportedGrammars, optionalGrammars, condBuild, jarName; flowtype Root = decorate {config, compiledGrammars, grammarName, env, globalImports, grammarDependencies, flowEnv}; -nonterminal GrammarDcl with - declaredName, grammarName, location, unparse, errors; +tracked nonterminal GrammarDcl with + declaredName, grammarName, unparse, errors; propagate errors on Root, GrammarDcl; propagate config, compiledGrammars, grammarName, globalImports, grammarDependencies, moduleNames on Root; @@ -70,8 +70,8 @@ top::GrammarDcl ::= 'grammar' qn::QName ';' top.declaredName = qn.name; top.errors <- if qn.name == top.grammarName then [] - else [err(top.location, "Grammar declaration is incorrect: " ++ qn.name)]; + else [errFromOrigin(top, "Grammar declaration is incorrect: " ++ qn.name)]; } action { - insert semantic token IdGrammarName_t at qn.baseNameLoc; + insert semantic token IdGrammarName_t at qn.nameLoc; } diff --git a/grammars/silver/compiler/definition/core/Type.sv b/grammars/silver/compiler/definition/core/Type.sv index 866903ee2..72efe924b 100644 --- a/grammars/silver/compiler/definition/core/Type.sv +++ b/grammars/silver/compiler/definition/core/Type.sv @@ -1,10 +1,10 @@ grammar silver:compiler:definition:core; -- LHS type gives this to 'application' for "foo(...)" calls. -synthesized attribute applicationDispatcher :: (Expr ::= Decorated! Expr Decorated! AppExprs Decorated! AnnoAppExprs Location); +synthesized attribute applicationDispatcher :: (Expr ::= Decorated! Expr Decorated! AppExprs Decorated! AnnoAppExprs); -- LHS type gives this to 'access' for "foo.some" accesses. -- (See DclInfo for the next step) -synthesized attribute accessHandler :: (Expr ::= Decorated! Expr Decorated! QNameAttrOccur Location); +synthesized attribute accessHandler :: (Expr ::= Decorated! Expr Decorated! QNameAttrOccur); -- Used for poor man's type classes -- TODO: Finish removing these and replace with real type classes @@ -15,8 +15,8 @@ attribute applicationDispatcher, accessHandler, instanceNum occurs on Type; aspect default production top::Type ::= { - top.applicationDispatcher = errorApplication(_, _, _, location=_); - top.accessHandler = errorAccessHandler(_, _, location=_); + top.applicationDispatcher = errorApplication; + top.accessHandler = errorAccessHandler; top.instanceNum = false; } @@ -38,7 +38,7 @@ top::Type ::= c::Type a::Type aspect production skolemType top::Type ::= _ { - top.accessHandler = undecoratedAccessHandler(_, _, location=_); + top.accessHandler = undecoratedAccessHandler; } aspect production intType @@ -58,31 +58,31 @@ top::Type ::= fn::String _ data::Boolean _ { top.accessHandler = if data - then dataAccessHandler(_, _, location=_) - else undecoratedAccessHandler(_, _, location=_); + then dataAccessHandler(_, _) + else undecoratedAccessHandler(_, _); } aspect production terminalType top::Type ::= fn::String { - top.accessHandler = terminalAccessHandler(_, _, location=_); + top.accessHandler = terminalAccessHandler; } aspect production decoratedType top::Type ::= te::Type _ { - top.accessHandler = decoratedAccessHandler(_, _, location=_); + top.accessHandler = decoratedAccessHandler; } aspect production uniqueDecoratedType top::Type ::= te::Type _ { - top.accessHandler = decoratedAccessHandler(_, _, location=_); + top.accessHandler = decoratedAccessHandler; } aspect production functionType top::Type ::= _ _ { - top.applicationDispatcher = functionApplication(_, _, _, location=_); + top.applicationDispatcher = functionApplication; } diff --git a/grammars/silver/compiler/definition/core/TypeDecl.sv b/grammars/silver/compiler/definition/core/TypeDecl.sv index 9d18d63d3..84a942b14 100644 --- a/grammars/silver/compiler/definition/core/TypeDecl.sv +++ b/grammars/silver/compiler/definition/core/TypeDecl.sv @@ -10,7 +10,7 @@ top::AGDcl ::= 'type' id::Name tl::BracketedOptTypeExprs '=' te::TypeExpr ';' local isCircular::Boolean = contains(fName, te.mentionedAliases); top.defs := [typeAliasDef( - top.grammarName, id.location, fName, te.mentionedAliases, tl.freeVariables, + top.grammarName, id.nameLoc, fName, te.mentionedAliases, tl.freeVariables, if isCircular then errorType() else te.typerep)]; top.errors <- tl.errorsTyVars; @@ -22,15 +22,15 @@ top::AGDcl ::= 'type' id::Name tl::BracketedOptTypeExprs '=' te::TypeExpr ';' -- Redefinition check of the name top.errors <- if length(getTypeDclAll(fName, top.env)) > 1 - then [err(id.location, "Type '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(id, "Type '" ++ fName ++ "' is already bound.")] else []; top.errors <- if isLower(substring(0,1,id.name)) - then [err(id.location, "Types must be capitalized. Invalid nonterminal name " ++ id.name)] + then [errFromOrigin(id, "Types must be capitalized. Invalid nonterminal name " ++ id.name)] else []; - top.errors <- if isCircular then [err(te.location, s"Definition of ${fName} is self-referential")] else []; + top.errors <- if isCircular then [errFromOrigin(te, s"Definition of ${fName} is self-referential")] else []; } action { - insert semantic token IdTypeDcl_t at id.location; + insert semantic token IdTypeDcl_t at id.nameLoc; } diff --git a/grammars/silver/compiler/definition/env/Context.sv b/grammars/silver/compiler/definition/env/Context.sv index 96209db1b..c6705909b 100644 --- a/grammars/silver/compiler/definition/env/Context.sv +++ b/grammars/silver/compiler/definition/env/Context.sv @@ -9,7 +9,7 @@ propagate env, config, compiledGrammars, grammarFlowTypes on Context, Contexts; -- This mostly exists as a convenient way to perform multiple env-dependant operations -- on a list of contexts without re-decorating them and repeating context resolution. -nonterminal Contexts with env, config, compiledGrammars, grammarFlowTypes, contexts, freeVariables, boundVariables; +tracked nonterminal Contexts with env, config, compiledGrammars, grammarFlowTypes, contexts, freeVariables, boundVariables; propagate boundVariables on Contexts; abstract production consContext diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index 4787dd3fb..3e785bbff 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -261,7 +261,7 @@ top::Expr ::= e::Expr '.' q::QNameAttrOccur } aspect production accessBouncer -top::Expr ::= target::(Expr ::= Decorated! Expr Decorated! QNameAttrOccur Location) e::Expr q::Decorated! QNameAttrOccur +top::Expr ::= target::(Expr ::= Decorated! Expr Decorated! QNameAttrOccur) e::Expr q::Decorated! QNameAttrOccur { propagate flowEnv; e.alwaysDecorated = false; @@ -389,14 +389,14 @@ top::Expr ::= 'decorate' e::Expr 'with' '{' inh::ExprInhs '}' -- this as to the flow analysis, and justifies all the choices below: -- First, generate our "anonymous" flow vertex name: - inh.decorationVertex = "__decorate" ++ toString(genInt()) ++ ":line" ++ toString(top.location.line); + inh.decorationVertex = "__decorate" ++ toString(genInt()) ++ ":line" ++ toString(getParsedOriginLocationOrFallback(top).line); -- Next, emit the "local equation" for this anonymous flow vertex. -- This means only the deps in 'e', see above conceptual transformation to see why. -- N.B. 'inh.flowDefs' will emit 'localInhEq's for this anonymous flow vertex. local eTy::Type = e.finalType; top.flowDefs <- - [anonEq(top.frame.fullName, inh.decorationVertex, eTy.typeName, eTy.isNonterminal, top.location, e.flowDeps)]; + [anonEq(top.frame.fullName, inh.decorationVertex, eTy.typeName, eTy.isNonterminal, getParsedOriginLocationOrFallback(top), e.flowDeps)]; -- Now, we represent ourselves to anything that might use us specially -- as though we were a reference to this anonymous local @@ -612,7 +612,7 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr -- so we DO need to be transitive. Unfortunately. -- hack note: there's a test that depends on this name starting with __scrutinee. grep for it if you have to change this - local anonName :: String = "__scrutinee" ++ toString(genInt()) ++ ":line" ++ toString(e.location.line); + local anonName :: String = "__scrutinee" ++ toString(genInt()) ++ ":line" ++ toString(getParsedOriginLocationOrFallback(e).line); pr.scrutineeVertexType = case e.flowVertexInfo of @@ -629,7 +629,7 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr top.flowDefs <- case e.flowVertexInfo of | just(vertex) -> [] - | nothing() -> [anonEq(top.frame.fullName, anonName, eTy.typeName, eTy.isNonterminal, top.location, e.flowDeps)] + | nothing() -> [anonEq(top.frame.fullName, anonName, eTy.typeName, eTy.isNonterminal, getParsedOriginLocationOrFallback(top), e.flowDeps)] end; -- We want to use anonEq here because that introduces the nonterminal stitch point for our vertex. diff --git a/grammars/silver/compiler/definition/flow/syntax/FlowSpec.sv b/grammars/silver/compiler/definition/flow/syntax/FlowSpec.sv index d5d80c18a..a724d277c 100644 --- a/grammars/silver/compiler/definition/flow/syntax/FlowSpec.sv +++ b/grammars/silver/compiler/definition/flow/syntax/FlowSpec.sv @@ -46,7 +46,7 @@ top::AGDcl ::= 'flowtype' attr::FlowSpec 'on' nts::NtList ';' } -nonterminal FlowSpecs with config, location, grammarName, errors, env, unparse, onNt, specDefs, compiledGrammars, flowEnv; +tracked nonterminal FlowSpecs with config, grammarName, errors, env, unparse, onNt, specDefs, compiledGrammars, flowEnv; propagate config, grammarName, errors, env, onNt, specDefs, compiledGrammars, flowEnv on FlowSpecs; @@ -61,7 +61,7 @@ top::FlowSpecs ::= h::FlowSpecs ',' t::FlowSpec top.unparse = h.unparse ++ ", " ++ t.unparse; } -nonterminal FlowSpec with config, location, grammarName, errors, env, unparse, onNt, specDefs, compiledGrammars, flowEnv; +tracked nonterminal FlowSpec with config, grammarName, errors, env, unparse, onNt, specDefs, compiledGrammars, flowEnv; inherited attribute onNt :: Type; @@ -76,12 +76,12 @@ top::FlowSpec ::= attr::FlowSpecId '{' inhs::FlowSpecInhs '}' if !attr.found || isExportedBy(top.grammarName, [attr.authorityGrammar], top.compiledGrammars) then [] - else [err(attr.location, "flow type for " ++ attr.name ++ " must be exported by " ++ attr.authorityGrammar)]; + else [errFromOrigin(attr, "flow type for " ++ attr.name ++ " must be exported by " ++ attr.authorityGrammar)]; top.errors <- if attr.found && length(filter(eq(attr.synName, _), getSpecifiedSynsForNt(top.onNt.typeName, top.flowEnv))) > 1 - then [err(attr.location, "duplicate specification of flow type for " ++ attr.name ++ " on " ++ top.onNt.typeName)] + then [errFromOrigin(attr, "duplicate specification of flow type for " ++ attr.name ++ " on " ++ top.onNt.typeName)] else []; -- oh no again! @@ -95,11 +95,11 @@ top::FlowSpec ::= attr::FlowSpecId '{' inhs::FlowSpecInhs '}' isExportedBy(attr.authorityGrammar, [hackGramFromFName(top.onNt.typeName)], top.compiledGrammars) || null(missingFt) then [] - else [err(attr.location, attr.name ++ " is an extension synthesized attribute, and must contain at least the forward flow type. It is missing " ++ implode(", ", missingFt))]; + else [errFromOrigin(attr, attr.name ++ " is an extension synthesized attribute, and must contain at least the forward flow type. It is missing " ++ implode(", ", missingFt))]; top.errors <- if attr.found && contains(attr.synName, inhs.refList) - then [err(top.location, s"circularity in flow specification for ${attr.name} on ${top.onNt.typeName}")] + then [errFromOrigin(top, s"circularity in flow specification for ${attr.name} on ${top.onNt.typeName}")] else []; -- We want to put the spec in even if there are errors in 'inhs' so that @@ -109,7 +109,7 @@ top::FlowSpec ::= attr::FlowSpecId '{' inhs::FlowSpecInhs '}' else [(top.onNt.typeName, attr.synName, if contains(attr.synName, inhs.refList) then [] else inhs.inhList, inhs.refList)]; } -nonterminal FlowSpecId with config, location, grammarName, errors, env, unparse, onNt, synName, authorityGrammar, found, name; +tracked nonterminal FlowSpecId with config, grammarName, errors, env, unparse, onNt, synName, authorityGrammar, found, name; synthesized attribute synName :: String; synthesized attribute authorityGrammar :: String; @@ -129,7 +129,7 @@ top::FlowSpecId ::= syn::QNameAttrOccur top.errors <- if !syn.found || syn.attrDcl.isSynthesized then [] - else [err(syn.location, syn.name ++ " is not a synthesized attribute, and so cannot have a flow type")]; + else [errFromOrigin(syn, syn.name ++ " is not a synthesized attribute, and so cannot have a flow type")]; } concrete production forwardSpecId @@ -153,7 +153,7 @@ top::FlowSpecId ::= 'decorate' } -nonterminal FlowSpecInhs with config, location, grammarName, errors, env, unparse, onNt, inhList, refList, flowEnv; +tracked nonterminal FlowSpecInhs with config, grammarName, errors, env, unparse, onNt, inhList, refList, flowEnv; monoid attribute inhList :: [String]; -- The attributes in the flow specification monoid attribute refList :: [String]; -- Flow specifications referenced in this one (currently can only contain "decorate" / "forward") @@ -176,7 +176,7 @@ top::FlowSpecInhs ::= h::FlowSpecInh ',' t::FlowSpecInhs top.unparse = h.unparse ++ ", " ++ t.unparse; } -nonterminal FlowSpecInh with config, location, grammarName, errors, env, unparse, onNt, inhList, refList, flowEnv; +tracked nonterminal FlowSpecInh with config, grammarName, errors, env, unparse, onNt, inhList, refList, flowEnv; flowtype FlowSpecInh = forward {grammarName, env, flowEnv, onNt}, inhList {forward}, errors {forward}; @@ -193,7 +193,7 @@ top::FlowSpecInh ::= inh::QNameAttrOccur top.errors <- if !inh.found || inh.attrDcl.isInherited then [] - else [err(inh.location, inh.name ++ " is not an inherited attribute and so cannot be within a flow type")]; + else [errFromOrigin(inh, inh.name ++ " is not an inherited attribute and so cannot be within a flow type")]; } concrete production flowSpecTrans @@ -211,10 +211,10 @@ top::FlowSpecInh ::= transSyn::QNameAttrOccur '.' inh::QNameAttrOccur top.errors <- if !transSyn.found || transSyn.attrDcl.isSynthesized && transSyn.attrDcl.isTranslation then [] - else [err(transSyn.location, transSyn.name ++ " is not a translation attribute and so cannot be within a flow type")]; + else [errFromOrigin(transSyn, transSyn.name ++ " is not a translation attribute and so cannot be within a flow type")]; top.errors <- if !inh.found || inh.attrDcl.isInherited then [] - else [err(inh.location, inh.name ++ " is not an inherited attribute and so cannot be within a flow type")]; + else [errFromOrigin(inh, inh.name ++ " is not an inherited attribute and so cannot be within a flow type")]; } {-- @@ -246,9 +246,9 @@ top::FlowSpecInh ::= 'decorate' case top.onNt, decSpec of | nonterminalType(_, _, _, _), just(_) -> [] | nonterminalType(_, _, _, _), nothing() -> - [err(top.location, s"to use the default reference set for nonterminal ${top.onNt.typeName}, 'decorate' must also have an explicit flow type")] + [errFromOrigin(top, s"to use the default reference set for nonterminal ${top.onNt.typeName}, 'decorate' must also have an explicit flow type")] | errorType(), _ -> [] - | _, _ -> [err(top.location, s"default reference set can only be used with nonterminal types, not ${prettyType(top.onNt)}")] + | _, _ -> [errFromOrigin(top, s"default reference set can only be used with nonterminal types, not ${prettyType(top.onNt)}")] end; top.inhList := fromMaybe(([], []), decSpec).fst; @@ -267,7 +267,7 @@ top::FlowSpecInh ::= 'forward' case forwardSpec of | just(_) -> [] | nothing() -> - [err(top.location, s"to use the forward set for nonterminal ${top.onNt.typeName} in a flow type, 'forward' must also have an explicit flow type")] + [errFromOrigin(top, s"to use the forward set for nonterminal ${top.onNt.typeName} in a flow type, 'forward' must also have an explicit flow type")] end; top.inhList := fromMaybe(([], []), forwardSpec).fst; @@ -275,7 +275,7 @@ top::FlowSpecInh ::= 'forward' } -nonterminal NtList with config, location, grammarName, errors, env, unparse, flowSpecSpec, specDefs, compiledGrammars, flowEnv; +tracked nonterminal NtList with config, grammarName, errors, env, unparse, flowSpecSpec, specDefs, compiledGrammars, flowEnv; propagate config, grammarName, errors, env, flowSpecSpec, specDefs, compiledGrammars, flowEnv on NtList; @@ -295,7 +295,7 @@ top::NtList ::= h::NtName ',' t::NtList top.unparse = h.unparse ++ ", " ++ t.unparse; } -nonterminal NtName with config, location, grammarName, errors, env, unparse, flowSpecSpec, specDefs, compiledGrammars, flowEnv; +tracked nonterminal NtName with config, grammarName, errors, env, unparse, flowSpecSpec, specDefs, compiledGrammars, flowEnv; propagate config, grammarName, env, compiledGrammars, flowEnv on NtName; diff --git a/grammars/silver/compiler/definition/origins/BlockContext.sv b/grammars/silver/compiler/definition/origins/BlockContext.sv index 948781124..8b3d64c26 100644 --- a/grammars/silver/compiler/definition/origins/BlockContext.sv +++ b/grammars/silver/compiler/definition/origins/BlockContext.sv @@ -2,6 +2,11 @@ import silver:compiler:definition:core; import silver:compiler:definition:env; import silver:compiler:definition:flow:driver; +data ContextOriginInfoSource + = useContextLhsAndRules + | useRuntimePassedInfo + | useBogusInfo name::String; + {-- - Does code generated in this block need to reference originsCtx, or can it - get information from the frame's left-hand-side and rules? Effectively, is @@ -9,26 +14,6 @@ import silver:compiler:definition:flow:driver; -} synthesized attribute originsContextSource :: ContextOriginInfoSource occurs on BlockContext; -nonterminal ContextOriginInfoSource; - -abstract production useContextLhsAndRules -top::ContextOriginInfoSource ::= -{ - -} - -abstract production useRuntimePassedInfo -top::ContextOriginInfoSource ::= -{ - -} - -abstract production useBogusInfo -top::ContextOriginInfoSource ::= name::String -{ - -} - aspect production functionContext top::BlockContext ::= sig::NamedSignature g::ProductionGraph { diff --git a/grammars/silver/compiler/definition/type/Kind.sv b/grammars/silver/compiler/definition/type/Kind.sv index 33640f389..91af94dad 100644 --- a/grammars/silver/compiler/definition/type/Kind.sv +++ b/grammars/silver/compiler/definition/type/Kind.sv @@ -3,7 +3,7 @@ grammar silver:compiler:definition:type; synthesized attribute baseKind::Kind; synthesized attribute argKinds::[Kind]; -nonterminal Kind with compareTo, isEqual, baseKind, argKinds; +tracked nonterminal Kind with compareTo, isEqual, baseKind, argKinds; propagate compareTo, isEqual on Kind; aspect default production diff --git a/grammars/silver/compiler/definition/type/Type.sv b/grammars/silver/compiler/definition/type/Type.sv index 2310286de..979f0ea0e 100644 --- a/grammars/silver/compiler/definition/type/Type.sv +++ b/grammars/silver/compiler/definition/type/Type.sv @@ -13,7 +13,7 @@ synthesized attribute monoType :: Type; -- Raises on error when we encounter a p {-- - Represents a type, quantified over some type variables. -} -nonterminal PolyType with boundVars, contexts, typerep, monoType; +tracked nonterminal PolyType with boundVars, contexts, typerep, monoType; flowtype PolyType = decorate {}, forward {}; @@ -48,7 +48,7 @@ top::PolyType ::= bound::[TyVar] contexts::[Context] ty::Type - Represents a constraint on a type, e.g. a type class instance -} -nonterminal Context with freeVariables; +tracked nonterminal Context with freeVariables; abstract production instContext top::Context ::= cls::String t::Type @@ -95,7 +95,7 @@ top::Context ::= msg::String {-- - Silver Type Representations. -} -nonterminal Type with kindrep, freeVariables; +tracked nonterminal Type with kindrep, freeVariables; flowtype Type = decorate {}, forward {}; @@ -337,7 +337,7 @@ top::Type ::= params::Integer namedParams::[String] -------------------------------------------------------------------------------- -nonterminal TyVar with kindrep, compareTo, isEqual; +tracked nonterminal TyVar with kindrep, compareTo, isEqual; propagate compareTo, isEqual on TyVar; -- In essence, this should be 'private' to this file. diff --git a/grammars/silver/compiler/definition/type/syntax/AspectDcl.sv b/grammars/silver/compiler/definition/type/syntax/AspectDcl.sv index c1f10a5a5..a144019c2 100644 --- a/grammars/silver/compiler/definition/type/syntax/AspectDcl.sv +++ b/grammars/silver/compiler/definition/type/syntax/AspectDcl.sv @@ -22,7 +22,7 @@ top::AGDcl ::= 'aspect' 'production' id::QName ns::AspectProductionSignature bod production attribute allLexicalTyVars :: [String]; allLexicalTyVars = nub(ns.lexicalTypeVariables); - sigDefs <- addNewLexicalTyVars_ActuallyVariables(top.grammarName, top.location, ns.lexicalTyVarKinds, allLexicalTyVars); + sigDefs <- addNewLexicalTyVars_ActuallyVariables(top.grammarName, id.nameLoc, ns.lexicalTyVarKinds, allLexicalTyVars); } aspect production aspectFunctionDcl @@ -31,7 +31,7 @@ top::AGDcl ::= 'aspect' 'function' id::QName ns::AspectFunctionSignature body::P production attribute allLexicalTyVars :: [String]; allLexicalTyVars = nub(ns.lexicalTypeVariables); - sigDefs <- addNewLexicalTyVars_ActuallyVariables(top.grammarName, top.location, ns.lexicalTyVarKinds, allLexicalTyVars); + sigDefs <- addNewLexicalTyVars_ActuallyVariables(top.grammarName, id.nameLoc, ns.lexicalTyVarKinds, allLexicalTyVars); } propagate lexicalTypeVariables on AspectProductionLHS, AspectFunctionLHS, AspectRHS, AspectRHSElem excluding aspectRHSElemCons; diff --git a/grammars/silver/compiler/definition/type/syntax/ClassDcl.sv b/grammars/silver/compiler/definition/type/syntax/ClassDcl.sv index 503ef3a67..e26b06b58 100644 --- a/grammars/silver/compiler/definition/type/syntax/ClassDcl.sv +++ b/grammars/silver/compiler/definition/type/syntax/ClassDcl.sv @@ -6,5 +6,5 @@ top::AGDcl ::= 'class' cl::ConstraintList '=>' id::QNameType var::TypeExpr '{' b production attribute allLexicalTyVars :: [String]; allLexicalTyVars = nub(cl.lexicalTypeVariables ++ var.lexicalTypeVariables ++ body.lexicalTypeVariables); - headPreDefs <- addNewLexicalTyVars(top.grammarName, top.location, cl.lexicalTyVarKinds ++ var.lexicalTyVarKinds ++ body.lexicalTyVarKinds, allLexicalTyVars); + headPreDefs <- addNewLexicalTyVars(top.grammarName, cl.lexicalTyVarKinds ++ var.lexicalTyVarKinds ++ body.lexicalTyVarKinds, allLexicalTyVars); } diff --git a/grammars/silver/compiler/definition/type/syntax/Constraint.sv b/grammars/silver/compiler/definition/type/syntax/Constraint.sv index 79f23160a..342cd1eeb 100644 --- a/grammars/silver/compiler/definition/type/syntax/Constraint.sv +++ b/grammars/silver/compiler/definition/type/syntax/Constraint.sv @@ -2,13 +2,13 @@ grammar silver:compiler:definition:type:syntax; inherited attribute constraintPos::ConstraintPosition; -nonterminal ConstraintList +tracked nonterminal ConstraintList -- This grammar doesn't export silver:compiler:definition:core, so the type concrete -- syntax doesn't "know about" the core layout terminals. -- Thus we have to set the layout explicitly for the "root" nonterminal here. layout {BlockComments, Comments, WhiteSpace} - with config, grammarName, env, flowEnv, location, unparse, errors, defs, occursDefs, contexts, lexicalTypeVariables, lexicalTyVarKinds, constraintPos; -nonterminal Constraint with config, grammarName, env, flowEnv, location, unparse, errors, defs, occursDefs, contexts, lexicalTypeVariables, lexicalTyVarKinds, constraintPos; + with config, grammarName, env, flowEnv, unparse, errors, defs, occursDefs, contexts, lexicalTypeVariables, lexicalTyVarKinds, constraintPos; +tracked nonterminal Constraint with config, grammarName, env, flowEnv, unparse, errors, defs, occursDefs, contexts, lexicalTypeVariables, lexicalTyVarKinds, constraintPos; flowtype Constraint = decorate {grammarName, env, flowEnv, constraintPos}; @@ -48,7 +48,7 @@ top::Constraint ::= c::QNameType t::TypeExpr top.errors <- c.lookupType.errors; top.errors <- if c.lookupType.found && dcl.isClass then [] - else [err(c.location, c.name ++ " is not a type class.")]; + else [errFromOrigin(c, c.name ++ " is not a type class.")]; top.errors <- t.errorsTyVars; -- We essentially permit FlexibleInstances but not UndecidableInstnaces, @@ -67,7 +67,7 @@ top::Constraint ::= c::QNameType t::TypeExpr production undecidableInstanceErrors::[Message] = case top.constraintPos.instanceHead of | just(h) when (h, contains(fName, undecidableInstanceClasses)) matches (instContext(_, skolemType(_)), false) -> - [err(top.location, s"The constraint ${top.unparse} is no smaller than the instance head ${prettyContext(h)}")] + [errFromOrigin(top, s"The constraint ${top.unparse} is no smaller than the instance head ${prettyContext(h)}")] | _ -> [] end; top.errors <- undecidableInstanceErrors; @@ -86,7 +86,7 @@ top::Constraint ::= c::QNameType t::TypeExpr | _ -> [] end; } action { - insert semantic token IdTypeClass_t at c.baseNameLoc; + insert semantic token IdTypeClass_t at c.nameLoc; } concrete production inhOccursConstraint @@ -101,22 +101,22 @@ top::Constraint ::= 'attribute' at::QName attl::BracketedOptTypeExprs 'occurs' ' top.errors <- at.lookupAttribute.errors; top.errors <- if at.lookupAttribute.found && !dcl.isInherited - then [err(at.location, fName ++ " is not an inherited attribute")] + then [errFromOrigin(at, fName ++ " is not an inherited attribute")] else []; top.errors <- if attl.missingCount > 0 - then [err(attl.location, "Attribute type arguments cannot contain _")] + then [errFromOrigin(attl, "Attribute type arguments cannot contain _")] else []; -- Make sure we get the number and kind of type variables correct for the ATTR top.errors <- if length(atTypeScheme.boundVars) != length(attl.types) - then [err(at.location, + then [errFromOrigin(at, at.name ++ " expects " ++ toString(length(atTypeScheme.boundVars)) ++ " type variables, but " ++ toString(length(attl.types)) ++ " were provided.")] else if map((.kindrep), atTypeScheme.boundVars) != map((.kindrep), attl.types) - then [err(at.location, + then [errFromOrigin(at, at.name ++ " has kind " ++ prettyKind(foldr(arrowKind, starKind(), map((.kindrep), atTypeScheme.boundVars))) ++ "but type variable(s) have kind(s) " ++ implode(", ", map(compose(prettyKind, (.kindrep)), attl.types)) ++ ".")] else []; @@ -143,29 +143,29 @@ top::Constraint ::= 'attribute' at::QName attl::BracketedOptTypeExprs i::TypeExp top.errors <- at.lookupAttribute.errors; top.errors <- if at.lookupAttribute.found && !dcl.isSynthesized - then [err(at.location, fName ++ " is not a synthesized attribute")] + then [errFromOrigin(at, fName ++ " is not a synthesized attribute")] else []; top.errors <- if attl.missingCount > 0 - then [err(attl.location, "Attribute type arguments cannot contain _")] + then [errFromOrigin(attl, "Attribute type arguments cannot contain _")] else []; -- Make sure we get the number and kind of type variables correct for the ATTR top.errors <- if length(atTypeScheme.boundVars) != length(attl.types) - then [err(at.location, + then [errFromOrigin(at, at.name ++ " expects " ++ toString(length(atTypeScheme.boundVars)) ++ " type variables, but " ++ toString(length(attl.types)) ++ " were provided.")] else if map((.kindrep), atTypeScheme.boundVars) != map((.kindrep), attl.types) - then [err(at.location, + then [errFromOrigin(at, at.name ++ " has kind " ++ prettyKind(foldr(arrowKind, starKind(), map((.kindrep), atTypeScheme.boundVars))) ++ "but type variable(s) have kind(s) " ++ implode(", ", map(compose(prettyKind, (.kindrep)), attl.types)) ++ ".")] else []; top.errors <- if i.typerep.kindrep != inhSetKind() - then [err(i.location, s"${i.unparse} has kind ${prettyKind(i.typerep.kindrep)}, but kind InhSet is expected here")] + then [errFromOrigin(i, s"${i.unparse} has kind ${prettyKind(i.typerep.kindrep)}, but kind InhSet is expected here")] else []; top.errors <- t.errorsKindStar; @@ -196,22 +196,22 @@ top::Constraint ::= 'annotation' at::QName attl::BracketedOptTypeExprs 'occurs' top.errors <- at.lookupAttribute.errors; top.errors <- if at.lookupAttribute.found && !dcl.isAnnotation - then [err(at.location, fName ++ " is not an annotation")] + then [errFromOrigin(at, fName ++ " is not an annotation")] else []; top.errors <- if attl.missingCount > 0 - then [err(attl.location, "Annotation type arguments cannot contain _")] + then [errFromOrigin(attl, "Annotation type arguments cannot contain _")] else []; -- Make sure we get the number and kind of type variables correct for the ATTR top.errors <- if length(atTypeScheme.boundVars) != length(attl.types) - then [err(at.location, + then [errFromOrigin(at, at.name ++ " expects " ++ toString(length(atTypeScheme.boundVars)) ++ " type variables, but " ++ toString(length(attl.types)) ++ " were provided.")] else if map((.kindrep), atTypeScheme.boundVars) != map((.kindrep), attl.types) - then [err(at.location, + then [errFromOrigin(at, at.name ++ " has kind " ++ prettyKind(foldr(arrowKind, starKind(), map((.kindrep), atTypeScheme.boundVars))) ++ "but type variable(s) have kind(s) " ++ implode(", ", map(compose(prettyKind, (.kindrep)), attl.types)) ++ ".")] else []; @@ -247,11 +247,11 @@ top::Constraint ::= i1::TypeExpr 'subset' i2::TypeExpr top.errors <- if i1.typerep.kindrep != inhSetKind() - then [err(top.location, s"${top.unparse} has kind ${prettyKind(i1.typerep.kindrep)}, but kind InhSet is expected here")] + then [errFromOrigin(top, s"${top.unparse} has kind ${prettyKind(i1.typerep.kindrep)}, but kind InhSet is expected here")] else []; top.errors <- if i2.typerep.kindrep != inhSetKind() - then [err(top.location, s"${top.unparse} has kind ${prettyKind(i2.typerep.kindrep)}, but kind InhSet is expected here")] + then [errFromOrigin(top, s"${top.unparse} has kind ${prettyKind(i2.typerep.kindrep)}, but kind InhSet is expected here")] else []; local instDcl::InstDclInfo = top.constraintPos.inhSubsetInstDcl(i1.typerep, i2.typerep, top.grammarName, top.location); @@ -262,7 +262,7 @@ top::Constraint ::= i1::TypeExpr 'subset' i2::TypeExpr end; top.errors <- case top.constraintPos of - | classPos(_, _) -> [err(top.location, "subset constraint not permitted as superclass")] + | classPos(_, _) -> [errFromOrigin(top, "subset constraint not permitted as superclass")] | _ -> [] end; @@ -287,7 +287,7 @@ top::Constraint ::= 'typeError' msg::String_t top.errors <- case top.constraintPos of | instancePos(_, _) -> [] - | _ -> [err(top.location, "typeError constraint is only permitted on instances")] + | _ -> [errFromOrigin(top, "typeError constraint is only permitted on instances")] end; } @@ -297,7 +297,7 @@ synthesized attribute typeableInstDcl::(InstDclInfo ::= Type String Location); synthesized attribute inhSubsetInstDcl::(InstDclInfo ::= Type Type String Location); synthesized attribute classDefName::Maybe; synthesized attribute instanceHead::Maybe; -nonterminal ConstraintPosition with classInstDcl, occursInstDcl, typeableInstDcl, inhSubsetInstDcl, classDefName, instanceHead; +tracked nonterminal ConstraintPosition with classInstDcl, occursInstDcl, typeableInstDcl, inhSubsetInstDcl, classDefName, instanceHead; aspect default production top::ConstraintPosition ::= diff --git a/grammars/silver/compiler/definition/type/syntax/FunctionDcl.sv b/grammars/silver/compiler/definition/type/syntax/FunctionDcl.sv index 3d870ab20..7d0855f0e 100644 --- a/grammars/silver/compiler/definition/type/syntax/FunctionDcl.sv +++ b/grammars/silver/compiler/definition/type/syntax/FunctionDcl.sv @@ -8,7 +8,7 @@ top::AGDcl ::= 'function' id::Name ns::FunctionSignature body::ProductionBody production attribute allLexicalTyVars :: [String]; allLexicalTyVars = nub(ns.lexicalTypeVariables); - sigDefs <- addNewLexicalTyVars(top.grammarName, top.location, ns.lexicalTyVarKinds, allLexicalTyVars); + sigDefs <- addNewLexicalTyVars(top.grammarName, ns.lexicalTyVarKinds, allLexicalTyVars); } aspect production functionSignature diff --git a/grammars/silver/compiler/definition/type/syntax/InstanceDcl.sv b/grammars/silver/compiler/definition/type/syntax/InstanceDcl.sv index 814c3d505..f65f69850 100644 --- a/grammars/silver/compiler/definition/type/syntax/InstanceDcl.sv +++ b/grammars/silver/compiler/definition/type/syntax/InstanceDcl.sv @@ -6,5 +6,5 @@ top::AGDcl ::= 'instance' cl::ConstraintList '=>' id::QNameType ty::TypeExpr '{' production attribute allLexicalTyVars :: [String]; allLexicalTyVars = nub(cl.lexicalTypeVariables ++ ty.lexicalTypeVariables); - headPreDefs <- addNewLexicalTyVars(top.grammarName, top.location, cl.lexicalTyVarKinds ++ ty.lexicalTyVarKinds, allLexicalTyVars); + headPreDefs <- addNewLexicalTyVars(top.grammarName, cl.lexicalTyVarKinds ++ ty.lexicalTyVarKinds, allLexicalTyVars); } diff --git a/grammars/silver/compiler/definition/type/syntax/KindExpr.sv b/grammars/silver/compiler/definition/type/syntax/KindExpr.sv index 48518b3b0..613d61eac 100644 --- a/grammars/silver/compiler/definition/type/syntax/KindExpr.sv +++ b/grammars/silver/compiler/definition/type/syntax/KindExpr.sv @@ -1,6 +1,6 @@ grammar silver:compiler:definition:type:syntax; -nonterminal KindExpr with config, location, grammarName, errors, env, unparse, kindrep; +tracked nonterminal KindExpr with config, grammarName, errors, env, unparse, kindrep; propagate errors on KindExpr; -- TODO: Are errors even possible here? diff --git a/grammars/silver/compiler/definition/type/syntax/ProductionDcl.sv b/grammars/silver/compiler/definition/type/syntax/ProductionDcl.sv index 0f0acac35..e457072ab 100644 --- a/grammars/silver/compiler/definition/type/syntax/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/type/syntax/ProductionDcl.sv @@ -10,7 +10,7 @@ top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::Pr production attribute allLexicalTyVars :: [String]; allLexicalTyVars = nub(ns.lexicalTypeVariables); - sigDefs <- addNewLexicalTyVars(top.grammarName, top.location, ns.lexicalTyVarKinds, allLexicalTyVars); + sigDefs <- addNewLexicalTyVars(top.grammarName, ns.lexicalTyVarKinds, allLexicalTyVars); } propagate lexicalTyVarKinds on ProductionSignature, ProductionLHS, ProductionRHS, ProductionRHSElem; diff --git a/grammars/silver/compiler/definition/type/syntax/TypeExpr.sv b/grammars/silver/compiler/definition/type/syntax/TypeExpr.sv index af2ca8681..8c4950bb5 100644 --- a/grammars/silver/compiler/definition/type/syntax/TypeExpr.sv +++ b/grammars/silver/compiler/definition/type/syntax/TypeExpr.sv @@ -6,13 +6,13 @@ imports silver:compiler:definition:env; imports silver:compiler:definition:flow:syntax; imports silver:compiler:definition:flow:env; -nonterminal TypeExpr with config, location, grammarName, errors, env, flowEnv, unparse, typerep, lexicalTypeVariables, lexicalTyVarKinds, errorsTyVars, errorsKindStar, freeVariables, mentionedAliases, onNt, errorsInhSet, typerepInhSet; -nonterminal Signature with config, location, grammarName, errors, env, flowEnv, unparse, typerep, lexicalTypeVariables, lexicalTyVarKinds, mentionedAliases; -nonterminal SignatureLHS with config, location, grammarName, errors, env, flowEnv, unparse, maybeType, lexicalTypeVariables, lexicalTyVarKinds, mentionedAliases; -nonterminal TypeExprs with config, location, grammarName, errors, env, unparse, flowEnv, types, missingCount, lexicalTypeVariables, lexicalTyVarKinds, appArgKinds, appLexicalTyVarKinds, errorsTyVars, errorsKindStar, freeVariables, mentionedAliases; -nonterminal BracketedTypeExprs with config, location, grammarName, errors, env, flowEnv, unparse, types, missingCount, lexicalTypeVariables, lexicalTyVarKinds, appArgKinds, appLexicalTyVarKinds, errorsTyVars, freeVariables, mentionedAliases, envBindingTyVars, initialEnv; -nonterminal BracketedOptTypeExprs with config, location, grammarName, errors, env, flowEnv, unparse, types, missingCount, lexicalTypeVariables, lexicalTyVarKinds, appArgKinds, appLexicalTyVarKinds, errorsTyVars, freeVariables, mentionedAliases, envBindingTyVars, initialEnv; -nonterminal NamedTypeExprs with config, location, grammarName, errors, env, unparse, flowEnv, namedTypes, lexicalTypeVariables, lexicalTyVarKinds, errorsKindStar, freeVariables, mentionedAliases; +tracked nonterminal TypeExpr with config, grammarName, errors, env, flowEnv, unparse, typerep, lexicalTypeVariables, lexicalTyVarKinds, errorsTyVars, errorsKindStar, freeVariables, mentionedAliases, onNt, errorsInhSet, typerepInhSet; +tracked nonterminal Signature with config, grammarName, errors, env, flowEnv, unparse, typerep, lexicalTypeVariables, lexicalTyVarKinds, mentionedAliases; +tracked nonterminal SignatureLHS with config, grammarName, errors, env, flowEnv, unparse, maybeType, lexicalTypeVariables, lexicalTyVarKinds, mentionedAliases; +tracked nonterminal TypeExprs with config, grammarName, errors, env, unparse, flowEnv, types, missingCount, lexicalTypeVariables, lexicalTyVarKinds, appArgKinds, appLexicalTyVarKinds, errorsTyVars, errorsKindStar, freeVariables, mentionedAliases; +tracked nonterminal BracketedTypeExprs with config, grammarName, errors, env, flowEnv, unparse, types, missingCount, lexicalTypeVariables, lexicalTyVarKinds, appArgKinds, appLexicalTyVarKinds, errorsTyVars, freeVariables, mentionedAliases, envBindingTyVars, initialEnv; +tracked nonterminal BracketedOptTypeExprs with config, grammarName, errors, env, flowEnv, unparse, types, missingCount, lexicalTypeVariables, lexicalTyVarKinds, appArgKinds, appLexicalTyVarKinds, errorsTyVars, freeVariables, mentionedAliases, envBindingTyVars, initialEnv; +tracked nonterminal NamedTypeExprs with config, grammarName, errors, env, unparse, flowEnv, namedTypes, lexicalTypeVariables, lexicalTyVarKinds, errorsKindStar, freeVariables, mentionedAliases; synthesized attribute maybeType :: Maybe; synthesized attribute types :: [Type]; @@ -68,9 +68,10 @@ propagate errorsKindStar on TypeExprs, NamedTypeExprs; propagate mentionedAliases on TypeExpr, Signature, SignatureLHS, TypeExprs, BracketedTypeExprs, BracketedOptTypeExprs, NamedTypeExprs; function addNewLexicalTyVars -[Def] ::= gn::String sl::Location lk::[Pair] l::[String] +[Def] ::= gn::String lk::[Pair] l::[String] { - return map(\ n::String -> lexTyVarDef(gn, sl, n, freshTyVarNamed(fromMaybe(starKind(), lookup(n, lk)), n)), l); + local loc::Location = getParsedOriginLocationOrFallback(ambientOrigin()); + return map(\ n::String -> lexTyVarDef(gn, loc, n, freshTyVarNamed(fromMaybe(starKind(), lookup(n, lk)), n)), l); } aspect default production @@ -79,11 +80,11 @@ top::TypeExpr ::= -- This has to do with type lists that are type variables only. -- We don't have a separate nonterminal for this, because we'd like to produce -- "semantic" errors, rather than parse errors for this. - top.errorsTyVars := [err(top.location, top.unparse ++ " is not permitted here, only type variables are")]; + top.errorsTyVars := [errFromOrigin(top, top.unparse ++ " is not permitted here, only type variables are")]; top.freeVariables = top.typerep.freeVariables; top.errorsKindStar := if top.typerep.kindrep != starKind() - then [err(top.location, s"${top.unparse} has kind ${prettyKind(top.typerep.kindrep)}, but kind * is expected here")] + then [errFromOrigin(top, s"${top.unparse} has kind ${prettyKind(top.typerep.kindrep)}, but kind * is expected here")] else []; top.errorsInhSet = top.errors; top.typerepInhSet = top.typerep; @@ -110,7 +111,7 @@ top::TypeExpr ::= t::Type case t of | varType(_) -> [] | skolemType(_) -> [] - | _ -> [err(top.location, top.unparse ++ " is not permitted here, only type variables are")] + | _ -> [errFromOrigin(top, top.unparse ++ " is not permitted here, only type variables are")] end; } @@ -189,12 +190,12 @@ top::TypeExpr ::= q::QNameType top.errors <- if !q.lookupType.found || q.lookupType.dcl.isType then [] else if q.lookupType.dcl.isTypeAlias -- Raise a less confusing error if we see an unapplied type alias - then [err(top.location, q.name ++ " is a type alias, expecting " ++ toString(length(q.lookupType.dcl.typeScheme.boundVars)) ++ " type arguments.")] - else [err(top.location, q.name ++ " is not a type.")]; + then [errFromOrigin(top, q.name ++ " is a type alias, expecting " ++ toString(length(q.lookupType.dcl.typeScheme.boundVars)) ++ " type arguments.")] + else [errFromOrigin(top, q.name ++ " is not a type.")]; top.typerep = q.lookupType.typeScheme.typerep; -- NOT .monoType since this can be a polyType when an error is raised } action { - insert semantic token IdType_t at q.baseNameLoc; + insert semantic token IdType_t at q.nameLoc; } concrete production typeVariableTypeExpr @@ -203,7 +204,7 @@ top::TypeExpr ::= tv::IdLower_t top.unparse = tv.lexeme; local attribute hack::QNameLookup; - hack = customLookup("type", getTypeDcl(tv.lexeme, top.env), tv.lexeme, top.location); + hack = customLookup("type", getTypeDcl(tv.lexeme, top.env), tv.lexeme); top.typerep = hack.typeScheme.monoType; top.errors <- hack.errors; @@ -220,7 +221,7 @@ top::TypeExpr ::= '(' tv::IdLower_t '::' k::KindExpr ')' top.unparse = s"(${tv.lexeme} :: ${k.unparse})"; local attribute hack::QNameLookup; - hack = customLookup("type", getTypeDcl(tv.lexeme, top.env), tv.lexeme, top.location); + hack = customLookup("type", getTypeDcl(tv.lexeme, top.env), tv.lexeme); top.typerep = hack.typeScheme.monoType; top.errors <- hack.errors; @@ -245,8 +246,8 @@ top::TypeExpr ::= ty::TypeExpr tl::BracketedTypeExprs | nominalTypeExpr(q) when q.lookupType.found && q.lookupType.dcl.isTypeAlias && length(q.lookupType.typeScheme.boundVars) > 0 -> - aliasAppTypeExpr(q, tl, location=top.location) - | _ -> typeAppTypeExpr(ty, tl, location=top.location) + aliasAppTypeExpr(q, tl) + | _ -> typeAppTypeExpr(ty, tl) end; } @@ -263,11 +264,11 @@ top::TypeExpr ::= q::Decorated QNameType with {env} tl::BracketedTypeExprs local tlCount::Integer = length(tl.types) + tl.missingCount; top.errors <- if tlCount != length(ts.boundVars) - then [err(top.location, q.lookupType.fullName ++ " expects " ++ toString(length(ts.boundVars)) ++ " type arguments, but there are " ++ toString(tlCount) ++ " supplied here.")] + then [errFromOrigin(top, q.lookupType.fullName ++ " expects " ++ toString(length(ts.boundVars)) ++ " type arguments, but there are " ++ toString(tlCount) ++ " supplied here.")] else []; top.errors <- if tl.missingCount > 0 - then [err(tl.location, q.lookupType.fullName ++ " is a type alias and cannot be partially applied.")] + then [errFromOrigin(tl, q.lookupType.fullName ++ " is a type alias and cannot be partially applied.")] else []; } @@ -286,9 +287,9 @@ top::TypeExpr ::= ty::Decorated TypeExpr tl::BracketedTypeExprs local tlKinds::[Kind] = map((.kindrep), tl.types); local kindErrors::[Message] = if tlCount != length(ty.typerep.kindrep.argKinds) - then [err(top.location, ty.unparse ++ " has kind " ++ prettyKind(ty.typerep.kindrep) ++ ", but there are " ++ toString(tlCount) ++ " type arguments supplied here.")] + then [errFromOrigin(top, ty.unparse ++ " has kind " ++ prettyKind(ty.typerep.kindrep) ++ ", but there are " ++ toString(tlCount) ++ " type arguments supplied here.")] else if take(length(tlKinds), ty.typerep.kindrep.argKinds) != tlKinds - then [err(top.location, ty.unparse ++ " has kind " ++ prettyKind(ty.typerep.kindrep) ++ ", but argument(s) have kind(s) " ++ implode(", ", map(prettyKind, tlKinds)))] + then [errFromOrigin(top, ty.unparse ++ " has kind " ++ prettyKind(ty.typerep.kindrep) ++ ", but argument(s) have kind(s) " ++ implode(", ", map(prettyKind, tlKinds)))] else []; top.errors <- kindErrors; @@ -322,15 +323,15 @@ top::TypeExpr ::= 'Decorated' t::TypeExpr 'with' i::TypeExpr top.errors := i.errorsInhSet ++ t.errors; top.errors <- case t.typerep.baseType of - | nonterminalType(fn,_,true,_) -> [err(t.location, s"${fn} is a data nonterminal and cannot be decorated")] + | nonterminalType(fn,_,true,_) -> [errFromOrigin(t, s"${fn} is a data nonterminal and cannot be decorated")] | nonterminalType(_,_,_,_) -> [] | skolemType(_) -> [] | varType(_) -> [] - | _ -> [err(t.location, t.unparse ++ " is not a nonterminal, and cannot be Decorated.")] + | _ -> [errFromOrigin(t, t.unparse ++ " is not a nonterminal, and cannot be Decorated.")] end; top.errors <- if i.typerep.kindrep != inhSetKind() - then [err(i.location, s"${i.unparse} has kind ${prettyKind(i.typerep.kindrep)}, but kind InhSet is expected here")] + then [errFromOrigin(i, s"${i.unparse} has kind ${prettyKind(i.typerep.kindrep)}, but kind InhSet is expected here")] else []; top.errors <- t.errorsKindStar; @@ -352,11 +353,11 @@ top::TypeExpr ::= 'Decorated' t::TypeExpr top.errors <- case t.typerep.baseType of - | nonterminalType(fn,_,true,_) -> [err(t.location, s"${fn} is a data nonterminal and cannot be decorated")] + | nonterminalType(fn,_,true,_) -> [errFromOrigin(t, s"${fn} is a data nonterminal and cannot be decorated")] | nonterminalType(_,_,_,_) -> [] - | skolemType(_) -> [err(t.location, "polymorphic Decorated types must specify an explicit reference set")] - | varType(_) -> [err(t.location, "polymorphic Decorated types must specify an explicit reference set")] - | _ -> [err(t.location, t.unparse ++ " is not a nonterminal, and cannot be Decorated.")] + | skolemType(_) -> [errFromOrigin(t, "polymorphic Decorated types must specify an explicit reference set")] + | varType(_) -> [errFromOrigin(t, "polymorphic Decorated types must specify an explicit reference set")] + | _ -> [errFromOrigin(t, t.unparse ++ " is not a nonterminal, and cannot be Decorated.")] end; } @@ -372,15 +373,15 @@ top::TypeExpr ::= 'Decorated!' t::TypeExpr 'with' i::TypeExpr top.errors := i.errorsInhSet ++ t.errors; top.errors <- case t.typerep.baseType of - | nonterminalType(fn,_,true,_) -> [err(t.location, s"${fn} is a data nonterminal and cannot be decorated")] + | nonterminalType(fn,_,true,_) -> [errFromOrigin(t, s"${fn} is a data nonterminal and cannot be decorated")] | nonterminalType(_,_,_,_) -> [] | skolemType(_) -> [] | varType(_) -> [] - | _ -> [err(t.location, t.unparse ++ " is not a nonterminal, and cannot be Decorated!.")] + | _ -> [errFromOrigin(t, t.unparse ++ " is not a nonterminal, and cannot be Decorated!.")] end; top.errors <- if i.typerep.kindrep != inhSetKind() - then [err(i.location, s"${i.unparse} has kind ${prettyKind(i.typerep.kindrep)}, but kind InhSet is expected here")] + then [errFromOrigin(i, s"${i.unparse} has kind ${prettyKind(i.typerep.kindrep)}, but kind InhSet is expected here")] else []; top.errors <- t.errorsKindStar; @@ -402,11 +403,11 @@ top::TypeExpr ::= 'Decorated!' t::TypeExpr top.errors <- case t.typerep.baseType of - | nonterminalType(fn,_,true,_) -> [err(t.location, s"${fn} is a data nonterminal and cannot be decorated")] + | nonterminalType(fn,_,true,_) -> [errFromOrigin(t, s"${fn} is a data nonterminal and cannot be decorated")] | nonterminalType(_,_,_,_) -> [] - | skolemType(_) -> [err(t.location, "polymorphic Decorated! types must specify an explicit reference set")] - | varType(_) -> [err(t.location, "polymorphic Decorated! types must specify an explicit reference set")] - | _ -> [err(t.location, t.unparse ++ " is not a nonterminal, and cannot be Decorated!.")] + | skolemType(_) -> [errFromOrigin(t, "polymorphic Decorated! types must specify an explicit reference set")] + | varType(_) -> [errFromOrigin(t, "polymorphic Decorated! types must specify an explicit reference set")] + | _ -> [errFromOrigin(t, t.unparse ++ " is not a nonterminal, and cannot be Decorated!.")] end; } @@ -436,7 +437,7 @@ top::Signature ::= l::SignatureLHS '::=' list::TypeExprs top.errors <- list.errorsKindStar; top.errors <- if l.maybeType.isJust && list.missingCount > 0 - then [err($1.location, "Return type cannot be present when argument types are missing")] + then [errFromOrigin(l, "Return type cannot be present when argument types are missing")] else []; } @@ -472,7 +473,7 @@ top::Signature ::= l::SignatureLHS '::=' list::TypeExprs ';' namedList::NamedTyp top.errors <- namedList.errorsKindStar; top.errors <- if list.missingCount > 0 - then [err($1.location, "Named parameters cannot be present when argument types are missing")] + then [errFromOrigin(namedList, "Named parameters cannot be present when argument types are missing")] else []; } @@ -498,7 +499,7 @@ concrete production botlNone top::BracketedOptTypeExprs ::= { top.unparse = ""; - forwards to botlSome(bTypeList('<', typeListNone(location=top.location), '>', location=top.location), location=top.location); + forwards to botlSome(bTypeList('<', typeListNone(), '>')); } concrete production botlSome @@ -526,16 +527,16 @@ top::BracketedTypeExprs ::= '<' tl::TypeExprs '>' top.errorsTyVars <- if length(tl.lexicalTypeVariables) != length(nub(tl.lexicalTypeVariables)) - then [err(top.location, "Type parameter list repeats type variable names")] + then [errFromOrigin(top, "Type parameter list repeats type variable names")] else []; top.errorsTyVars <- if tl.missingCount > 0 - then [err(top.location, "Type parameter list cannot contain _")] + then [errFromOrigin(top, "Type parameter list cannot contain _")] else []; top.envBindingTyVars = newScopeEnv( - addNewLexicalTyVars(top.grammarName, top.location, tl.lexicalTyVarKinds, tl.lexicalTypeVariables), + addNewLexicalTyVars(top.grammarName, tl.lexicalTyVarKinds, tl.lexicalTypeVariables), top.initialEnv); tl.appArgKinds = top.appArgKinds; @@ -556,14 +557,14 @@ concrete production typeListSingle top::TypeExprs ::= t::TypeExpr { top.unparse = t.unparse; - forwards to typeListCons(t, typeListNone(location=top.location), location=top.location); + forwards to typeListCons(t, typeListNone()); } concrete production typeListSingleMissing top::TypeExprs ::= '_' { top.unparse = "_"; - forwards to typeListConsMissing($1, typeListNone(location=top.location), location=top.location); + forwards to typeListConsMissing($1, typeListNone()); } concrete production typeListCons @@ -620,7 +621,7 @@ concrete production namedTypeListSingle top::NamedTypeExprs ::= n::Name '::' t::TypeExpr { top.unparse = t.unparse; - forwards to namedTypeListCons(n, $2, t, namedTypeListNone(location=top.location), location=top.location); + forwards to namedTypeListCons(n, $2, t, namedTypeListNone()); } concrete production namedTypeListCons diff --git a/grammars/silver/compiler/driver/BuildProcess.sv b/grammars/silver/compiler/driver/BuildProcess.sv index d19182b0b..a05632cc3 100644 --- a/grammars/silver/compiler/driver/BuildProcess.sv +++ b/grammars/silver/compiler/driver/BuildProcess.sv @@ -39,7 +39,7 @@ IO ::= unit::IOErrorable res::Either <- unit.run; case res of | left(re) -> do { - eprintln(re.message); + eprintln(re.errMsg); return re.code; } | right(comp) -> runAll(comp.postOps) @@ -194,17 +194,11 @@ function eatGrammars newDeps ++ eatGrammars(triggered, n-1+length(newDeps), newDeps ++ sofar, tail(rootStream), tail(grammars)); } -synthesized attribute code::Integer; +annotation code::Integer; +annotation errMsg::String; -nonterminal RunError with code, message; --- from silver:langutil, and silver:compiler:driver:util; - -abstract production runError -top::RunError ::= c::Integer m::String -{ - top.code = c; - top.message = m; -} +data RunError = runError + with code, errMsg; -- A common return type for IO functions. Does IO and returns error or whatever. type IOErrorable = EitherT; @@ -212,5 +206,5 @@ type IOErrorable = EitherT; function throwRunError IOErrorable ::= c::Integer m::String { - return throwError(runError(c, m)); + return throwError(runError(code=c, errMsg=m)); } diff --git a/grammars/silver/compiler/extension/astconstruction/Syntax.sv b/grammars/silver/compiler/extension/astconstruction/Syntax.sv index 4555cc34d..03f1c8b69 100644 --- a/grammars/silver/compiler/extension/astconstruction/Syntax.sv +++ b/grammars/silver/compiler/extension/astconstruction/Syntax.sv @@ -39,10 +39,10 @@ concrete production varAST_c top::AST_c ::= n::QName_t { top.unparse = n.lexeme; - top.ast = antiquotePatternAST(varPattern(name(n.lexeme, n.location), location=top.location)); + top.ast = antiquotePatternAST(varPattern(name(n.lexeme, n.location))); top.errors := if indexOf(":", n.lexeme) != -1 - then [err(n.location, "Pattern variable name must be unqualified")] + then [errFromOrigin(n, "Pattern variable name must be unqualified")] else []; } @@ -50,7 +50,7 @@ concrete production wildAST_c top::AST_c ::= '_' { top.unparse = "_"; - top.ast = antiquotePatternAST(wildcPattern('_', location=top.location)); + top.ast = antiquotePatternAST(wildcPattern('_')); top.errors := []; } diff --git a/grammars/silver/compiler/extension/attrsection/AttrSection.sv.md b/grammars/silver/compiler/extension/attrsection/AttrSection.sv.md index dfde8e953..574c6e768 100644 --- a/grammars/silver/compiler/extension/attrsection/AttrSection.sv.md +++ b/grammars/silver/compiler/extension/attrsection/AttrSection.sv.md @@ -66,7 +66,7 @@ specific type that differs from the output type is safe to use for the attribute ```silver top.errors := if !null(outputTy.freeFlexibleVars) - then [err(top.location, s"The attribute section ${top.unparse} has an ambiguous inferred output type ${prettyType(outputTy)}, where ${implode(", ", map(findAbbrevFor(_, outputTy.freeVariables), outputTy.freeFlexibleVars))} ${if length(outputTy.freeFlexibleVars) > 1 then "are" else "is"} unspecialized")] + then [errFromOrigin(top, s"The attribute section ${top.unparse} has an ambiguous inferred output type ${prettyType(outputTy)}, where ${implode(", ", map(findAbbrevFor(_, outputTy.freeVariables), outputTy.freeFlexibleVars))} ${if length(outputTy.freeFlexibleVars) > 1 then "are" else "is"} unspecialized")] else forward.errors; ``` @@ -79,7 +79,7 @@ was inferred elsewhere.) checkOutputType.finalSubst = composeSubst(forward.upSubst, top.finalSubst); top.errors <- if checkOutputType.typeerror - then [err(top.location, s"Attribute section ${top.unparse} has inferred output type ${checkOutputType.leftpp} that does not match the attribute's type ${checkOutputType.rightpp}")] + then [errFromOrigin(top, s"Attribute section ${top.unparse} has inferred output type ${checkOutputType.leftpp} that does not match the attribute's type ${checkOutputType.rightpp}")] else []; ``` @@ -88,10 +88,8 @@ The forward is just equivalent to `\ x::inputTy -> x.attr` forwards to lambdap( productionRHSCons( - productionRHSElem(name("x", top.location), '::', typerepTypeExpr(inputTy, location=top.location), location=top.location), - productionRHSNil(location=top.location), - location=top.location), - access(baseExpr(qName(top.location, "x"), location=top.location), '.', q, location=top.location), - location=top.location); + productionRHSElem(name("x"), '::', typerepTypeExpr(inputTy)), + productionRHSNil()), + access(baseExpr(qName("x")), '.', q)); } ``` diff --git a/grammars/silver/compiler/extension/auto_ast/AutoAst.sv b/grammars/silver/compiler/extension/auto_ast/AutoAst.sv index 750c1656b..ad6c88a9e 100644 --- a/grammars/silver/compiler/extension/auto_ast/AutoAst.sv +++ b/grammars/silver/compiler/extension/auto_ast/AutoAst.sv @@ -31,7 +31,7 @@ top::ProductionStmt ::= 'abstract' v::QName ';' top.errors <- if hasAst(top.frame.signature.outputElement, top.env) then [] - else [err(top.location, "This lhs '" ++ top.frame.signature.outputElement.elementName ++ "' does not have the 'silver:langutil:ast' attribute.")]; + else [errFromOrigin(top, "This lhs '" ++ top.frame.signature.outputElement.elementName ++ "' does not have the 'silver:langutil:ast' attribute.")]; local attribute errCheck1 :: TypeCheck; errCheck1.finalSubst = top.finalSubst; @@ -40,39 +40,37 @@ top::ProductionStmt ::= 'abstract' v::QName ';' errCheck1 = check(vty, inferredType); top.errors <- if !errCheck1.typeerror then [] - else [err(v.location, "Signature yields ast type " ++ errCheck1.rightpp ++ ", but the supplied ast constructor has type " ++ errCheck1.leftpp)]; + else [errFromOrigin(v, "Signature yields ast type " ++ errCheck1.rightpp ++ ", but the supplied ast constructor has type " ++ errCheck1.leftpp)]; top.errors <- if hasLoc && null(getOccursDcl("silver:core:location", top.frame.lhsNtName, top.env)) - then [err(top.location, "Ast constructor wants 'location' but this nonterminal does not have a location")] + then [errFromOrigin(top, "Ast constructor wants 'location' but this nonterminal does not have a location")] else []; local lhsQName :: QName = - qName(top.location, top.frame.signature.outputElement.elementName); + qName(top.frame.signature.outputElement.elementName); local astQName :: QNameAttrOccur = - qNameAttrOccur(qName(top.location, "silver:langutil:ast"), location=top.location); + qNameAttrOccur(qName("silver:langutil:ast")); - -- lhs.ast = v( (.ast) on elems, location=lhs.location if present); + -- lhs.ast = v( (.ast) on elems if present); forwards to attributeDef( - concreteDefLHS(lhsQName, location=top.location), + concreteDefLHS(lhsQName), '.', astQName, '=', mkFullFunctionInvocation( top.location, - baseExpr(v, location=v.location), + baseExpr(v), map(accessAst(_, top.location), elems), if hasLoc then [("location", access( - baseExpr(lhsQName, location=top.location), + baseExpr(lhsQName), '.', - qNameAttrOccur(qName(top.location, "location"), location=top.location), - location=top.location))] + qNameAttrOccur(qName("location"))))] else []), - ';', - location=top.location); + ';'); } @@ -98,9 +96,9 @@ Expr ::= ns::NamedSignatureElement l::Location { return access( - baseExpr(qName(l, ns.elementName), location=l), + baseExpr(qName(ns.elementName)), '.', - qNameAttrOccur(qName(l, "silver:langutil:ast"), location=l), + qNameAttrOccur(qName("silver:langutil:ast")), location=l); } diff --git a/grammars/silver/compiler/extension/autoattr/BiEquality.sv b/grammars/silver/compiler/extension/autoattr/BiEquality.sv index b45a88166..afa66e2f4 100644 --- a/grammars/silver/compiler/extension/autoattr/BiEquality.sv +++ b/grammars/silver/compiler/extension/autoattr/BiEquality.sv @@ -17,24 +17,23 @@ top::AGDcl ::= 'biequality' 'attribute' synPartial::Name ',' syn::Name 'with' in top.errors <- if length(getAttrDclAll(synPartialFName, top.env)) > 1 - then [err(syn.location, "Attribute '" ++ synPartialFName ++ "' is already bound.")] + then [errFromOrigin(syn, "Attribute '" ++ synPartialFName ++ "' is already bound.")] else []; top.errors <- if length(getAttrDclAll(synFName, top.env)) > 1 - then [err(syn.location, "Attribute '" ++ synFName ++ "' is already bound.")] + then [errFromOrigin(syn, "Attribute '" ++ synFName ++ "' is already bound.")] else []; forwards to defsAGDcl( [attrDef(defaultEnvItem(biequalityPartialDcl(inhFName, synPartialFName, synFName, sourceGrammar=top.grammarName, sourceLocation=synPartial.location))), - attrDef(defaultEnvItem(biequalityDcl(inhFName, synPartialFName, synFName, sourceGrammar=top.grammarName, sourceLocation=syn.location)))], - location=top.location); + attrDef(defaultEnvItem(biequalityDcl(inhFName, synPartialFName, synFName, sourceGrammar=top.grammarName, sourceLocation=syn.location)))]); } abstract production biequalityInhAttributionDcl top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs { - undecorates to attributionDcl('attribute', at, attl, 'occurs', 'on', nt, nttl, ';', location=top.location); + undecorates to attributionDcl('attribute', at, attl, 'occurs', 'on', nt, nttl, ';'); top.unparse = "attribute " ++ at.unparse ++ attl.unparse ++ " occurs on " ++ nt.unparse ++ nttl.unparse ++ ";"; top.moduleNames := []; @@ -53,21 +52,18 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: case nttl of | botlSome(tl) -> appTypeExpr( - nominalTypeExpr(nt.qNameType, location=top.location), - tl, location=top.location) - | botlNone() -> nominalTypeExpr(nt.qNameType, location=top.location) - end, - location=top.location), - '>', location=top.location), - location=top.location), - nt, nttl, - location=top.location); + nominalTypeExpr(nt.qNameType), + tl) + | botlNone() -> nominalTypeExpr(nt.qNameType) + end), + '>')), + nt, nttl); } abstract production propagateBiequalitySynPartial top::ProductionStmt ::= inh::String synPartial::Decorated! QName syn::String { - undecorates to propagateOneAttr(synPartial, location=top.location); + undecorates to propagateOneAttr(synPartial); top.unparse = s"propagate ${synPartial.unparse};"; forwards to @@ -76,20 +72,19 @@ top::ProductionStmt ::= inh::String synPartial::Decorated! QName syn::String case $name{top.frame.signature.outputElement.elementName}.$name{inh} of | $Pattern{ prodAppPattern( - qName(top.location, top.frame.signature.fullName), + qName(top.frame.signature.fullName), '(', foldr( - patternList_more(_, ',', _, location=top.location), - patternList_nil(location=top.location), + patternList_more(_, ',', _), + patternList_nil(), map( \ ie::NamedSignatureElement -> Silver_Pattern { $name{ie.elementName ++ "2"} }, top.frame.signature.inputElements)), - ')', - location=top.location)} -> + ')')} -> $Expr{ foldr( - and(_, '&&', _, location=top.location), - trueConst('true', location=top.location), + and(_, '&&', _), + trueConst('true'), map( \ ie::NamedSignatureElement -> if null(getOccursDcl(syn, ie.typerep.typeName, top.env)) @@ -104,7 +99,7 @@ top::ProductionStmt ::= inh::String synPartial::Decorated! QName syn::String abstract production propagateBiequalitySyn top::ProductionStmt ::= inh::String synPartial::String syn::Decorated! QName { - undecorates to propagateOneAttr(syn, location=top.location); + undecorates to propagateOneAttr(syn); top.unparse = s"propagate ${syn.unparse};"; forwards to diff --git a/grammars/silver/compiler/extension/autoattr/DclInfo.sv b/grammars/silver/compiler/extension/autoattr/DclInfo.sv index c5e64379b..54c237844 100644 --- a/grammars/silver/compiler/extension/autoattr/DclInfo.sv +++ b/grammars/silver/compiler/extension/autoattr/DclInfo.sv @@ -1,20 +1,20 @@ grammar silver:compiler:extension:autoattr; -synthesized attribute propagateDispatcher :: (ProductionStmt ::= Decorated! QName Location) occurs on AttributeDclInfo; +synthesized attribute propagateDispatcher :: (ProductionStmt ::= Decorated! QName) occurs on AttributeDclInfo; synthesized attribute emptyVal::Expr occurs on AttributeDclInfo; aspect default production top::AttributeDclInfo ::= { - top.propagateDispatcher = propagateError(_, location=_); + top.propagateDispatcher = propagateError; top.emptyVal = error("Internal compiler error: must be defined for all monoid attribute declarations"); } aspect production inhDcl top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type { - top.propagateDispatcher = propagateInh(_, location=_); + top.propagateDispatcher = propagateInh; } abstract production functorDcl @@ -27,12 +27,12 @@ top::AttributeDclInfo ::= fn::String top.typeScheme = polyType([tyVar], varType(tyVar)); top.isSynthesized = true; - top.decoratedAccessHandler = synDecoratedAccessHandler(_, _, location=_); - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _, location=_), _, _, _); - top.dataAccessHandler = synDataAccessHandler(_, _, location=_); - top.attrDefDispatcher = synthesizedAttributeDef(_, _, _, location=_); -- Allow normal syn equations - top.attributionDispatcher = functorAttributionDcl(_, _, _, _, location=_); - top.propagateDispatcher = propagateFunctor(_, location=_); + top.decoratedAccessHandler = synDecoratedAccessHandler; + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.dataAccessHandler = synDataAccessHandler; + top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations + top.attributionDispatcher = functorAttributionDcl; + top.propagateDispatcher = propagateFunctor; } abstract production monoidDcl @@ -52,16 +52,16 @@ top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type empty::Expr append: top.emptyVal = empty; top.operation = append; - top.decoratedAccessHandler = synDecoratedAccessHandler(_, _, location=_); - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _, location=_), _, _, _); - top.dataAccessHandler = synDataAccessHandler(_, _, location=_); + top.decoratedAccessHandler = synDecoratedAccessHandler; + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr l::Location -> - errorAttributeDef([err(l, attr.name ++ " is a monoid collection attribute, and you must use ':=' or '<-', not '='.")], dl, attr, e, location=l); - top.attrBaseDefDispatcher = synBaseColAttributeDef(_, _, _, location=_); - top.attrAppendDefDispatcher = synAppendColAttributeDef(_, _, _, location=_); - top.attributionDispatcher = defaultAttributionDcl(_, _, _, _, location=_); - top.propagateDispatcher = propagateMonoid(_, location=_); + errorAttributeDef([err(l, attr.name ++ " is a monoid collection attribute, and you must use ':=' or '<-', not '='.")], dl, attr, e); + top.attrBaseDefDispatcher = synBaseColAttributeDef; + top.attrAppendDefDispatcher = synAppendColAttributeDef; + top.attributionDispatcher = defaultAttributionDcl; + top.propagateDispatcher = propagateMonoid; } abstract production destructDcl @@ -75,12 +75,12 @@ top::AttributeDclInfo ::= fn::String top.typeScheme = polyType([tyVar, inhsTyVar], decoratedType(varType(tyVar), varType(inhsTyVar))); top.isInherited = true; - top.decoratedAccessHandler = inhDecoratedAccessHandler(_, _, location=_); - top.undecoratedAccessHandler = inhUndecoratedAccessErrorHandler(_, _, location=_); - top.dataAccessHandler = inhUndecoratedAccessErrorHandler(_, _, location=_); - top.attrDefDispatcher = inheritedAttributeDef(_, _, _, location=_); -- Allow normal inh equations - top.attributionDispatcher = destructAttributionDcl(_, _, _, _, location=_); - top.propagateDispatcher = propagateDestruct(_, location=_); + top.decoratedAccessHandler = inhDecoratedAccessHandler; + top.undecoratedAccessHandler = inhUndecoratedAccessErrorHandler; + top.dataAccessHandler = inhUndecoratedAccessErrorHandler; + top.attrDefDispatcher = inheritedAttributeDef; -- Allow normal inh equations + top.attributionDispatcher = destructAttributionDcl; + top.propagateDispatcher = propagateDestruct; } abstract production equalityDcl @@ -92,12 +92,12 @@ top::AttributeDclInfo ::= inh::String syn::String top.typeScheme = monoType(boolType()); top.isSynthesized = true; - top.decoratedAccessHandler = synDecoratedAccessHandler(_, _, location=_); - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _, location=_), _, _, _); - top.dataAccessHandler = synDataAccessHandler(_, _, location=_); - top.attrDefDispatcher = synthesizedAttributeDef(_, _, _, location=_); -- Allow normal syn equations - top.attributionDispatcher = defaultAttributionDcl(_, _, _, _, location=_); - top.propagateDispatcher = propagateEquality(inh, _, location=_); + top.decoratedAccessHandler = synDecoratedAccessHandler; + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.dataAccessHandler = synDataAccessHandler; + top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations + top.attributionDispatcher = defaultAttributionDcl; + top.propagateDispatcher = propagateEquality(inh, _); } abstract production orderingKeyDcl @@ -109,12 +109,12 @@ top::AttributeDclInfo ::= syn::String top.typeScheme = monoType(stringType()); top.isSynthesized = true; - top.decoratedAccessHandler = synDecoratedAccessHandler(_, _, location=_); - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _, location=_), _, _, _); - top.dataAccessHandler = synDataAccessHandler(_, _, location=_); - top.attrDefDispatcher = synthesizedAttributeDef(_, _, _, location=_); -- Allow normal syn equations - top.attributionDispatcher = defaultAttributionDcl(_, _, _, _, location=_); - top.propagateDispatcher = propagateOrderingKey(_, location=_); + top.decoratedAccessHandler = synDecoratedAccessHandler; + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.dataAccessHandler = synDataAccessHandler; + top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations + top.attributionDispatcher = defaultAttributionDcl; + top.propagateDispatcher = propagateOrderingKey; } abstract production orderingDcl @@ -126,12 +126,12 @@ top::AttributeDclInfo ::= inh::String keySyn::String syn::String top.typeScheme = monoType(intType()); top.isSynthesized = true; - top.decoratedAccessHandler = synDecoratedAccessHandler(_, _, location=_); - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _, location=_), _, _, _); - top.dataAccessHandler = synDataAccessHandler(_, _, location=_); - top.attrDefDispatcher = synthesizedAttributeDef(_, _, _, location=_); -- Allow normal syn equations - top.attributionDispatcher = defaultAttributionDcl(_, _, _, _, location=_); - top.propagateDispatcher = propagateOrdering(inh, keySyn, _, location=_); + top.decoratedAccessHandler = synDecoratedAccessHandler; + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.dataAccessHandler = synDataAccessHandler; + top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations + top.attributionDispatcher = defaultAttributionDcl; + top.propagateDispatcher = propagateOrdering(inh, keySyn, _); } abstract production biequalityPartialDcl @@ -143,12 +143,12 @@ top::AttributeDclInfo ::= inh::String synPartial::String syn::String top.typeScheme = monoType(boolType()); top.isSynthesized = true; - top.decoratedAccessHandler = synDecoratedAccessHandler(_, _, location=_); - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _, location=_), _, _, _); - top.dataAccessHandler = synDataAccessHandler(_, _, location=_); - top.attrDefDispatcher = synthesizedAttributeDef(_, _, _, location=_); -- Allow normal syn equations - top.attributionDispatcher = defaultAttributionDcl(_, _, _, _, location=_); - top.propagateDispatcher = propagateBiequalitySynPartial(inh, _, syn, location=_); + top.decoratedAccessHandler = synDecoratedAccessHandler; + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.dataAccessHandler = synDataAccessHandler; + top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations + top.attributionDispatcher = defaultAttributionDcl; + top.propagateDispatcher = propagateBiequalitySynPartial(inh, _, syn); } abstract production biequalityDcl @@ -160,12 +160,12 @@ top::AttributeDclInfo ::= inh::String synPartial::String syn::String top.typeScheme = monoType(boolType()); top.isSynthesized = true; - top.decoratedAccessHandler = synDecoratedAccessHandler(_, _, location=_); - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _, location=_), _, _, _); - top.dataAccessHandler = synDataAccessHandler(_, _, location=_); - top.attrDefDispatcher = synthesizedAttributeDef(_, _, _, location=_); -- Allow normal syn equations - top.attributionDispatcher = defaultAttributionDcl(_, _, _, _, location=_); - top.propagateDispatcher = propagateBiequalitySyn(inh, synPartial, _, location=_); + top.decoratedAccessHandler = synDecoratedAccessHandler; + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.dataAccessHandler = synDataAccessHandler; + top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations + top.attributionDispatcher = defaultAttributionDcl; + top.propagateDispatcher = propagateBiequalitySyn(inh, synPartial, _); } abstract production threadedInhDcl @@ -185,23 +185,23 @@ top::AttributeDclInfo ::= inh::String syn::String bound::[TyVar] ty::Type o::May top.isCollection = o.isJust; top.operation = o.fromJust; - top.decoratedAccessHandler = inhDecoratedAccessHandler(_, _, location=_); - top.undecoratedAccessHandler = inhUndecoratedAccessErrorHandler(_, _, location=_); - top.dataAccessHandler = inhUndecoratedAccessErrorHandler(_, _, location=_); + top.decoratedAccessHandler = inhDecoratedAccessHandler; + top.undecoratedAccessHandler = inhUndecoratedAccessErrorHandler; + top.dataAccessHandler = inhUndecoratedAccessErrorHandler; top.attrDefDispatcher = if o.isJust then collectionAttrDefError - else inheritedAttributeDef(_, _, _, location=_); -- Allow normal inh equations + else inheritedAttributeDef(_, _, _); -- Allow normal inh equations top.attrBaseDefDispatcher = if o.isJust - then inhBaseColAttributeDef(_, _, _, location=_) -- Allow normal inh base equations + then inhBaseColAttributeDef(_, _, _) -- Allow normal inh base equations else nonCollectionAttrBaseDefError; top.attrAppendDefDispatcher = if o.isJust - then inhAppendColAttributeDef(_, _, _, location=_) -- Allow normal inh append equations + then inhAppendColAttributeDef(_, _, _) -- Allow normal inh append equations else nonCollectionAttrAppendDefError; - top.attributionDispatcher = defaultAttributionDcl(_, _, _, _, location=_); - top.propagateDispatcher = propagateThreadedInh(o.isJust, rev, _, syn, location=_); + top.attributionDispatcher = defaultAttributionDcl; + top.propagateDispatcher = propagateThreadedInh(o.isJust, rev, _, syn); } abstract production threadedSynDcl @@ -221,21 +221,21 @@ top::AttributeDclInfo ::= inh::String syn::String bound::[TyVar] ty::Type o::May top.isCollection = o.isJust; top.operation = o.fromJust; - top.decoratedAccessHandler = synDecoratedAccessHandler(_, _, location=_); - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _, location=_), _, _, _); - top.dataAccessHandler = synDataAccessHandler(_, _, location=_); + top.decoratedAccessHandler = synDecoratedAccessHandler; + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = if o.isJust then collectionAttrDefError - else synthesizedAttributeDef(_, _, _, location=_); -- Allow normal syn equations + else synthesizedAttributeDef(_, _, _); -- Allow normal syn equations top.attrBaseDefDispatcher = if o.isJust - then synBaseColAttributeDef(_, _, _, location=_) -- Allow normal syn base equations + then synBaseColAttributeDef(_, _, _) -- Allow normal syn base equations else nonCollectionAttrBaseDefError; top.attrAppendDefDispatcher = if o.isJust - then synAppendColAttributeDef(_, _, _, location=_) -- Allow normal syn append equations + then synAppendColAttributeDef(_, _, _) -- Allow normal syn append equations else nonCollectionAttrAppendDefError; - top.attributionDispatcher = defaultAttributionDcl(_, _, _, _, location=_); - top.propagateDispatcher = propagateThreadedSyn(o.isJust, rev, inh, _, location=_); + top.attributionDispatcher = defaultAttributionDcl; + top.propagateDispatcher = propagateThreadedSyn(o.isJust, rev, inh, _); } diff --git a/grammars/silver/compiler/extension/autoattr/Destruct.sv b/grammars/silver/compiler/extension/autoattr/Destruct.sv index 47e02524f..6dbeb52e4 100644 --- a/grammars/silver/compiler/extension/autoattr/Destruct.sv +++ b/grammars/silver/compiler/extension/autoattr/Destruct.sv @@ -11,19 +11,18 @@ top::AGDcl ::= 'destruct' 'attribute' inh::Name ';' top.errors <- if length(getAttrDclAll(inhFName, top.env)) > 1 - then [err(inh.location, "Attribute '" ++ inhFName ++ "' is already bound.")] + then [errFromOrigin(inh, "Attribute '" ++ inhFName ++ "' is already bound.")] else []; forwards to defsAGDcl( - [attrDef(defaultEnvItem(destructDcl(inhFName, sourceGrammar=top.grammarName, sourceLocation=inh.location)))], - location=top.location); + [attrDef(defaultEnvItem(destructDcl(inhFName, sourceGrammar=top.grammarName, sourceLocation=inh.location)))]); } abstract production destructAttributionDcl top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs { - undecorates to attributionDcl('attribute', at, attl, 'occurs', 'on', nt, nttl, ';', location=top.location); + undecorates to attributionDcl('attribute', at, attl, 'occurs', 'on', nt, nttl, ';'); top.unparse = "attribute " ++ at.unparse ++ attl.unparse ++ " occurs on " ++ nt.unparse ++ nttl.unparse ++ ";"; top.moduleNames := []; @@ -41,16 +40,13 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: case nttl of | botlSome(tl) -> appTypeExpr( - nominalTypeExpr(nt.qNameType, location=top.location), - tl, location=top.location) - | botlNone() -> nominalTypeExpr(nt.qNameType, location=top.location) + nominalTypeExpr(nt.qNameType), + tl) + | botlNone() -> nominalTypeExpr(nt.qNameType) end, typeListSingle( - typerepTypeExpr(inhSetType([]), location=top.location), - location=top.location), - location=top.location), - '>', location=top.location), - location=top.location) + typerepTypeExpr(inhSetType([])))), + '>')) | [i] -> botlSome( bTypeList( @@ -59,20 +55,16 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: case nttl of | botlSome(tl) -> appTypeExpr( - nominalTypeExpr(nt.qNameType, location=top.location), - tl, location=top.location) - | botlNone() -> nominalTypeExpr(nt.qNameType, location=top.location) + nominalTypeExpr(nt.qNameType), + tl) + | botlNone() -> nominalTypeExpr(nt.qNameType) end, typeListSingle( - typerepTypeExpr(i, location=top.location), - location=top.location), - location=top.location), - '>', location=top.location), - location=top.location) + typerepTypeExpr(i))), + '>')) | _ -> attl end, - nt, nttl, - location=top.location); + nt, nttl); } {-- @@ -82,14 +74,14 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: abstract production propagateDestruct top::ProductionStmt ::= attr::Decorated! QName { - undecorates to propagateOneAttr(attr, location=top.location); + undecorates to propagateOneAttr(attr); top.unparse = s"propagate ${attr.unparse};"; local numChildren::Integer = length(top.frame.signature.inputElements); forwards to foldr( - productionStmtAppend(_, _, location=top.location), - errorProductionStmt([], location=top.location), -- No emptyProductionStmt? + productionStmtAppend(_, _), + errorProductionStmt([]), -- No emptyProductionStmt? map( \ ie::Pair -> Silver_ProductionStmt { @@ -97,21 +89,20 @@ top::ProductionStmt ::= attr::Decorated! QName case $name{top.frame.signature.outputElement.elementName}.$QName{new(attr)} of | $Pattern{ prodAppPattern( - qName(top.location, top.frame.signature.fullName), + qName(top.frame.signature.fullName), '(', foldr( - patternList_more(_, ',', _, location=top.location), - patternList_nil(location=top.location), - repeat(wildcPattern('_', location=top.location), ie.fst) ++ + patternList_more(_, ',', _), + patternList_nil(), + repeat(wildcPattern('_'), ie.fst) ++ Silver_Pattern { a } :: - repeat(wildcPattern('_', location=top.location), numChildren - (ie.fst + 1)) ), - ')', - location=top.location)} -> a + repeat(wildcPattern('_'), numChildren - (ie.fst + 1)) ), + ')')} -> a | a -> error( - "Destruct attribute " ++ $Expr{stringConst(terminal(String_t, s"\"${attr.name}\"", top.location), location=top.location)} ++ - " demanded on child " ++ $Expr{stringConst(terminal(String_t, s"\"${ie.snd.elementName}\"", top.location), location=top.location)} ++ - " of production " ++ $Expr{stringConst(terminal(String_t, s"\"${top.frame.signature.fullName}\"", top.location), location=top.location)} ++ + "Destruct attribute " ++ $Expr{stringConst(terminal(String_t, s"\"${attr.name}\"", top.location))} ++ + " demanded on child " ++ $Expr{stringConst(terminal(String_t, s"\"${ie.snd.elementName}\"", top.location))} ++ + " of production " ++ $Expr{stringConst(terminal(String_t, s"\"${top.frame.signature.fullName}\"", top.location))} ++ " when given value " ++ silver:core:hackUnparse(a) ++ " does not match.") -- TODO: Shouldn't really be using hackUnparse here. end; }, diff --git a/grammars/silver/compiler/extension/autoattr/Equality.sv b/grammars/silver/compiler/extension/autoattr/Equality.sv index 4e43bee94..b02e5c723 100644 --- a/grammars/silver/compiler/extension/autoattr/Equality.sv +++ b/grammars/silver/compiler/extension/autoattr/Equality.sv @@ -15,13 +15,12 @@ top::AGDcl ::= 'equality' 'attribute' syn::Name 'with' inh::QName ';' top.errors <- if length(getAttrDclAll(synFName, top.env)) > 1 - then [err(syn.location, "Attribute '" ++ synFName ++ "' is already bound.")] + then [errFromOrigin(syn, "Attribute '" ++ synFName ++ "' is already bound.")] else []; forwards to defsAGDcl( - [attrDef(defaultEnvItem(equalityDcl(inhFName, synFName, sourceGrammar=top.grammarName, sourceLocation=syn.location)))], - location=top.location); + [attrDef(defaultEnvItem(equalityDcl(inhFName, synFName, sourceGrammar=top.grammarName, sourceLocation=syn.location)))]); } {-- @@ -31,7 +30,7 @@ top::AGDcl ::= 'equality' 'attribute' syn::Name 'with' inh::QName ';' abstract production propagateEquality top::ProductionStmt ::= inh::String syn::Decorated! QName { - undecorates to propagateOneAttr(syn, location=top.location); + undecorates to propagateOneAttr(syn); top.unparse = s"propagate ${syn.unparse};"; forwards to @@ -40,20 +39,19 @@ top::ProductionStmt ::= inh::String syn::Decorated! QName case $name{top.frame.signature.outputElement.elementName}.$name{inh} of | $Pattern{ prodAppPattern( - qName(top.location, top.frame.signature.fullName), + qName(top.frame.signature.fullName), '(', foldr( - patternList_more(_, ',', _, location=top.location), - patternList_nil(location=top.location), + patternList_more(_, ',', _), + patternList_nil(), map( \ ie::NamedSignatureElement -> Silver_Pattern { $name{ie.elementName ++ "2"} }, top.frame.signature.inputElements)), - ')', - location=top.location)} -> + ')')} -> $Expr{ foldr( - and(_, '&&', _, location=top.location), - trueConst('true', location=top.location), + and(_, '&&', _), + trueConst('true'), map( \ ie::NamedSignatureElement -> if null(getOccursDcl(syn.lookupAttribute.dcl.fullName, ie.typerep.typeName, top.env)) diff --git a/grammars/silver/compiler/extension/autoattr/Functor.sv b/grammars/silver/compiler/extension/autoattr/Functor.sv index 9360f27ae..999637dad 100644 --- a/grammars/silver/compiler/extension/autoattr/Functor.sv +++ b/grammars/silver/compiler/extension/autoattr/Functor.sv @@ -11,19 +11,18 @@ top::AGDcl ::= 'functor' 'attribute' a::Name ';' top.errors <- if length(getAttrDclAll(fName, top.env)) > 1 - then [err(a.location, "Attribute '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(a, "Attribute '" ++ fName ++ "' is already bound.")] else []; forwards to defsAGDcl( - [attrDef(defaultEnvItem(functorDcl(fName, sourceGrammar=top.grammarName, sourceLocation=a.location)))], - location=top.location); + [attrDef(defaultEnvItem(functorDcl(fName, sourceGrammar=top.grammarName, sourceLocation=a.location)))]); } abstract production functorAttributionDcl top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs { - undecorates to attributionDcl('attribute', at, attl, 'occurs', 'on', nt, nttl, ';', location=top.location); + undecorates to attributionDcl('attribute', at, attl, 'occurs', 'on', nt, nttl, ';'); top.unparse = "attribute " ++ at.unparse ++ attl.unparse ++ " occurs on " ++ nt.unparse ++ nttl.unparse ++ ";"; top.moduleNames := []; @@ -42,15 +41,12 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: case nttl of | botlSome(tl) -> appTypeExpr( - nominalTypeExpr(nt.qNameType, location=top.location), - tl, location=top.location) - | botlNone() -> nominalTypeExpr(nt.qNameType, location=top.location) - end, - location=top.location), - '>', location=top.location), - location=top.location), - nt, nttl, - location=top.location); + nominalTypeExpr(nt.qNameType), + tl) + | botlNone() -> nominalTypeExpr(nt.qNameType) + end), + '>')), + nt, nttl); } {-- @@ -60,7 +56,7 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: abstract production propagateFunctor top::ProductionStmt ::= attr::Decorated! QName { - undecorates to propagateOneAttr(attr, location=top.location); + undecorates to propagateOneAttr(attr); top.unparse = s"propagate ${attr.unparse};"; -- No explicit errors, for now. The only conceivable issue is the attribute not @@ -77,17 +73,16 @@ top::ProductionStmt ::= attr::Decorated! QName -- Construct an attribute def and call with the generated arguments forwards to attributeDef( - concreteDefLHS(qName(top.location, top.frame.signature.outputElement.elementName), location=top.location), + concreteDefLHS(qName(top.frame.signature.outputElement.elementName)), '.', - qNameAttrOccur(new(attr), location=top.location), + qNameAttrOccur(new(attr)), '=', mkFullFunctionInvocation( top.location, - baseExpr(qName(top.location, top.frame.fullName), location=top.location), + baseExpr(qName(top.frame.fullName)), inputs, annotations), - ';', - location=top.location); + ';'); } {-- @@ -101,7 +96,7 @@ top::ProductionStmt ::= attr::Decorated! QName function makeArg Expr ::= loc::Location env::Env attrName::Decorated QName input::NamedSignatureElement { - local at::QName = qName(loc, input.elementName); + local at::QName = qName(input.elementName); at.env = env; -- Check if the attribute occurs on the first child @@ -113,10 +108,9 @@ Expr ::= loc::Location env::Env attrName::Decorated QName input::NamedSignatureE return if validTypeHead && attrOccursOnHead then access( - baseExpr(at, location=loc), '.', - qNameAttrOccur(new(attrName), location=loc), - location=loc) - else baseExpr(at, location=loc); + baseExpr(at), '.', + qNameAttrOccur(new(attrName))) + else baseExpr(at); } {-- @@ -136,7 +130,6 @@ Pair ::= loc::Location baseName::String input::NamedSignatureElemen return (annoName, access( - baseExpr(qName(loc, baseName), location=loc), '.', - qNameAttrOccur(qName(loc, annoName), location=loc), - location=loc)); + baseExpr(qName(baseName)), '.', + qNameAttrOccur(qName(annoName)))); } diff --git a/grammars/silver/compiler/extension/autoattr/Inherited.sv b/grammars/silver/compiler/extension/autoattr/Inherited.sv index c440e4ae5..6e1bddb48 100644 --- a/grammars/silver/compiler/extension/autoattr/Inherited.sv +++ b/grammars/silver/compiler/extension/autoattr/Inherited.sv @@ -3,7 +3,7 @@ grammar silver:compiler:extension:autoattr; abstract production propagateInh top::ProductionStmt ::= attr::Decorated! QName { - undecorates to propagateOneAttr(attr, location=top.location); + undecorates to propagateOneAttr(attr); top.unparse = s"propagate ${attr.unparse};"; local attrFullName::String = attr.lookupAttribute.dcl.fullName; @@ -20,19 +20,17 @@ top::ProductionStmt ::= attr::Decorated! QName top.frame.signature.inputElements); forwards to foldr( - productionStmtAppend(_, _, location=top.location), - errorProductionStmt([], location=top.location), -- No emptyProductionStmt? + productionStmtAppend(_, _), + errorProductionStmt([]), -- No emptyProductionStmt? map( \ ie::NamedSignatureElement -> attributeDef( - concreteDefLHS(qName(top.location, ie.elementName), location=top.location), '.', - qNameAttrOccur(new(attr), location=top.location), + concreteDefLHS(qName(ie.elementName)), '.', + qNameAttrOccur(new(attr)), '=', access( - baseExpr(qName(top.location, top.frame.signature.outputElement.elementName), location=top.location), '.', - qNameAttrOccur(new(attr), location=top.location), - location=top.location), - ';', - location=top.location), + baseExpr(qName(top.frame.signature.outputElement.elementName)), '.', + qNameAttrOccur(new(attr))), + ';'), inputsWithAttr)); } diff --git a/grammars/silver/compiler/extension/autoattr/Monoid.sv b/grammars/silver/compiler/extension/autoattr/Monoid.sv index a118b4a1f..67b9e3ddb 100644 --- a/grammars/silver/compiler/extension/autoattr/Monoid.sv +++ b/grammars/silver/compiler/extension/autoattr/Monoid.sv @@ -29,13 +29,13 @@ top::AGDcl ::= 'monoid' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te::T top.errors <- if length(getAttrDclAll(fName, top.env)) > 1 - then [err(a.location, "Attribute '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(a, "Attribute '" ++ fName ++ "' is already bound.")] else []; local errCheck1 :: TypeCheck = check(e.typerep, te.typerep); top.errors <- if errCheck1.typeerror - then [err(e.location, "Monoid attribute " ++ fName ++ " of type " ++ errCheck1.rightpp ++ " has empty value specified with type " ++ errCheck1.leftpp)] + then [errFromOrigin(e, "Monoid attribute " ++ fName ++ " of type " ++ errCheck1.rightpp ++ " has empty value specified with type " ++ errCheck1.leftpp)] else []; e.downSubst = emptySubst(); @@ -59,8 +59,7 @@ top::AGDcl ::= 'monoid' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te::T forwards to collectionAttributeDclSyn( - 'synthesized', 'attribute', a, tl, '::', te, 'with', q, ';', - location=top.location); + 'synthesized', 'attribute', a, tl, '::', te, 'with', q, ';'); } concrete production tcMonoidAttributeDcl @@ -70,9 +69,8 @@ top::AGDcl ::= 'monoid' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te::T forwards to monoidAttributeDcl( $1, $2, a, tl, $5, te, 'with', - baseExpr(qName(te.location, "silver:core:mempty"), location=te.location), ',', - exprOperator(baseExpr(qName(te.location, "silver:core:append"), location=te.location), location=te.location), $7, - location=top.location); + baseExpr(qName("silver:core:mempty")), ',', + exprOperator(baseExpr(qName("silver:core:append"))), $7); } synthesized attribute appendProd :: (Expr ::= Expr Expr Location) occurs on Operation; @@ -85,32 +83,32 @@ top::Operation ::= e::Expr _ _ aspect production plusPlusOperationString top::Operation ::= { - top.appendProd = plusPlus(_, '++', _, location=_); + top.appendProd = plusPlus(_, '++', _); } aspect production plusPlusOperationList top::Operation ::= { - top.appendProd = plusPlus(_, '++', _, location=_); + top.appendProd = plusPlus(_, '++', _); } aspect production borOperation top::Operation ::= { - top.appendProd = or(_, '||', _, location=_); + top.appendProd = or(_, '||', _); } aspect production bandOperation top::Operation ::= { - top.appendProd = and(_, '&&', _, location=_); + top.appendProd = and(_, '&&', _); } aspect production addOperation top::Operation ::= { - top.appendProd = plus(_, '+', _, location=_); + top.appendProd = plus(_, '+', _); } aspect production mulOperation top::Operation ::= { - top.appendProd = multiply(_, '*', _, location=_); + top.appendProd = multiply(_, '*', _); } {-- @@ -120,7 +118,7 @@ top::Operation ::= abstract production propagateMonoid top::ProductionStmt ::= attr::Decorated! QName { - undecorates to propagateOneAttr(attr, location=top.location); + undecorates to propagateOneAttr(attr); top.unparse = s"propagate ${attr.unparse};"; -- No explicit errors, for now. The only conceivable issue is the attribute not @@ -142,17 +140,16 @@ top::ProductionStmt ::= attr::Decorated! QName map( \ i::NamedSignatureElement -> access( - baseExpr(qName(top.location, i.elementName), location=top.location), + baseExpr(qName(i.elementName)), '.', - qNameAttrOccur(new(attr), location=top.location), - location=top.location), + qNameAttrOccur(new(attr))), inputsWithAttr)); -- Construct an attribute def and call with the generated arguments forwards to attrContainsBase( - concreteDefLHS(qName(top.location, top.frame.signature.outputElement.elementName), location=top.location), + concreteDefLHS(qName(top.frame.signature.outputElement.elementName)), '.', - qNameAttrOccur(new(attr), location=top.location), - ':=', res, ';', location=top.location); + qNameAttrOccur(new(attr)), + ':=', res, ';'); } diff --git a/grammars/silver/compiler/extension/autoattr/Ordering.sv b/grammars/silver/compiler/extension/autoattr/Ordering.sv index 190ed9404..af55680c3 100644 --- a/grammars/silver/compiler/extension/autoattr/Ordering.sv +++ b/grammars/silver/compiler/extension/autoattr/Ordering.sv @@ -17,19 +17,18 @@ top::AGDcl ::= 'ordering' 'attribute' keySyn::Name ',' syn::Name 'with' inh::QNa top.errors <- if length(getAttrDclAll(synFName, top.env)) > 1 - then [err(syn.location, "Attribute '" ++ synFName ++ "' is already bound.")] + then [errFromOrigin(syn, "Attribute '" ++ synFName ++ "' is already bound.")] else []; top.errors <- if length(getAttrDclAll(keySynFName, top.env)) > 1 - then [err(syn.location, "Attribute '" ++ keySynFName ++ "' is already bound.")] + then [errFromOrigin(syn, "Attribute '" ++ keySynFName ++ "' is already bound.")] else []; forwards to defsAGDcl( [attrDef(defaultEnvItem(orderingKeyDcl(keySynFName, sourceGrammar=top.grammarName, sourceLocation=syn.location))), - attrDef(defaultEnvItem(orderingDcl(inhFName, keySynFName, synFName, sourceGrammar=top.grammarName, sourceLocation=syn.location)))], - location=top.location); + attrDef(defaultEnvItem(orderingDcl(inhFName, keySynFName, synFName, sourceGrammar=top.grammarName, sourceLocation=syn.location)))]); } {-- @@ -38,13 +37,13 @@ top::AGDcl ::= 'ordering' 'attribute' keySyn::Name ',' syn::Name 'with' inh::QNa abstract production propagateOrderingKey top::ProductionStmt ::= syn::Decorated! QName { - undecorates to propagateOneAttr(syn, location=top.location); + undecorates to propagateOneAttr(syn); top.unparse = s"propagate ${syn.unparse};"; forwards to Silver_ProductionStmt { $name{top.frame.signature.outputElement.elementName}.$QName{new(syn)} = - $Expr{stringConst(terminal(String_t, s"\"${top.frame.fullName}\""), location=top.location)}; + $Expr{stringConst(terminal(String_t, s"\"${top.frame.fullName}\""))}; }; } @@ -54,7 +53,7 @@ top::ProductionStmt ::= syn::Decorated! QName abstract production propagateOrdering top::ProductionStmt ::= inh::String keySyn::String syn::Decorated! QName { - undecorates to propagateOneAttr(syn, location=top.location); + undecorates to propagateOneAttr(syn); top.unparse = s"propagate ${syn.unparse};"; local topName::String = top.frame.signature.outputElement.elementName; @@ -64,16 +63,15 @@ top::ProductionStmt ::= inh::String keySyn::String syn::Decorated! QName case $name{topName}.$name{inh} of | $Pattern{ prodAppPattern( - qName(top.location, top.frame.signature.fullName), + qName(top.frame.signature.fullName), '(', foldr( - patternList_more(_, ',', _, location=top.location), - patternList_nil(location=top.location), + patternList_more(_, ',', _), + patternList_nil(), map( \ ie::NamedSignatureElement -> Silver_Pattern { $name{ie.elementName ++ "2"} }, top.frame.signature.inputElements)), - ')', - location=top.location)} -> + ')')} -> $Expr{ if null(top.frame.signature.inputElements) then Silver_Expr { 0 } diff --git a/grammars/silver/compiler/extension/autoattr/Propagate.sv b/grammars/silver/compiler/extension/autoattr/Propagate.sv index fe38c5f2e..86daf3f64 100644 --- a/grammars/silver/compiler/extension/autoattr/Propagate.sv +++ b/grammars/silver/compiler/extension/autoattr/Propagate.sv @@ -7,7 +7,7 @@ top::AGDcl ::= 'propagate' attrs::NameList 'on' nts::NameList 'excluding' ps::Pr propagate env; top.errors <- ps.errors; - forwards to propagateOnNTListDcl(attrs, nts, ps, location=top.location); + forwards to propagateOnNTListDcl(attrs, nts, ps); } concrete production propagateOnNTListDcl_c @@ -16,7 +16,7 @@ top::AGDcl ::= 'propagate' attrs::NameList 'on' nts::NameList ';' top.unparse = s"propagate ${attrs.unparse} on ${nts.unparse};"; forwards to - propagateOnNTListDcl(attrs, nts, prodNameListNil(location=top.location), location=top.location); + propagateOnNTListDcl(attrs, nts, prodNameListNil()); } abstract production propagateOnNTListDcl @@ -26,12 +26,11 @@ top::AGDcl ::= attrs::NameList nts::NameList ps::ProdNameList forwards to case nts of - | nameListOne(n) -> propagateOnOneNTDcl(attrs, n, ps, location=n.location) + | nameListOne(n) -> propagateOnOneNTDcl(attrs, n, ps) | nameListCons(n, _, rest) -> appendAGDcl( - propagateOnOneNTDcl(attrs, n, ps, location=n.location), - propagateOnNTListDcl(attrs, rest, ps, location=top.location), - location=top.location) + propagateOnOneNTDcl(attrs, n, ps), + propagateOnNTListDcl(attrs, rest, ps)) end; } @@ -58,12 +57,12 @@ top::AGDcl ::= attrs::NameList nt::QName ps::ProdNameList getKnownProds(nt.lookupType.fullName, top.env)); local dcl::AGDcl = foldr( - appendAGDcl(_, _, location=top.location), emptyAGDcl(location=top.location), - map(propagateAspectDcl(_, attrs, location=nt.location), includedProds)); + appendAGDcl(_, _), emptyAGDcl(), + map(propagateAspectDcl(_, attrs), includedProds)); forwards to if !null(nt.lookupType.errors) - then errorAGDcl(nt.lookupType.errors, location=top.location) + then errorAGDcl(nt.lookupType.errors) else dcl; } @@ -77,33 +76,27 @@ top::AGDcl ::= d::ValueDclInfo attrs::NameList forwards to aspectProductionDcl( - 'aspect', 'production', qName(top.location, d.fullName), + 'aspect', 'production', qName(d.fullName), aspectProductionSignature( aspectProductionLHSFull( name(d.namedSignature.outputElement.elementName, top.location), - d.namedSignature.outputElement.typerep, - location=top.location), + d.namedSignature.outputElement.typerep), '::=', foldr( - aspectRHSElemCons(_, _, location=top.location), - aspectRHSElemNil(location=top.location), + aspectRHSElemCons(_, _), + aspectRHSElemNil(), map( \ ie::NamedSignatureElement -> aspectRHSElemFull( name(ie.elementName, top.location), - freshenType(ie.typerep, ie.typerep.freeVariables), - location=top.location), - d.namedSignature.inputElements)), - location=top.location), + freshenType(ie.typerep, ie.typerep.freeVariables)), + d.namedSignature.inputElements))), productionBody( '{', productionStmtsSnoc( - productionStmtsNil(location=top.location), - propagateAttrList('propagate', attrs, ';', location=top.location), - location=top.location), - '}', - location=top.location), - location=top.location); + productionStmtsNil(), + propagateAttrList('propagate', attrs, ';')), + '}')); } concrete production propagateAttrList @@ -115,12 +108,11 @@ top::ProductionStmt ::= 'propagate' ns::NameList ';' -- and propagateAttrDcl containing the remaining names forwards to case ns of - | nameListOne(n) -> propagateOneAttr(n, location=top.location) + | nameListOne(n) -> propagateOneAttr(n) | nameListCons(n, _, rest) -> productionStmtAppend( - propagateOneAttr(n, location=n.location), - propagateAttrList($1, rest, $3, location=top.location), - location=top.location) + propagateOneAttr(n), + propagateAttrList($1, rest, $3)) end; } @@ -143,23 +135,22 @@ top::ProductionStmt ::= attr::QName top.productionAttributes := []; forwards to if !null(attr.lookupAttribute.errors) - then errorProductionStmt(attr.lookupAttribute.errors, location=top.location) + then errorProductionStmt(attr.lookupAttribute.errors) else attr.lookupAttribute.dcl.propagateDispatcher(attr, top.location); } abstract production propagateError top::ProductionStmt ::= attr::Decorated! QName { - undecorates to propagateOneAttr(attr, location=top.location); + undecorates to propagateOneAttr(attr); forwards to errorProductionStmt( - [err(attr.location, s"Attribute ${attr.name} cannot be propagated")], - location=top.location); + [errFromOrigin(attr, s"Attribute ${attr.name} cannot be propagated")]); } -- Need a seperate nonterminal since this can be empty and needs env to check errors -nonterminal ProdNameList with config, grammarName, env, location, unparse, names, errors; +tracked nonterminal ProdNameList with config, grammarName, env, unparse, names, errors; propagate config, grammarName, env, errors on ProdNameList; abstract production prodNameListNil @@ -180,7 +171,7 @@ top::ProdNameList ::= n::QName then case n.lookupValue.dcl of | prodDcl(_, _) -> [] - | _ -> [err(n.location, n.name ++ " is not a production")] + | _ -> [errFromOrigin(n, n.name ++ " is not a production")] end else []; } @@ -196,7 +187,7 @@ top::ProdNameList ::= h::QName ',' t::ProdNameList then case h.lookupValue.dcl of | prodDcl(_, _) -> [] - | _ -> [err(h.location, h.name ++ " is not a production")] + | _ -> [errFromOrigin(h, h.name ++ " is not a production")] end else []; } diff --git a/grammars/silver/compiler/extension/autoattr/Threaded.sv b/grammars/silver/compiler/extension/autoattr/Threaded.sv index 76f7df756..be2d30f6d 100644 --- a/grammars/silver/compiler/extension/autoattr/Threaded.sv +++ b/grammars/silver/compiler/extension/autoattr/Threaded.sv @@ -21,18 +21,17 @@ top::AGDcl ::= 'threaded' 'attribute' inh::Name ',' syn::Name tl::BracketedOptTy top.errors <- if length(getAttrDclAll(inhFName, top.env)) > 1 - then [err(inh.location, "Attribute '" ++ inhFName ++ "' is already bound.")] + then [errFromOrigin(inh, "Attribute '" ++ inhFName ++ "' is already bound.")] else []; top.errors <- if length(getAttrDclAll(synFName, top.env)) > 1 - then [err(syn.location, "Attribute '" ++ synFName ++ "' is already bound.")] + then [errFromOrigin(syn, "Attribute '" ++ synFName ++ "' is already bound.")] else []; forwards to defsAGDcl( [attrDef(defaultEnvItem(threadedInhDcl(inhFName, synFName, tl.freeVariables, te.typerep, nothing(), d.reversed, sourceGrammar=top.grammarName, sourceLocation=inh.location))), - attrDef(defaultEnvItem(threadedSynDcl(inhFName, synFName, tl.freeVariables, te.typerep, nothing(), d.reversed, sourceGrammar=top.grammarName, sourceLocation=syn.location)))], - location=top.location); + attrDef(defaultEnvItem(threadedSynDcl(inhFName, synFName, tl.freeVariables, te.typerep, nothing(), d.reversed, sourceGrammar=top.grammarName, sourceLocation=syn.location)))]); } concrete production collectionThreadedAttributeDcl @@ -57,11 +56,11 @@ top::AGDcl ::= 'threaded' 'attribute' inh::Name ',' syn::Name tl::BracketedOptTy top.errors <- if length(getAttrDclAll(inhFName, top.env)) > 1 - then [err(inh.location, "Attribute '" ++ inhFName ++ "' is already bound.")] + then [errFromOrigin(inh, "Attribute '" ++ inhFName ++ "' is already bound.")] else []; top.errors <- if length(getAttrDclAll(synFName, top.env)) > 1 - then [err(syn.location, "Attribute '" ++ synFName ++ "' is already bound.")] + then [errFromOrigin(syn, "Attribute '" ++ synFName ++ "' is already bound.")] else []; -- TODO: We want to forward to collection attr decls for the translation, but provide our own defs. @@ -73,14 +72,13 @@ top::AGDcl ::= 'threaded' 'attribute' inh::Name ',' syn::Name tl::BracketedOptTy forwards to appendAGDcl( - collectionAttributeDclInh('inherited', 'attribute', inh, tl, '::', te, 'with', q, ';', location=top.location), - collectionAttributeDclSyn('synthesized', 'attribute', syn, tl, '::', te, 'with', q, ';', location=top.location), - location=top.location); + collectionAttributeDclInh('inherited', 'attribute', inh, tl, '::', te, 'with', q, ';'), + collectionAttributeDclSyn('synthesized', 'attribute', syn, tl, '::', te, 'with', q, ';')); } synthesized attribute reversed::Boolean; -nonterminal OptDirectionMod with unparse, reversed; +tracked nonterminal OptDirectionMod with unparse, reversed; concrete productions top::OptDirectionMod | 'direction' '=' d::Direction { top.unparse = " direction=" ++ d.unparse; @@ -89,7 +87,7 @@ concrete productions top::OptDirectionMod { top.unparse = ""; top.reversed = false; } -nonterminal Direction with unparse, reversed; +tracked nonterminal Direction with unparse, reversed; concrete productions top::Direction | 'left' 'to' 'right' { top.unparse = "left to right"; @@ -101,7 +99,7 @@ concrete productions top::Direction abstract production propagateThreadedInh top::ProductionStmt ::= isCol::Boolean rev::Boolean inh::Decorated! QName syn::String { - undecorates to propagateOneAttr(inh, location=top.location); + undecorates to propagateOneAttr(inh); top.unparse = s"propagate ${inh.unparse};"; local lhsName::String = top.frame.signature.outputElement.elementName; @@ -132,14 +130,13 @@ top::ProductionStmt ::= isCol::Boolean rev::Boolean inh::Decorated! QName syn::S then if !null(getOccursDcl(inh.lookupAttribute.fullName, last(top.frame.signature.inputElements).typerep.typeName, top.env)) then [last(top.frame.signature.inputElements).elementName] else [] - else [if !null(getValueDcl("forward", top.env)) then "forward" else lhsName]), - location=top.location); + else [if !null(getValueDcl("forward", top.env)) then "forward" else lhsName])); } abstract production propagateThreadedSyn top::ProductionStmt ::= isCol::Boolean rev::Boolean inh::String syn::Decorated! QName { - undecorates to propagateOneAttr(syn, location=top.location); + undecorates to propagateOneAttr(syn); top.unparse = s"propagate ${syn.unparse};"; local lhsName::String = top.frame.signature.outputElement.elementName; @@ -164,8 +161,7 @@ top::ProductionStmt ::= isCol::Boolean rev::Boolean inh::String syn::Decorated! name(_, top.location), lhsName :: (if rev then reverse(occursChildren) else occursChildren) ++ - [if !null(getValueDcl("forward", top.env)) then "forward" else lhsName]), - location=top.location); + [if !null(getValueDcl("forward", top.env)) then "forward" else lhsName])); } concrete production threadDcl_c @@ -182,13 +178,10 @@ top::ProductionStmt ::= 'thread' inh::QName ',' syn::QName 'on' children::ChildN productionStmtAppend( threadInhDcl( inh.lookupAttribute.found && inh.lookupAttribute.dcl.isCollection, - inh.name, syn.name, children.ids, - location=top.location), + inh.name, syn.name, children.ids), threadSynDcl( syn.lookupAttribute.found && syn.lookupAttribute.dcl.isCollection, - inh.name, syn.name, children.ids, - location=top.location), - location=top.location); + inh.name, syn.name, children.ids)); } abstract production threadInhDcl @@ -199,24 +192,23 @@ top::ProductionStmt ::= isCol::Boolean inh::String syn::String children::[Name] local lhsName::String = top.frame.signature.outputElement.elementName; local attrDefProd::(ProductionStmt ::= DefLHS QNameAttrOccur Expr) = if isCol - then attrContainsBase(_, '.', _, ':=', _, ';', location=top.location) - else attributeDef(_, '.', _, '=', _, ';', location=top.location); + then attrContainsBase(_, '.', _, ':=', _, ';') + else attributeDef(_, '.', _, '=', _, ';'); forwards to foldr( - productionStmtAppend(_, _, location=top.location), - errorProductionStmt([], location=top.location), -- No emptyProductionStmt? + productionStmtAppend(_, _), + errorProductionStmt([]), -- No emptyProductionStmt? zipWith( \ c1::Name c2::Name -> if c1.name != lhsName then attrDefProd( - concreteDefLHS(qNameId(c1, location=top.location), location=top.location), - qNameAttrOccur(qName(top.location, inh), location=top.location), + concreteDefLHS(qNameId(c1)), + qNameAttrOccur(qName(inh)), access( - baseExpr(qNameId(c2, location=top.location), location=top.location), '.', - qNameAttrOccur(qName(top.location, if c2.name == lhsName then inh else syn), location=top.location), - location=top.location)) - else errorProductionStmt([], location=top.location), + baseExpr(qNameId(c2)), '.', + qNameAttrOccur(qName(if c2.name == lhsName then inh else syn)))) + else errorProductionStmt([]), tail(children), children)); } @@ -228,30 +220,29 @@ top::ProductionStmt ::= isCol::Boolean inh::String syn::String children::[Name] local lhsName::String = top.frame.signature.outputElement.elementName; local attrDefProd::(ProductionStmt ::= DefLHS QNameAttrOccur Expr) = if isCol - then attrContainsBase(_, '.', _, ':=', _, ';', location=top.location) - else attributeDef(_, '.', _, '=', _, ';', location=top.location); + then attrContainsBase(_, '.', _, ':=', _, ';') + else attributeDef(_, '.', _, '=', _, ';'); forwards to foldr( - productionStmtAppend(_, _, location=top.location), - errorProductionStmt([], location=top.location), -- No emptyProductionStmt? + productionStmtAppend(_, _), + errorProductionStmt([]), -- No emptyProductionStmt? zipWith( \ c1::Name c2::Name -> if c1.name == lhsName then attrDefProd( - concreteDefLHS(qNameId(c1, location=top.location), location=top.location), - qNameAttrOccur(qName(top.location, syn), location=top.location), + concreteDefLHS(qNameId(c1)), + qNameAttrOccur(qName(syn)), access( - baseExpr(qNameId(c2, location=top.location), location=top.location), '.', - qNameAttrOccur(qName(top.location, if c2.name == lhsName then inh else syn), location=top.location), - location=top.location)) - else errorProductionStmt([], location=top.location), + baseExpr(qNameId(c2)), '.', + qNameAttrOccur(qName(if c2.name == lhsName then inh else syn)))) + else errorProductionStmt([]), tail(children), children)); } synthesized attribute ids :: [Name]; -nonterminal ChildNameList with location, unparse, ids; +tracked nonterminal ChildNameList with unparse, ids; concrete production idSingle top::ChildNameList ::= id::ChildName { @@ -268,7 +259,7 @@ top::ChildNameList ::= id1::ChildName ',' id2::ChildNameList synthesized attribute id :: Name; -nonterminal ChildName with location, unparse, id; +tracked nonterminal ChildName with unparse, id; concrete production idName top::ChildName ::= id::Name { @@ -280,6 +271,6 @@ concrete production idForward top::ChildName ::= 'forward' { top.unparse = "forward"; - top.id = name("forward", top.location); + top.id = name("forward"); } diff --git a/grammars/silver/compiler/extension/autoattr/convenience/Convenience.sv b/grammars/silver/compiler/extension/autoattr/convenience/Convenience.sv index 93e9fd2a6..9ae3e2a90 100644 --- a/grammars/silver/compiler/extension/autoattr/convenience/Convenience.sv +++ b/grammars/silver/compiler/extension/autoattr/convenience/Convenience.sv @@ -15,9 +15,8 @@ top::AGDcl ::= 'functor' 'attribute' a::Name 'occurs' 'on' qs::QNames ';' top.unparse = "functor attribute " ++ a.name ++ " occurs on " ++ qs.unparse ++ ";"; forwards to appendAGDcl( - functorAttributeDcl($1, $2, a, $7, location=a.location), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(a, location=a.location), botlNone(location=top.location)), qs.qnames), - location=top.location); + functorAttributeDcl($1, $2, a, $7), + makeOccursDclsHelp($1.location, qNameWithTL(qNameId(a), botlNone()), qs.qnames)); } concrete production monoidAttributeDclMultiple @@ -26,9 +25,8 @@ top::AGDcl ::= 'monoid' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te::T top.unparse = "monoid attribute " ++ a.unparse ++ tl.unparse ++ " :: " ++ te.unparse ++ " with " ++ e.unparse ++ ", " ++ q.unparse ++ " occurs on " ++ qs.unparse ++ ";"; forwards to appendAGDcl( - monoidAttributeDcl($1, $2, a, tl, $5, te, $7, e, $9, q, $14, location=a.location), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(a, location=a.location), botlNone(location=top.location)), qs.qnames), - location=top.location); + monoidAttributeDcl($1, $2, a, tl, $5, te, $7, e, $9, q, $14), + makeOccursDclsHelp($1.location, qNameWithTL(qNameId(a), botlNone()), qs.qnames)); } concrete production tcMonoidAttributeDclMultiple @@ -37,9 +35,8 @@ top::AGDcl ::= 'monoid' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te::T top.unparse = "monoid attribute " ++ a.unparse ++ tl.unparse ++ " :: " ++ te.unparse ++ " occurs on " ++ qs.unparse ++ ";"; forwards to appendAGDcl( - tcMonoidAttributeDcl($1, $2, a, tl, $5, te, $10, location=a.location), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(a, location=a.location), botlNone(location=top.location)), qs.qnames), - location=top.location); + tcMonoidAttributeDcl($1, $2, a, tl, $5, te, $10), + makeOccursDclsHelp($1.location, qNameWithTL(qNameId(a), botlNone()), qs.qnames)); } concrete production destructAttributeDclMultiple @@ -48,9 +45,8 @@ top::AGDcl ::= 'destruct' 'attribute' a::Name 'occurs' 'on' qs::QNames ';' top.unparse = "destruct attribute " ++ a.name ++ " occurs on " ++ qs.unparse ++ ";"; forwards to appendAGDcl( - destructAttributeDcl($1, $2, a, ';', location=a.location), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(a, location=a.location), botlNone(location=top.location)), qs.qnames), - location=top.location); + destructAttributeDcl($1, $2, a, ';'), + makeOccursDclsHelp($1.location, qNameWithTL(qNameId(a), botlNone()), qs.qnames)); } concrete production equalityAttributeDclMultiple @@ -59,9 +55,8 @@ top::AGDcl ::= 'equality' 'attribute' syn::Name 'with' inh::QName 'occurs' 'on' top.unparse = "equality attribute " ++ syn.name ++ " with " ++ inh.unparse ++ " occurs on " ++ qs.unparse ++ ";"; forwards to appendAGDcl( - equalityAttributeDcl($1, $2, syn, $4, inh, $9, location=top.location), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(syn, location=syn.location), botlNone(location=top.location)), qs.qnames), - location=top.location); + equalityAttributeDcl($1, $2, syn, $4, inh, $9), + makeOccursDclsHelp($1.location, qNameWithTL(qNameId(syn), botlNone()), qs.qnames)); } concrete production orderingAttributeDclMultiple @@ -70,12 +65,10 @@ top::AGDcl ::= 'ordering' 'attribute' keySyn::Name ',' syn::Name 'with' inh::QNa top.unparse = "ordering attribute " ++ keySyn.name ++ ", " ++ syn.name ++ " with " ++ inh.unparse ++ " occurs on " ++ qs.unparse ++ ";"; forwards to appendAGDcl( - orderingAttributeDcl($1, $2, keySyn, $4, syn, $6, inh, $11, location=top.location), + orderingAttributeDcl($1, $2, keySyn, $4, syn, $6, inh, $11), appendAGDcl( - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(keySyn, location=syn.location), botlNone(location=top.location)), qs.qnames), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(syn, location=syn.location), botlNone(location=top.location)), qs.qnames), - location=top.location), - location=top.location); + makeOccursDclsHelp($1.location, qNameWithTL(qNameId(keySyn), botlNone()), qs.qnames), + makeOccursDclsHelp($1.location, qNameWithTL(qNameId(syn), botlNone()), qs.qnames))); } -- Deprecate? Eric suggested keeping this: https://github.com/melt-umn/silver/issues/431#issuecomment-760552226 @@ -85,9 +78,8 @@ top::AGDcl ::= 'equality' 'attribute' inh::Name ',' syn::Name ';' top.unparse = "equality attribute " ++ inh.unparse ++ ", " ++ syn.name ++ ";"; forwards to appendAGDcl( - destructAttributeDcl('destruct', $2, inh, $6, location=top.location), - equalityAttributeDcl($1, $2, syn, 'with', qNameId(inh, location=top.location), $6, location=top.location), - location=top.location); + destructAttributeDcl('destruct', $2, inh, $6), + equalityAttributeDcl($1, $2, syn, 'with', qNameId(inh), $6)); } concrete production destructEqualityAttributeDclMultiple top::AGDcl ::= 'equality' 'attribute' inh::Name ',' syn::Name 'occurs' 'on' qs::QNames ';' @@ -95,9 +87,8 @@ top::AGDcl ::= 'equality' 'attribute' inh::Name ',' syn::Name 'occurs' 'on' qs:: top.unparse = "equality attribute " ++ inh.unparse ++ ", " ++ syn.name ++ " occurs on " ++ qs.unparse ++ ";"; forwards to appendAGDcl( - destructAttributeDclMultiple('destruct', $2, inh, $6, $7, qs, $9, location=top.location), - equalityAttributeDclMultiple($1, $2, syn, 'with', qNameId(inh, location=top.location), $6, $7, qs, $9, location=top.location), - location=top.location); + destructAttributeDclMultiple('destruct', $2, inh, $6, $7, qs, $9), + equalityAttributeDclMultiple($1, $2, syn, 'with', qNameId(inh), $6, $7, qs, $9)); } concrete production destructOrderingAttributeDcl top::AGDcl ::= 'ordering' 'attribute' inh::Name ',' keySyn::Name ',' syn::Name ';' @@ -105,9 +96,8 @@ top::AGDcl ::= 'ordering' 'attribute' inh::Name ',' keySyn::Name ',' syn::Name ' top.unparse = "ordering attribute " ++ inh.unparse ++ ", " ++ keySyn.name ++ ", " ++ syn.name ++ ";"; forwards to appendAGDcl( - destructAttributeDcl('destruct', $2, inh, $8, location=top.location), - orderingAttributeDcl($1, $2, keySyn, $6, syn, 'with', qNameId(inh, location=top.location), $8, location=top.location), - location=top.location); + destructAttributeDcl('destruct', $2, inh, $8), + orderingAttributeDcl($1, $2, keySyn, $6, syn, 'with', qNameId(inh), $8)); } concrete production destructOrderingAttributeDclMultiple top::AGDcl ::= 'ordering' 'attribute' inh::Name ',' keySyn::Name ',' syn::Name 'occurs' 'on' qs::QNames ';' @@ -115,9 +105,8 @@ top::AGDcl ::= 'ordering' 'attribute' inh::Name ',' keySyn::Name ',' syn::Name ' top.unparse = "ordering attribute " ++ inh.unparse ++ ", " ++ keySyn.name ++ ", " ++ syn.name ++ " occurs on " ++ qs.unparse ++ ";"; forwards to appendAGDcl( - destructAttributeDclMultiple('destruct', $2, inh, $8, $9, qs, $11, location=top.location), - orderingAttributeDclMultiple($1, $2, keySyn, $6, syn, 'with', qNameId(inh, location=top.location), $8, $9, qs, $11, location=top.location), - location=top.location); + destructAttributeDclMultiple('destruct', $2, inh, $8, $9, qs, $11), + orderingAttributeDclMultiple($1, $2, keySyn, $6, syn, 'with', qNameId(inh), $8, $9, qs, $11)); } concrete production biequalityAttributeDclMultiple @@ -126,12 +115,10 @@ top::AGDcl ::= 'biequality' 'attribute' synPartial::Name ',' syn::Name 'with' in top.unparse = "biequality attribute " ++ synPartial.name ++ ", " ++ syn.name ++ " with " ++ inh.unparse ++ " occurs on " ++ qs.unparse ++ ";"; forwards to appendAGDcl( - biequalityAttributeDcl($1, $2, synPartial, ',', syn, 'with', inh, ';', location=top.location), + biequalityAttributeDcl($1, $2, synPartial, ',', syn, 'with', inh, ';'), appendAGDcl( - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(synPartial, location=synPartial.location), botlNone(location=top.location)), qs.qnames), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(syn, location=syn.location), botlNone(location=top.location)), qs.qnames), - location=top.location), - location=top.location); + makeOccursDclsHelp($1.location, qNameWithTL(qNameId(synPartial), botlNone()), qs.qnames), + makeOccursDclsHelp($1.location, qNameWithTL(qNameId(syn), botlNone()), qs.qnames))); } concrete production threadedAttributeDclMultiple @@ -140,12 +127,10 @@ top::AGDcl ::= 'threaded' 'attribute' inh::Name ',' syn::Name tl::BracketedOptTy top.unparse = "threaded attribute " ++ inh.unparse ++ ", " ++ syn.name ++ tl.unparse ++ " :: " ++ te.unparse ++ d.unparse ++ " occurs on " ++ qs.unparse ++ ";"; forwards to appendAGDcl( - threadedAttributeDcl($1, $2, inh, $4, syn, tl, $7, te, d, ';', location=top.location), + threadedAttributeDcl($1, $2, inh, $4, syn, tl, $7, te, d, ';'), appendAGDcl( - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(inh, location=inh.location), botlNone(location=top.location)), qs.qnames), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(syn, location=syn.location), botlNone(location=top.location)), qs.qnames), - location=top.location), - location=top.location); + makeOccursDclsHelp($1.location, qNameWithTL(qNameId(inh), botlNone()), qs.qnames), + makeOccursDclsHelp($1.location, qNameWithTL(qNameId(syn), botlNone()), qs.qnames))); } concrete production collectionThreadedAttributeDclMultiple @@ -154,10 +139,8 @@ top::AGDcl ::= 'threaded' 'attribute' inh::Name ',' syn::Name tl::BracketedOptTy top.unparse = "threaded attribute " ++ inh.unparse ++ ", " ++ syn.name ++ tl.unparse ++ " :: " ++ te.unparse ++ " with " ++ q.unparse ++ d.unparse ++ " occurs on " ++ qs.unparse ++ ";"; forwards to appendAGDcl( - collectionThreadedAttributeDcl($1, $2, inh, $4, syn, tl, $7, te, 'with', q, d, ';', location=top.location), + collectionThreadedAttributeDcl($1, $2, inh, $4, syn, tl, $7, te, 'with', q, d, ';'), appendAGDcl( - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(inh, location=inh.location), botlNone(location=top.location)), qs.qnames), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(syn, location=syn.location), botlNone(location=top.location)), qs.qnames), - location=top.location), - location=top.location); + makeOccursDclsHelp($1.location, qNameWithTL(qNameId(inh), botlNone()), qs.qnames), + makeOccursDclsHelp($1.location, qNameWithTL(qNameId(syn), botlNone()), qs.qnames))); } diff --git a/grammars/silver/compiler/extension/constructparser/Construct.sv b/grammars/silver/compiler/extension/constructparser/Construct.sv index 4a6408263..57a720683 100644 --- a/grammars/silver/compiler/extension/constructparser/Construct.sv +++ b/grammars/silver/compiler/extension/constructparser/Construct.sv @@ -16,64 +16,50 @@ top::Root ::= gdcl::GrammarDcl mStmts::ModuleStmts is::ImportStmts { local agDcls :: AGDcls = consAGDcls(setJarName, consAGDcls(prsr, consAGDcls(main, - nilAGDcls(location=top.location), location=top.location), - location=top.location), location=top.location); + nilAGDcls()))); - local setJarName :: AGDcl = jarNameDcl(parserName, location=top.location); + local setJarName :: AGDcl = jarNameDcl(parserName); local prsr :: AGDcl = - parserDcl('parser', name("extendedParser", top.location), '::', - nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "Root"), location=top.location), location=top.location), + parserDcl('parser', name("extendedParser"), '::', + nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "Root"))), '{', consParserComponent( - parserComponent(moduleName(m, location=top.location), - nilParserComponentModifier(location=top.location), ';', location=top.location), - ms, location=top.location), - '}', location=top.location); + parserComponent(moduleName(m), + nilParserComponentModifier(), ';'), + ms), + '}'); local main :: AGDcl = - functionDcl('function', name("main", top.location), + functionDcl('function', name("main"), functionSignature( - nilConstraint(location=top.location), + nilConstraint(), '=>', functionLHS( appTypeExpr( nominalTypeExpr( - qNameTypeId(terminal(IdUpper_t, "IOVal"), location=top.location), - location=top.location), - bTypeList('<', typeListSingle(integerTypeExpr('Integer', location=top.location), - location=top.location), '>', location=top.location), - location=top.location - ), - location=top.location), + qNameTypeId(terminal(IdUpper_t, "IOVal"))), + bTypeList('<', typeListSingle(integerTypeExpr('Integer')), '>'))), '::=', productionRHSCons( - productionRHSElem(name("args", top.location), '::', - listTypeExpr('[', stringTypeExpr('String', location=top.location), ']', - location=top.location), location=top.location), + productionRHSElem(name("args"), '::', + listTypeExpr('[', stringTypeExpr('String'), ']')), productionRHSCons( - productionRHSElem(name("ioIn", top.location), '::', - nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "IOToken"), location=top.location), location=top.location), - location=top.location), - productionRHSNil(location=top.location), - location=top.location - ), - location=top.location - ), location=top.location), + productionRHSElem(name("ioIn"), '::', + nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "IOToken")))), + productionRHSNil()))), productionBody('{', - productionStmtsSnoc(productionStmtsNil(location=top.location), + productionStmtsSnoc(productionStmtsNil(), returnDef('return', Silver_Expr { driver(args, ioIn, extendedParser) }, - ';', location=top.location), - location=top.location), - '}', location=top.location), - location=top.location); + ';')), + '}')); local importStmts :: ImportStmts = consImportStmts( - importStmt('import', moduleAll(m, location=top.location), ';', location=top.location), - is, location=top.location); + importStmt('import', moduleAll(m), ';'), + is); - forwards to root(gdcl, mStmts, importStmts, agDcls, location=top.location); + forwards to root(gdcl, mStmts, importStmts, agDcls); } diff --git a/grammars/silver/compiler/extension/convenience/Children.sv b/grammars/silver/compiler/extension/convenience/Children.sv index 5cd81cc3b..14b8ae09a 100644 --- a/grammars/silver/compiler/extension/convenience/Children.sv +++ b/grammars/silver/compiler/extension/convenience/Children.sv @@ -18,7 +18,7 @@ top::Expr ::= '$' e::Int_t findChild(toInteger(e.lexeme), [top.frame.signature.outputElement.elementName] ++ top.frame.signature.inputNames)); - forwards to baseExpr(qName(top.location, ref), location=top.location); + forwards to baseExpr(qName(ref)); } function findChild diff --git a/grammars/silver/compiler/extension/convenience/Convenience.sv b/grammars/silver/compiler/extension/convenience/Convenience.sv index 6ca6c91b3..58b73bbbe 100644 --- a/grammars/silver/compiler/extension/convenience/Convenience.sv +++ b/grammars/silver/compiler/extension/convenience/Convenience.sv @@ -53,11 +53,10 @@ top::AGDcl ::= quals::NTDeclQualifiers 'nonterminal' id::Name tl::BracketedOptTy { top.unparse = "nonterminal " ++ id.unparse ++ tl.unparse ++ " " ++ nm.unparse ++ " with " ++ attrs.unparse ++ " ;"; forwards to appendAGDcl( - nonterminalDcl(quals, $2, id, tl, nm, $8, location=top.location), - makeOccursDcls(top.location, attrs.qnames, [qNameWithTL(qNameId(id, location=id.location), tl)]), - location=top.location); + nonterminalDcl(quals, $2, id, tl, nm, $8), + makeOccursDcls(top.location, attrs.qnames, [qNameWithTL(qNameId(id), tl)])); } action { - insert semantic token IdTypeDcl_t at id.location; + insert semantic token IdTypeDcl_t at id.nameLoc; } @@ -66,9 +65,8 @@ top::AGDcl ::= 'inherited' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te { top.unparse = "inherited attribute " ++ a.name ++ tl.unparse ++ " :: " ++ te.unparse ++ " occurs on " ++ qs.unparse ++ ";" ; forwards to appendAGDcl( - attributeDclInh($1, $2, a, tl, $5, te, $10, location=top.location), - makeOccursDclsHelp(top.location, qNameWithTL(qNameId(a, location=a.location), tl), qs.qnames), - location=top.location); + attributeDclInh($1, $2, a, tl, $5, te, $10), + makeOccursDclsHelp(top.location, qNameWithTL(qNameId(a), tl), qs.qnames)); } concrete production attributeDclSynMultiple @@ -76,9 +74,8 @@ top::AGDcl ::= 'synthesized' 'attribute' a::Name tl::BracketedOptTypeExprs '::' { top.unparse = "synthesized attribute " ++ a.name ++ tl.unparse ++ " :: " ++ te.unparse ++ " occurs on " ++ qs.unparse ++ ";" ; forwards to appendAGDcl( - attributeDclSyn($1, $2, a, tl, $5, te, $10, location=top.location), - makeOccursDclsHelp(top.location, qNameWithTL(qNameId(a, location=a.location), tl), qs.qnames), - location=top.location); + attributeDclSyn($1, $2, a, tl, $5, te, $10), + makeOccursDclsHelp(top.location, qNameWithTL(qNameId(a), tl), qs.qnames)); } concrete production attributeDclTransMultiple @@ -86,9 +83,8 @@ top::AGDcl ::= 'translation' 'attribute' a::Name tl::BracketedOptTypeExprs '::' { top.unparse = "translation attribute " ++ a.name ++ tl.unparse ++ " :: " ++ te.unparse ++ " occurs on " ++ qs.unparse ++ ";" ; forwards to appendAGDcl( - attributeDclTrans($1, $2, a, tl, $5, te, $10, location=top.location), - makeOccursDclsHelp(top.location, qNameWithTL(qNameId(a, location=a.location), tl), qs.qnames), - location=top.location); + attributeDclTrans($1, $2, a, tl, $5, te, $10), + makeOccursDclsHelp(top.location, qNameWithTL(qNameId(a), tl), qs.qnames)); } concrete production collectionAttributeDclInhMultiple @@ -96,9 +92,8 @@ top::AGDcl ::= 'inherited' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te { top.unparse = "inherited attribute " ++ a.name ++ tl.unparse ++ " :: " ++ te.unparse ++ " with " ++ q.unparse ++ " ;" ; forwards to appendAGDcl( - collectionAttributeDclInh($1, $2, a, tl, $5, te, $7, q, $12, location=top.location), - makeOccursDclsHelp(top.location, qNameWithTL(qNameId(a, location=a.location), tl), qs.qnames), - location=top.location); + collectionAttributeDclInh($1, $2, a, tl, $5, te, $7, q, $12), + makeOccursDclsHelp(top.location, qNameWithTL(qNameId(a), tl), qs.qnames)); } concrete production collectionAttributeDclSynMultiple @@ -106,9 +101,8 @@ top::AGDcl ::= 'synthesized' 'attribute' a::Name tl::BracketedOptTypeExprs '::' { top.unparse = "synthesized attribute " ++ a.name ++ tl.unparse ++ " :: " ++ te.unparse ++ " with " ++ q.unparse ++ " ;" ; forwards to appendAGDcl( - collectionAttributeDclSyn($1, $2, a, tl, $5, te, $7, q, $12, location=top.location), - makeOccursDclsHelp(top.location, qNameWithTL(qNameId(a, location=a.location), tl), qs.qnames), - location=top.location); + collectionAttributeDclSyn($1, $2, a, tl, $5, te, $7, q, $12), + makeOccursDclsHelp(top.location, qNameWithTL(qNameId(a), tl), qs.qnames)); } diff --git a/grammars/silver/compiler/extension/convenience/Lists.sv b/grammars/silver/compiler/extension/convenience/Lists.sv index 700be4edc..4130d6468 100644 --- a/grammars/silver/compiler/extension/convenience/Lists.sv +++ b/grammars/silver/compiler/extension/convenience/Lists.sv @@ -1,6 +1,6 @@ grammar silver:compiler:extension:convenience; -nonterminal QNameWithTL with unparse,qnwtQN, qnwtTL; +tracked nonterminal QNameWithTL with unparse,qnwtQN, qnwtTL; synthesized attribute qnwtQN :: QName; synthesized attribute qnwtTL :: BracketedOptTypeExprs; @@ -17,8 +17,8 @@ top::QNameWithTL ::= qn::QName tl::BracketedOptTypeExprs list just one, then it goes to the ordinary, non-convenience extension form. -} -nonterminal QNames2 with unparse, qnames; -nonterminal QNames with unparse, qnames; +tracked nonterminal QNames2 with unparse, qnames; +tracked nonterminal QNames with unparse, qnames; synthesized attribute qnames :: [QNameWithTL]; @@ -57,18 +57,18 @@ function makeOccursDcls AGDcl ::= l::Location ats::[QNameWithTL] nts::[QNameWithTL] { return if null(ats) - then emptyAGDcl(location=l) - else appendAGDcl(makeOccursDclsHelp(l, head(ats), nts), makeOccursDcls(l, tail(ats), nts), location=l); + then emptyAGDcl() + else appendAGDcl(makeOccursDclsHelp(l, head(ats), nts), makeOccursDcls(l, tail(ats), nts)); } function makeOccursDclsHelp AGDcl ::= l::Location at::QNameWithTL nts::[QNameWithTL] { return if null(nts) - then emptyAGDcl(location=l) + then emptyAGDcl() else appendAGDcl( - attributionDcl('attribute', at.qnwtQN, at.qnwtTL, 'occurs', 'on', head(nts).qnwtQN, head(nts).qnwtTL, ';', location=l), - makeOccursDclsHelp(l, at, tail(nts)), location=l); + attributionDcl('attribute', at.qnwtQN, at.qnwtTL, 'occurs', 'on', head(nts).qnwtQN, head(nts).qnwtTL, ';'), + makeOccursDclsHelp(l, at, tail(nts))); } @@ -77,7 +77,7 @@ AGDcl ::= l::Location at::QNameWithTL nts::[QNameWithTL] synthesized attribute ids :: [Name]; -nonterminal Names2 with unparse, ids; +tracked nonterminal Names2 with unparse, ids; concrete production id2Single top::Names2 ::= id::Name ',' id2::Name { @@ -92,7 +92,7 @@ top::Names2 ::= id1::Name ',' id2::Names2 top.ids = [id1] ++ id2.ids; } -nonterminal Names with unparse, ids; +tracked nonterminal Names with unparse, ids; concrete production idSingle top::Names ::= id::Name { diff --git a/grammars/silver/compiler/extension/convenience/Productions.sv b/grammars/silver/compiler/extension/convenience/Productions.sv index 525b1e9e1..c9780c570 100644 --- a/grammars/silver/compiler/extension/convenience/Productions.sv +++ b/grammars/silver/compiler/extension/convenience/Productions.sv @@ -6,12 +6,12 @@ import silver:compiler:modification:copper; concrete production productionDclImplicitAbs top::AGDcl ::= 'production' id::Name ns::ProductionSignature body::ProductionBody { - forwards to productionDcl('abstract', $1, id, ns, body, location=top.location); + forwards to productionDcl('abstract', $1, id, ns, body); } -- "concrete productions" syntax -nonterminal ProductionDclStmts with unparse, location, proddcls, lhsdcl, grammarName; -nonterminal ProductionDclStmt with unparse, location, proddcls, lhsdcl, grammarName; +tracked nonterminal ProductionDclStmts with unparse, proddcls, lhsdcl, grammarName; +tracked nonterminal ProductionDclStmt with unparse, proddcls, lhsdcl, grammarName; propagate lhsdcl, grammarName on ProductionDclStmts, ProductionDclStmt; synthesized attribute proddcls :: AGDcl; @@ -41,7 +41,7 @@ concrete production productionDclStmtsCons top::ProductionDclStmts ::= s::ProductionDclStmt ss::ProductionDclStmts { top.unparse = s.unparse ++ ss.unparse; - top.proddcls = appendAGDcl(s.proddcls, ss.proddcls, location=top.location); + top.proddcls = appendAGDcl(s.proddcls, ss.proddcls); } concrete production productionDclStmt @@ -66,18 +66,18 @@ top::ProductionDclStmt ::= optn::OptionalName v::ProdVBar end; local newSig :: ProductionSignature = - productionSignature(nilConstraint(location=top.location), '=>', top.lhsdcl, '::=', rhs, location=rhs.location); + productionSignature(nilConstraint(), '=>', top.lhsdcl, '::=', rhs); top.proddcls = case opta of | noOptionalAction() -> - concreteProductionDcl('concrete', 'production', nme, newSig, mods, body, location=top.location) + concreteProductionDcl('concrete', 'production', nme, newSig, mods, body) | anOptionalAction(a,c) -> - concreteProductionDclAction('concrete', 'production', nme, newSig, mods, body, a, c, location=top.location) + concreteProductionDclAction('concrete', 'production', nme, newSig, mods, body, a, c) end; } -nonterminal OptionalName with location; +tracked nonterminal OptionalName; concrete production noOptionalName optn::OptionalName ::= { @@ -87,7 +87,7 @@ optn::OptionalName ::= '(' id::Name ')' { } -nonterminal OptionalAction with location; +tracked nonterminal OptionalAction; concrete production noOptionalAction opta::OptionalAction ::= { diff --git a/grammars/silver/compiler/extension/convenience/ShortLocalProdAttrDeclDef.sv b/grammars/silver/compiler/extension/convenience/ShortLocalProdAttrDeclDef.sv index e4f52b3da..06d151423 100644 --- a/grammars/silver/compiler/extension/convenience/ShortLocalProdAttrDeclDef.sv +++ b/grammars/silver/compiler/extension/convenience/ShortLocalProdAttrDeclDef.sv @@ -6,9 +6,8 @@ top::ProductionStmt ::= lk::'local' a::Name ht::'::' te::TypeExpr { forwards to productionStmtAppend( - localAttributeDcl(lk, 'attribute', a, ht, te, sm, location=top.location), - valueEq(qNameId(a, location=a.location), eq, v, sm, location=v.location), - location=top.location); + localAttributeDcl(lk, 'attribute', a, ht, te, sm), + valueEq(qNameId(a), eq, v, sm)); } concrete production shortLocalDeclwKwds @@ -17,9 +16,8 @@ top::ProductionStmt ::= lk::'local' ak::'attribute' a::Name ht::'::' te::TypeExp { forwards to productionStmtAppend( - localAttributeDcl(lk, ak, a, ht, te, sm, location=top.location), - valueEq(qNameId(a, location=a.location), eq, v, sm, location=v.location), - location=top.location); + localAttributeDcl(lk, ak, a, ht, te, sm), + valueEq(qNameId(a), eq, v, sm)); } concrete production shortProductionDecl @@ -28,9 +26,8 @@ top::ProductionStmt ::= pk::'production' a::Name ht::'::' te::TypeExpr { forwards to productionStmtAppend( - productionAttributeDcl(pk, 'attribute', a, ht, te, sm, location=top.location), - valueEq(qNameId(a, location=a.location), eq, v, sm, location=v.location), - location=top.location); + productionAttributeDcl(pk, 'attribute', a, ht, te, sm), + valueEq(qNameId(a), eq, v, sm)); } concrete production shortProductionDeclwKwds @@ -39,9 +36,8 @@ top::ProductionStmt ::= pk::'production' ak::'attribute' { forwards to productionStmtAppend( - productionAttributeDcl(pk, ak, a, ht, te, sm, location=top.location), - valueEq(qNameId(a, location=a.location), eq, v, sm, location=v.location), - location=top.location); + productionAttributeDcl(pk, ak, a, ht, te, sm), + valueEq(qNameId(a), eq, v, sm)); } concrete production shortForwardProductionDecl @@ -50,9 +46,8 @@ top::ProductionStmt ::= fk::'forward' a::Name { forwards to productionStmtAppend( - forwardProductionAttributeDcl(fk, 'production', 'attribute', a, sm, location=top.location), - valueEq(qNameId(a, location=a.location), eq, v, sm, location=v.location), - location=top.location); + forwardProductionAttributeDcl(fk, 'production', 'attribute', a, sm), + valueEq(qNameId(a), eq, v, sm)); } concrete production shortForwardProductionDeclwKwds @@ -61,8 +56,7 @@ top::ProductionStmt ::= fk::'forward' pk::'production' ak::'attribute' { forwards to productionStmtAppend( - forwardProductionAttributeDcl(fk, pk, ak, a, sm, location=top.location), - valueEq(qNameId(a, location=a.location), eq, v, sm, location=v.location), - location=top.location); + forwardProductionAttributeDcl(fk, pk, ak, a, sm), + valueEq(qNameId(a), eq, v, sm)); } diff --git a/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv b/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv index d7c8f1800..9ab8d2a78 100644 --- a/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv +++ b/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv @@ -13,8 +13,8 @@ PatternList ::= l::[Pattern] defaultLoc::Location { return foldr( - \next::Pattern accum::PatternList -> patternList_more(next, ',', accum, location=next.location), - patternList_nil(location=defaultLoc), + \next::Pattern accum::PatternList -> patternList_more(next, ',', accum), + patternList_nil(), l); } @@ -72,11 +72,11 @@ function makeExprsFromExprList Exprs ::= l::[Expr] defaultLoc::Location { return - if null(l) then exprsEmpty(location=defaultLoc) + if null(l) then exprsEmpty() else foldrLastElem( - \leftelem::Expr accum::Exprs -> exprsCons(leftelem,',',accum,location=leftelem.location), - \elem::Expr -> exprsSingle(elem,location=elem.location), + \leftelem::Expr accum::Exprs -> exprsCons(leftelem,',',accum), + \elem::Expr -> exprsSingle(elem), l); } @@ -90,8 +90,8 @@ function makeMRuleListFromListMatchRules MRuleList ::= l::[MatchRule] { return foldrLastElem( - \leftelem::MatchRule accum::MRuleList -> mRuleList_cons(leftelem,'|',accum, location=leftelem.location), - \a::MatchRule -> mRuleList_one(a,location=a.location), + \leftelem::MatchRule accum::MRuleList -> mRuleList_cons(leftelem,'|',accum), + \a::MatchRule -> mRuleList_one(a), l); } @@ -126,7 +126,7 @@ function makeGeneratedNamesFromMatchRule | matchRule_c(patternList_one(prodAppPattern(_,_,pl,_)),_,_) -> pl | matchRuleWhen_c(patternList_one(prodAppPattern(_,_,pl,_)),_,_,_,_) -> pl | matchRuleWhenMatches_c(patternList_one(prodAppPattern(_,_,pl,_)),_,_,_,_,_,_) -> pl - | _ -> patternList_nil(location=loc) + | _ -> patternList_nil() end; return @@ -152,12 +152,12 @@ PatternList ::= mr::MatchRule loc::Location | matchRule_c(patternList_one(prodAppPattern(_,_,pl,_)),_,_) -> pl | matchRuleWhen_c(patternList_one(prodAppPattern(_,_,pl,_)),_,_,_,_) -> pl | matchRuleWhenMatches_c(patternList_one(prodAppPattern(_,_,pl,_)),_,_,_,_,_,_) -> pl - | _ -> patternList_nil(location=loc) + | _ -> patternList_nil() end; return makePatternListFromListofPatterns( map(\pat::Pattern -> - wildcPattern('_', location=loc), + wildcPattern('_'), collectPatternsFromPatternList(patList,[])), loc); } @@ -172,7 +172,7 @@ PatternList ::= mr::MatchRule loc::Location function makeDefinitionLHSFromName DefLHS ::= name::Name loc::Location { - return concreteDefLHS(qNameId(name,location=loc), location=loc); + return concreteDefLHS(qNameId(name)); } @{- @@ -194,10 +194,8 @@ Expr ::= newName::Name aspectLHS::Decorated ConvAspectLHS e::Expr loc::Location '::', aspectLHS.aspectType, '=', - baseExpr(qNameId(aspectLHS.aspectName,location=loc),location=loc), - location=loc), - e, - location=loc); + baseExpr(qNameId(aspectLHS.aspectName))), + e); } @@ -217,7 +215,7 @@ Expr ::= patList::PatternList aspectLHS::Decorated ConvAspectLHS e::Expr loc::Lo | patternList_more(wildcPattern(_),_,_) -> e | patternList_one(varPattern(name)) -> makeLetExprForTopRenaming(name, aspectLHS, e, loc) | patternList_more(varPattern(name),_,_) -> makeLetExprForTopRenaming(name, aspectLHS, e, loc) - | _ -> errorExpr([],location=loc) + | _ -> errorExpr([]) end; } @@ -246,16 +244,14 @@ Pair ::= rules::[MatchRule] aspectLHS::Decorated ConvAspectLHS end; local makeAspectRHSElemListFromNameAndTypeLists::([AspectRHSElem] ::= [Name] [Type]) = - zipWith(aspectRHSElemFull(_, _, location=location), _, _); + zipWith(aspectRHSElemFull, _, _); - local makeAspectRHSFromParamsList::(AspectRHS ::= [AspectRHSElem] ) = foldr( - aspectRHSElemCons(_, _, location=location), - aspectRHSElemNil(location=location), - _); + local makeAspectRHSFromParamsList::(AspectRHS ::= [AspectRHSElem] ) = + foldr(aspectRHSElemCons, aspectRHSElemNil(), _); - local makeQNamesFromNames::([QName] ::= [Name]) = map(qNameId(_, location=location),_); + local makeQNamesFromNames::([QName] ::= [Name]) = map(qNameId,_); - local makeBaseExprFromQNames::([Expr] ::= [QName]) = map(baseExpr(_,location=location),_); + local makeBaseExprFromQNames::([Expr] ::= [QName]) = map(baseExpr,_); -- Transforms it to extract a subpattern and bring it up as the -- main pattern. @@ -264,16 +260,14 @@ Pair ::= rules::[MatchRule] aspectLHS::Decorated ConvAspectLHS | matchRule_c(pl,arrow,e) -> matchRule_c( extractSubPatternListsFromProdPatterns(pl), arrow, - e, - location=location) + eation) | matchRuleWhen_c(pl,whenKWD,cond,arrow,e) -> matchRuleWhen_c( extractSubPatternListsFromProdPatterns(pl), whenKWD, cond, arrow, - e, - location=location) + eation) | matchRuleWhenMatches_c(pl,whenKWD,cond,matches,p,arrow,e) -> matchRuleWhenMatches_c( extractSubPatternListsFromProdPatterns(pl), @@ -282,8 +276,7 @@ Pair ::= rules::[MatchRule] aspectLHS::Decorated ConvAspectLHS matches, p, arrow, - e, - location=location) + eation) end), _); @@ -299,8 +292,7 @@ Pair ::= rules::[MatchRule] aspectLHS::Decorated ConvAspectLHS 'of', terminal(Opt_Vbar_t, "|"), makeMRuleListFromListMatchRules(transformPatternMatchRule(mRules)), - 'end', - location=location); + 'end'); -- This function makes our aspect production from the Expression, QName, and AspectRHS -- We've generated elsewhere. @@ -415,7 +407,7 @@ Pair ::= rules::[MatchRule] aspectLHS::Decorated ConvAspectLHS []) | _ -> ( - emptyAGDcl(location=location), + emptyAGDcl(), [err(location,"Patterns in aspect convenience syntax should be productions,wildcards, or varpatterns only")]) end; } @@ -608,8 +600,8 @@ top::AGDcl ::= attr::QNameAttrOccur aspectLHS::Decorated ConvAspectLHS eqKind::C local combinedAspectProds::[AGDcl] = map(fst(_),groupExtractResults); local combinedAspectDcls::AGDcls = foldr( - consAGDcls(_,_,location=top.location), - nilAGDcls(location=top.location), + consAGDcls(_,_), + nilAGDcls(), combinedAspectProds); diff --git a/grammars/silver/compiler/extension/convenienceaspects/ConcreteSyntax.sv b/grammars/silver/compiler/extension/convenienceaspects/ConcreteSyntax.sv index 395ab92af..bd12bd1c8 100644 --- a/grammars/silver/compiler/extension/convenienceaspects/ConcreteSyntax.sv +++ b/grammars/silver/compiler/extension/convenienceaspects/ConcreteSyntax.sv @@ -9,31 +9,31 @@ synthesized attribute makeAspectEquation::(ProductionStmt ::= DefLHS QNameAttrOc @{- - A nonterminal describing what binding to use on the attribute in the generated aspects. -} -nonterminal ConvenienceAspectEquationKind with location, unparse, pp, makeAspectEquation; +tracked nonterminal ConvenienceAspectEquationKind with unparse, pp, makeAspectEquation; @{- @hide -} concrete productions top::ConvenienceAspectEquationKind | 'using' '=' { - top.makeAspectEquation = attributeDef(_,'.',_,'=',_,';',location=_); + top.makeAspectEquation = attributeDef(_,'.',_,'=',_,';'); top.pp = pp"using ="; top.unparse = "using ="; } | 'using' ':=' { - top.makeAspectEquation = attrContainsBase(_,'.',_,':=',_,';',location=_); + top.makeAspectEquation = attrContainsBase(_,'.',_,':=',_,';'); top.pp = pp"using :="; top.unparse = "using :="; } | 'using' '<-' { - top.makeAspectEquation = attrContainsAppend(_,'.',_,'<-',_,';', location=_); + top.makeAspectEquation = attrContainsAppend(_,'.',_,'<-',_,';'); top.pp = pp"using <-"; top.unparse = "using <-"; } | { - top.makeAspectEquation = attributeDef(_,'.',_,'=',_,';',location=_); + top.makeAspectEquation = attributeDef(_,'.',_,'=',_,';'); top.pp = pp""; top.unparse = ""; } @@ -46,7 +46,7 @@ synthesized attribute aspectType::TypeExpr; @{- - Nonterminal for the name and type of the term for which you're constructing aspect productions for. -} -nonterminal ConvAspectLHS with aspectName, aspectType, unparse; +tracked nonterminal ConvAspectLHS with aspectName, aspectType, unparse; @{- @hide -} concrete productions top::ConvAspectLHS | name::Name '::' ty::TypeExpr @@ -58,7 +58,7 @@ concrete productions top::ConvAspectLHS | ty::TypeExpr { top.aspectType = ty; - top.aspectName = name("__generatedTop_" ++ toString(genInt()), ty.location); + top.aspectName = name("__generatedTop_" ++ toString(genInt())); top.unparse = ty.unparse; } @@ -75,5 +75,5 @@ concrete productions top::ConvAspectLHS concrete production convenienceAspects_c top::AGDcl ::= 'aspect' attr::QNameAttrOccur 'on' aspectLHS::ConvAspectLHS eqKind::ConvenienceAspectEquationKind 'of' Opt_Vbar_t ml::MRuleList 'end' ';' { - forwards to convenienceAspects(attr, aspectLHS, eqKind, ml, location=top.location); + forwards to convenienceAspects(attr, aspectLHS, eqKind, ml); } diff --git a/grammars/silver/compiler/extension/data/DataDcl.sv b/grammars/silver/compiler/extension/data/DataDcl.sv index 21b8ed9c1..3962f4ba8 100644 --- a/grammars/silver/compiler/extension/data/DataDcl.sv +++ b/grammars/silver/compiler/extension/data/DataDcl.sv @@ -8,11 +8,9 @@ top::AGDcl ::= 'data' id::Name tl::BracketedOptTypeExprs '=' ctors::DataConstruc ctors.ntTypeArgs = tl; forwards to appendAGDcl( nonterminalDcl( - dataNTQualifier($1, nilNTQualifier(location=top.location), location=top.location), - 'nonterminal', id, tl, nonterminalModifiersNone(location=top.location), ';', - location=top.location), - ctors.ctorDcls, - location=top.location); + dataNTQualifier($1, nilNTQualifier()), + 'nonterminal', id, tl, nonterminalModifiersNone(), ';'), + ctors.ctorDcls); } concrete production dataDclWith @@ -23,11 +21,9 @@ top::AGDcl ::= 'data' id::Name tl::BracketedOptTypeExprs '=' ctors::DataConstruc ctors.ntTypeArgs = tl; forwards to appendAGDcl( nonterminalWithDcl( - dataNTQualifier($1, nilNTQualifier(location=top.location), location=top.location), - 'nonterminal', id, tl, nonterminalModifiersNone(location=top.location), 'with', attrs, ';', - location=top.location), - ctors.ctorDcls, - location=top.location); + dataNTQualifier($1, nilNTQualifier()), + 'nonterminal', id, tl, nonterminalModifiersNone(), 'with', attrs, ';'), + ctors.ctorDcls); } synthesized attribute ctorDcls::AGDcl; @@ -36,14 +32,14 @@ inherited attribute ntTypeArgs::BracketedOptTypeExprs; terminal DataConstructorOr_t '|' lexer classes {SPECOP}; -nonterminal DataConstructors with location, unparse, grammarName, config, ctorDcls, ntName, ntTypeArgs; +tracked nonterminal DataConstructors with unparse, grammarName, config, ctorDcls, ntName, ntTypeArgs; propagate grammarName, config, ntName, ntTypeArgs on DataConstructors; concrete production consDataConstructor top::DataConstructors ::= h::DataConstructor '|' t::DataConstructors { top.unparse = s"${h.unparse} | ${t.unparse}"; - top.ctorDcls = appendAGDcl(h.ctorDcls, t.ctorDcls, location=top.location); + top.ctorDcls = appendAGDcl(h.ctorDcls, t.ctorDcls); } concrete production oneDataConstructor @@ -57,10 +53,10 @@ concrete production nilDataConstructor top::DataConstructors ::= { top.unparse = ""; - top.ctorDcls = emptyAGDcl(location=top.location); + top.ctorDcls = emptyAGDcl(); } -nonterminal DataConstructor with location, unparse, grammarName, config, ctorDcls, ntName, ntTypeArgs; +tracked nonterminal DataConstructor with unparse, grammarName, config, ctorDcls, ntName, ntTypeArgs; propagate grammarName, config on DataConstructor; concrete production dataConstructor @@ -69,12 +65,11 @@ top::DataConstructor ::= id::Name rhs::ProductionRHS top.unparse = s"${id.unparse} ${rhs.unparse}"; local ntBaseType::TypeExpr = nominalTypeExpr( - qNameTypeId(terminal(IdUpper_t, top.ntName, top.location), location=top.location), - location=top.location); + qNameTypeId(terminal(IdUpper_t, top.ntName, top.location))); local ntType::TypeExpr = case top.ntTypeArgs of | botlNone() -> ntBaseType - | botlSome(btl) -> appTypeExpr(ntBaseType, btl, location=top.location) + | botlSome(btl) -> appTypeExpr(ntBaseType, btl) end; top.ctorDcls = Silver_AGDcl { abstract production $Name{id} diff --git a/grammars/silver/compiler/extension/deprecation/BuildWith.sv b/grammars/silver/compiler/extension/deprecation/BuildWith.sv index 361aeadd3..26c6046e8 100644 --- a/grammars/silver/compiler/extension/deprecation/BuildWith.sv +++ b/grammars/silver/compiler/extension/deprecation/BuildWith.sv @@ -5,8 +5,8 @@ terminal Build_kwd 'build' lexer classes {MODSTMT}; concrete production buildsStmt top::ModuleStmt ::= 'build' m::QName 'with' c::QName ';' { - top.errors <- [wrn(top.location, "Conditional export using old-style 'build ... with' rather than 'exports ... with'")]; + top.errors <- [wrnFromOrigin(top, "Conditional export using old-style 'build ... with' rather than 'exports ... with'")]; - forwards to exportsWithStmt('exports', m, $3, c, $5, location=top.location); + forwards to exportsWithStmt('exports', m, $3, c, $5); } diff --git a/grammars/silver/compiler/extension/deprecation/Deprecation.sv b/grammars/silver/compiler/extension/deprecation/Deprecation.sv index 0701d2ec4..102f45844 100644 --- a/grammars/silver/compiler/extension/deprecation/Deprecation.sv +++ b/grammars/silver/compiler/extension/deprecation/Deprecation.sv @@ -13,8 +13,8 @@ top::AGDcl ::= 'deprecated' s::String_t ';' { top.unparse = "deprecated" ++ s.lexeme ++ ";"; - top.errors := [wrn(top.location, s.lexeme)]; + top.errors := [wrnFromOrigin(top, s.lexeme)]; - forwards to emptyAGDcl(location=top.location); + forwards to emptyAGDcl(); } diff --git a/grammars/silver/compiler/extension/deprecation/NameTicks.sv b/grammars/silver/compiler/extension/deprecation/NameTicks.sv index 4c8065b24..a7c5766a1 100644 --- a/grammars/silver/compiler/extension/deprecation/NameTicks.sv +++ b/grammars/silver/compiler/extension/deprecation/NameTicks.sv @@ -8,22 +8,22 @@ top::Expr ::= q::NameTick { top.unparse = q.unparse; - top.errors <- [wrn(top.location, "Tick suffixes no longer do ANYTHING. Remove it!")]; + top.errors <- [wrnFromOrigin(top, "Tick suffixes no longer do ANYTHING. Remove it!")]; - forwards to baseExpr(qName(q.location, q.name), location=q.location); + forwards to baseExpr(qName(q.name)); } concrete production concreteDontDecorateExpr top::Expr ::= q::NameTickTick { top.unparse = q.unparse; - top.errors <- [wrn(top.location, "Double tick suffixes no longer do ANYTHING. Remove it!")]; + top.errors <- [wrnFromOrigin(top, "Double tick suffixes no longer do ANYTHING. Remove it!")]; - forwards to baseExpr(qName(q.location, q.name), location=q.location); + forwards to baseExpr(qName(q.name)); } -nonterminal NameTick with config, grammarName, location, unparse, name; -nonterminal NameTickTick with config, grammarName, location, unparse, name; +tracked nonterminal NameTick with config, grammarName, unparse, name; +tracked nonterminal NameTickTick with config, grammarName, unparse, name; concrete production nameIdTick top::NameTick ::= id::IdTick_t diff --git a/grammars/silver/compiler/extension/deprecation/ProductionSemi.sv b/grammars/silver/compiler/extension/deprecation/ProductionSemi.sv index b6fdc8eef..6f458909c 100644 --- a/grammars/silver/compiler/extension/deprecation/ProductionSemi.sv +++ b/grammars/silver/compiler/extension/deprecation/ProductionSemi.sv @@ -5,9 +5,9 @@ top::ProductionBody ::= ';' { top.unparse = ";"; - top.errors <- [wrn(top.location, "Terminating a production declaration with a semicolon is deprecated. Use {}.")]; + top.errors <- [wrnFromOrigin(top, "Terminating a production declaration with a semicolon is deprecated. Use {}.")]; - forwards to productionBody('{', productionStmtsNil(location=top.location), '}', location=top.location); + forwards to productionBody('{', productionStmtsNil(), '}'); } diff --git a/grammars/silver/compiler/extension/deriving/Derive.sv b/grammars/silver/compiler/extension/deriving/Derive.sv index 5075a93fe..46d04343b 100644 --- a/grammars/silver/compiler/extension/deriving/Derive.sv +++ b/grammars/silver/compiler/extension/deriving/Derive.sv @@ -9,7 +9,7 @@ top::AGDcl ::= 'derive' tcs::NameList 'on' nts::NameList ';' { top.unparse = s"derive ${tcs.unparse} on ${nts.unparse};"; - forwards to deriveTCsOnNTListDcl(tcs, nts, location=top.location); + forwards to deriveTCsOnNTListDcl(tcs, nts); } production deriveTCsOnNTListDcl @@ -19,12 +19,11 @@ top::AGDcl ::= tcs::NameList nts::NameList forwards to case nts of - | nameListOne(n) -> deriveTCsOnOneNTDcl(tcs, n, location=n.location) + | nameListOne(n) -> deriveTCsOnOneNTDcl(tcs, n) | nameListCons(n, _, rest) -> appendAGDcl( - deriveTCsOnOneNTDcl(tcs, n, location=n.location), - deriveTCsOnNTListDcl(tcs, rest, location=top.location), - location=top.location) + deriveTCsOnOneNTDcl(tcs, n), + deriveTCsOnNTListDcl(tcs, rest)) end; } @@ -35,12 +34,11 @@ top::AGDcl ::= tcs::NameList nt::QName forwards to case tcs of - | nameListOne(tc) -> deriveDcl(tc, nt, location=top.location) + | nameListOne(tc) -> deriveDcl(tc, nt) | nameListCons(tc, _, rest) -> appendAGDcl( - deriveDcl(tc, nt, location=top.location), - deriveTCsOnOneNTDcl(rest, nt, location=top.location), - location=top.location) + deriveDcl(tc, nt), + deriveTCsOnOneNTDcl(rest, nt)) end; } @@ -54,29 +52,29 @@ top::AGDcl ::= tc::QName nt::QName local localErrors::[Message] = tc.lookupType.errors ++ nt.lookupType.errors ++ (if tc.lookupType.found && !tc.lookupType.dcl.isClass - then [err(tc.location, s"${tc.lookupType.fullName} is not a type class")] + then [errFromOrigin(tc, s"${tc.lookupType.fullName} is not a type class")] else []) ++ (if nt.lookupType.found && !(nt.lookupType.dcl.isType && nt.lookupType.typeScheme.isNonterminal) - then [err(nt.location, s"${nt.lookupType.fullName} is not a nonterminal")] + then [errFromOrigin(nt, s"${nt.lookupType.fullName} is not a nonterminal")] else []) ++ (if nt.lookupType.found && nt.lookupType.dcl.isClosed - then [err(nt.location, s"Cannot derive instances for ${nt.lookupType.fullName}, since that nonterminal is closed")] + then [errFromOrigin(nt, s"Cannot derive instances for ${nt.lookupType.fullName}, since that nonterminal is closed")] else []); top.errors := if null(localErrors) then forward.errors else localErrors; forwards to -- TODO: Yuck, can't forward based on env here since we need the defs from the forward. case if startsWith("silver:core:", tc.name) then tc.name else "silver:core:" ++ tc.name of -- tc.lookupType.fullName - | "silver:core:Eq" -> deriveEqDcl(nt, location=top.location) - | "silver:core:Ord" -> deriveOrdDcl(nt, location=top.location) - | fn -> errorAGDcl([err(tc.location, s"Cannot derive type class ${fn}")], location=top.location) + | "silver:core:Eq" -> deriveEqDcl(nt) + | "silver:core:Ord" -> deriveOrdDcl(nt) + | fn -> errorAGDcl([errFromOrigin(tc, s"Cannot derive type class ${fn}")]) end; } production deriveEqDcl top::AGDcl ::= nt::Decorated! QName { - undecorates to deriveDcl(qName(top.location, "silver:core:Eq"), nt, location=top.location); + undecorates to deriveDcl(qName("silver:core:Eq"), nt); top.unparse = s"derive silver:core:Eq on ${nt.unparse};"; top.moduleNames := []; @@ -90,108 +88,97 @@ top::AGDcl ::= nt::Decorated! QName forwards to Silver_AGDcl { instance $ConstraintList{ foldr( - consConstraint(_, ',', _, location=top.location), - nilConstraint(location=top.location), + consConstraint(_, ',', _), + nilConstraint(), filterMap( \ tv::TyVar -> if tv.kindrep == starKind() then just( classConstraint( - qName(top.location, "silver:core:Eq").qNameType, - typerepTypeExpr(skolemType(tv), location=top.location), - location=top.location)) + qName("silver:core:Eq").qNameType, + typerepTypeExpr(skolemType(tv)))) else nothing(), - tvs))} => silver:core:Eq $TypeExpr{typerepTypeExpr(ntty, location=top.location)} { - eq = \ x::$TypeExpr{typerepTypeExpr(ntty, location=top.location)} y::$TypeExpr{typerepTypeExpr(ntty, location=top.location)} -> $Expr{ + tvs))} => silver:core:Eq $TypeExpr{typerepTypeExpr(ntty)} { + eq = \ x::$TypeExpr{typerepTypeExpr(ntty)} y::$TypeExpr{typerepTypeExpr(ntty)} -> $Expr{ if null(includedProds) then Silver_Expr {true} else foldr( - and(_, '&&', _, location=top.location), + and(_, '&&', _), matchPrimitive( Silver_Expr {x}, Silver_TypeExpr {Boolean}, foldPrimPatterns( map( \ prod::ValueDclInfo -> - prodPattern(qName(top.location, prod.fullName), '(', + prodPattern(qName(prod.fullName), '(', foldr( - consVarBinder(_, ',', _, location=top.location), - nilVarBinder(location=top.location), + consVarBinder(_, ',', _), + nilVarBinder(), map(\ i::Integer -> - varVarBinder(name(s"a${toString(i)}", top.location), location=top.location), + varVarBinder(name(s"a${toString(i)}", top.location)), range(0, length(prod.namedSignature.inputElements)))), ')', '->', matchPrimitive( Silver_Expr {y}, Silver_TypeExpr {Boolean}, onePattern( - prodPattern(qName(top.location, prod.fullName), '(', + prodPattern(qName(prod.fullName), '(', foldr( - consVarBinder(_, ',', _, location=top.location), - nilVarBinder(location=top.location), + consVarBinder(_, ',', _), + nilVarBinder(), map(\ i::Integer -> - varVarBinder(name(s"b${toString(i)}", top.location), location=top.location), + varVarBinder(name(s"b${toString(i)}", top.location)), range(0, length(prod.namedSignature.inputElements)))), ')', '->', foldr( - and(_, '&&', _, location=top.location), + and(_, '&&', _), Silver_Expr {true}, map( \ i::Integer -> Silver_Expr { $name{s"a${toString(i)}"} == $name{s"b${toString(i)}"} }, - range(0, length(prod.namedSignature.inputElements)))), - location=top.location), - location=top.location), - Silver_Expr {false}, - location=top.location), - location=top.location), + range(0, length(prod.namedSignature.inputElements)))))), + Silver_Expr {false})), includedProds), top.location), - Silver_Expr {silver:core:error("Unexpected production in derived Eq instance!")}, - location=top.location), + Silver_Expr {silver:core:error("Unexpected production in derived Eq instance!")}), map( \ anno::NamedSignatureElement -> Silver_Expr { x.$name{anno.elementName} == y.$name{anno.elementName} }, annotationsForNonterminal(ntty, top.env)))}; - neq = \ x::$TypeExpr{typerepTypeExpr(ntty, location=top.location)} y::$TypeExpr{typerepTypeExpr(ntty, location=top.location)} -> $Expr{ + neq = \ x::$TypeExpr{typerepTypeExpr(ntty)} y::$TypeExpr{typerepTypeExpr(ntty)} -> $Expr{ if null(includedProds) then Silver_Expr {false} else foldr( - or(_, '||', _, location=top.location), + or(_, '||', _), matchPrimitive( Silver_Expr {x}, Silver_TypeExpr {Boolean}, foldPrimPatterns( map( \ prod::ValueDclInfo -> - prodPattern(qName(top.location, prod.fullName), '(', + prodPattern(qName(prod.fullName), '(', foldr( - consVarBinder(_, ',', _, location=top.location), - nilVarBinder(location=top.location), + consVarBinder(_, ',', _), + nilVarBinder(), map(\ i::Integer -> - varVarBinder(name(s"a${toString(i)}", top.location), location=top.location), + varVarBinder(name(s"a${toString(i)}", top.location)), range(0, length(prod.namedSignature.inputElements)))), ')', '->', matchPrimitive( Silver_Expr {y}, Silver_TypeExpr {Boolean}, onePattern( - prodPattern(qName(top.location, prod.fullName), '(', + prodPattern(qName(prod.fullName), '(', foldr( - consVarBinder(_, ',', _, location=top.location), - nilVarBinder(location=top.location), + consVarBinder(_, ',', _), + nilVarBinder(), map(\ i::Integer -> - varVarBinder(name(s"b${toString(i)}", top.location), location=top.location), + varVarBinder(name(s"b${toString(i)}", top.location)), range(0, length(prod.namedSignature.inputElements)))), ')', '->', foldr( - or(_, '||', _, location=top.location), + or(_, '||', _), Silver_Expr {false}, map( \ i::Integer -> Silver_Expr { $name{s"a${toString(i)}"} != $name{s"b${toString(i)}"} }, - range(0, length(prod.namedSignature.inputElements)))), - location=top.location), - location=top.location), - Silver_Expr {true}, - location=top.location), - location=top.location), + range(0, length(prod.namedSignature.inputElements)))))), + Silver_Expr {true})), includedProds), top.location), - Silver_Expr {silver:core:error("Unexpected production in derived Eq instance!")}, - location=top.location), + Silver_Expr {silver:core:error("Unexpected production in derived Eq instance!")}), map( \ anno::NamedSignatureElement -> Silver_Expr { x.$name{anno.elementName} != y.$name{anno.elementName} }, @@ -203,7 +190,7 @@ top::AGDcl ::= nt::Decorated! QName production deriveOrdDcl top::AGDcl ::= nt::Decorated! QName { - undecorates to deriveDcl(qName(top.location, "silver:core:Ord"), nt, location=top.location); + undecorates to deriveDcl(qName("silver:core:Ord"), nt); top.unparse = s"derive silver:core:Ord on ${nt.unparse};"; top.moduleNames := []; @@ -218,19 +205,18 @@ top::AGDcl ::= nt::Decorated! QName forwards to Silver_AGDcl { instance $ConstraintList{ foldr( - consConstraint(_, ',', _, location=top.location), - nilConstraint(location=top.location), + consConstraint(_, ',', _), + nilConstraint(), filterMap( \ tv::TyVar -> if tv.kindrep == starKind() then just( classConstraint( - qName(top.location, "silver:core:Ord").qNameType, - typerepTypeExpr(skolemType(tv), location=top.location), - location=top.location)) + qName("silver:core:Ord").qNameType, + typerepTypeExpr(skolemType(tv)))) else nothing(), - tvs))} => silver:core:Ord $TypeExpr{typerepTypeExpr(ntty, location=top.location)} { - compare = \ x::$TypeExpr{typerepTypeExpr(ntty, location=top.location)} y::$TypeExpr{typerepTypeExpr(ntty, location=top.location)} -> $Expr{ + tvs))} => silver:core:Ord $TypeExpr{typerepTypeExpr(ntty)} { + compare = \ x::$TypeExpr{typerepTypeExpr(ntty)} y::$TypeExpr{typerepTypeExpr(ntty)} -> $Expr{ if null(includedProds) then Silver_Expr { 0 } else foldr( \ e1::Expr e2::Expr -> @@ -241,12 +227,12 @@ top::AGDcl ::= nt::Decorated! QName foldPrimPatterns( map( \ prod::ValueDclInfo -> - prodPattern(qName(top.location, prod.fullName), '(', + prodPattern(qName(prod.fullName), '(', foldr( - consVarBinder(_, ',', _, location=top.location), - nilVarBinder(location=top.location), + consVarBinder(_, ',', _), + nilVarBinder(), map(\ i::Integer -> - varVarBinder(name(s"a${toString(i)}", top.location), location=top.location), + varVarBinder(name(s"a${toString(i)}", top.location)), range(0, length(prod.namedSignature.inputElements)))), ')', '->', matchPrimitive( Silver_Expr {y}, @@ -255,15 +241,15 @@ top::AGDcl ::= nt::Decorated! QName map( \ prod2::ValueDclInfo -> prodPattern( - qName(top.location, prod2.fullName), '(', + qName(prod2.fullName), '(', foldr( - consVarBinder(_, ',', _, location=top.location), - nilVarBinder(location=top.location), + consVarBinder(_, ',', _), + nilVarBinder(), map( \ i::Integer -> if prod.fullName == prod2.fullName - then varVarBinder(name(s"b${toString(i)}", top.location), location=top.location) - else ignoreVarBinder('_', location=top.location), + then varVarBinder(name(s"b${toString(i)}", top.location)) + else ignoreVarBinder('_'), range(0, length(prod2.namedSignature.inputElements)))), ')', '->', if prod.fullName < prod2.fullName then Silver_Expr { -1 } @@ -276,17 +262,13 @@ top::AGDcl ::= nt::Decorated! QName Silver_Expr { let res::Integer = $Expr{e1} in if res == 0 then $Expr{e2} else res end }, map( \ i::Integer -> Silver_Expr { silver:core:compare($name{s"a${toString(i)}"}, $name{s"b${toString(i)}"}) }, - range(0, length(prod2.namedSignature.inputElements)))), - location=top.location), + range(0, length(prod2.namedSignature.inputElements))))), includedProds), top.location), - Silver_Expr {silver:core:error("Unexpected production in derived Ord instance!")}, - location=top.location), - location=top.location), + Silver_Expr {silver:core:error("Unexpected production in derived Ord instance!")})), includedProds), top.location), - Silver_Expr {silver:core:error("Unexpected production in derived Ord instance!")}, - location=top.location), + Silver_Expr {silver:core:error("Unexpected production in derived Ord instance!")}), map( \ anno::NamedSignatureElement -> Silver_Expr { silver:core:compare(x.$name{anno.elementName}, y.$name{anno.elementName}) }, @@ -300,8 +282,8 @@ PrimPatterns ::= ps::[PrimPattern] loc::Location { return case ps of - | [h] -> onePattern(h, location=loc) - | h :: t -> consPattern(h, '|', foldPrimPatterns(t, loc), location=loc) + | [h] -> onePattern(h) + | h :: t -> consPattern(h, '|', foldPrimPatterns(t, loc)) | [] -> error("empty patterns") end; } diff --git a/grammars/silver/compiler/extension/do_notation/Syntax.sv b/grammars/silver/compiler/extension/do_notation/Syntax.sv index 1f9ef45c7..2b24e9a7b 100644 --- a/grammars/silver/compiler/extension/do_notation/Syntax.sv +++ b/grammars/silver/compiler/extension/do_notation/Syntax.sv @@ -48,7 +48,7 @@ top::Expr ::= 'mdo' '{' body::DoBody '}' body.recVars = mempty; body.recRes = error("First binding cannot have unbound vars"); - forwards to do_c('do', '{', body.mdoTransform, '}', location=top.location); + forwards to do_c('do', '{', body.mdoTransform, '}'); } -- The set of variables that have been bound within this do body so far @@ -87,13 +87,13 @@ synthesized attribute recBody::DoBody; -- A transformation on a do body, wrapping segments in mfix synthesized attribute mdoTransform::DoBody; -nonterminal DoBody with - location, unparse, frame, boundVarEnv, allBoundVars, boundVars, bindingFreeVars, +tracked nonterminal DoBody with + unparse, frame, boundVarEnv, allBoundVars, boundVars, bindingFreeVars, isApplicative, appBindings, appExprs, appResult, transform, recVars, recBindings, recRes, recBody, mdoTransform; -nonterminal DoBinding with - location, unparse, frame, boundVars, freeVars, +tracked nonterminal DoBinding with + unparse, frame, boundVars, freeVars, isApplicative, appBindings, appExprs, transform, transformIn, recBindings; @@ -126,8 +126,8 @@ top::DoBody ::= b::DoBinding rest::DoBody foldr( \ el::ProductionRHSElem trans::Expr -> lambdap( - productionRHSCons(el, productionRHSNil(location=top.location), location=top.location), - trans, location=top.location), + productionRHSCons(el, productionRHSNil()), + trans), top.appResult, top.appBindings), head(top.appExprs)]), tail(top.appExprs)) @@ -151,14 +151,13 @@ top::DoBody ::= b::DoBinding rest::DoBody foldr1( \ e1::Expr e2::Expr -> Silver_Expr { silver:core:pair(fst=$Expr{e1}, snd=$Expr{e2}) }, map(\ item::(String, TypeExpr) -> Silver_Expr { $name{item.1} }, top.recBindings)), - ';', location=top.location) + ';') else top.recRes; top.recBody = consDoBody(b, if ts:isEmpty(rest.recVars) then rest.recRes - else rest.recBody, - location=top.location); + else rest.recBody); local recVarName::String = s"_rec_items_${toString(genInt())}"; local recVarType::TypeExpr = @@ -168,14 +167,13 @@ top::DoBody ::= b::DoBinding rest::DoBody map(snd, top.recBindings)); local wrapUnpackRecBindings::(DoBody ::= DoBody) = foldr( - consDoBody(_, _, location=top.location), + consDoBody(_, _), _, zipWith( \ i::Integer item::(String, TypeExpr) -> letDoBinding( 'let', name(item.1, top.location), '::', item.2, '=', - select(Silver_Expr { $name{recVarName} }, 1, i + 1, length(top.recBindings), location=top.location), ';', - location=top.location), + select(Silver_Expr { $name{recVarName} }, 1, i + 1, length(top.recBindings)), ';'), range(0, length(top.recBindings)), top.recBindings)); top.mdoTransform = @@ -189,13 +187,11 @@ top::DoBody ::= b::DoBinding rest::DoBody mfix( \ $name{recVarName}::$TypeExpr{recVarType} -> $Expr{ - do_c('do', '{', wrapUnpackRecBindings(top.recBody), '}', location=top.location) + do_c('do', '{', wrapUnpackRecBindings(top.recBody), '}') }) - }, ';', - location=top.location), - wrapUnpackRecBindings(rest.mdoTransform), - location=top.location) - else consDoBody(b, rest.mdoTransform, location=top.location); + }, ';'), + wrapUnpackRecBindings(rest.mdoTransform)) + else consDoBody(b, rest.mdoTransform); } concrete production finalExprDoBody @@ -234,17 +230,15 @@ top::DoBinding ::= n::Name DoDoubleColon_t t::TypeExpr '<-' e::Expr ';' top.unparse = s"${n.unparse}::${t.unparse} <- ${e.unparse};"; top.boundVars <- ts:fromList([n.name]); top.isApplicative = true; - top.appBindings = [productionRHSElem(n, terminal(ColonColon_t, "::"), t, location=top.location)]; + top.appBindings = [productionRHSElem(n, terminal(ColonColon_t, "::"), t)]; top.appExprs = [e]; local cont :: Expr = lambdap( productionRHSCons( - productionRHSElem(n, terminal(ColonColon_t, "::"), t, location=top.location), - productionRHSNil(location=top.location), - location=top.location), - top.transformIn, - location=top.location); + productionRHSElem(n, terminal(ColonColon_t, "::"), t), + productionRHSNil()), + top.transformIn); top.transform = mkStrFunctionInvocation(top.location, "silver:core:bind", [e, cont]); top.recBindings = [(n.name, t)]; @@ -256,7 +250,7 @@ top::DoBinding ::= e::Expr ';' top.unparse = s"${e.unparse};"; top.isApplicative = true; top.appBindings = - [productionRHSElemType(typerepTypeExpr(freshType(), location=top.location), location=top.location)]; + [productionRHSElemType(typerepTypeExpr(freshType()))]; top.appExprs = [e]; top.transform = mkStrFunctionInvocation(top.location, "silver:core:applySecond", [e, top.transformIn]); @@ -274,9 +268,8 @@ top::DoBinding ::= 'let' n::Name '::' t::TypeExpr '=' e::Expr ';' top.transform = letp( - assignExpr(n, terminal(ColonColon_t, "::"), t, '=', e, location=top.location), - top.transformIn, - location=top.location); + assignExpr(n, terminal(ColonColon_t, "::"), t, '=', e), + top.transformIn); top.recBindings = [(n.name, t)]; } diff --git a/grammars/silver/compiler/extension/doc/core/CommentItem.sv b/grammars/silver/compiler/extension/doc/core/CommentItem.sv index b5c2914b4..bcecc6b61 100644 --- a/grammars/silver/compiler/extension/doc/core/CommentItem.sv +++ b/grammars/silver/compiler/extension/doc/core/CommentItem.sv @@ -5,7 +5,7 @@ synthesized attribute loc :: Location; synthesized attribute stub :: Boolean; synthesized attribute docNames :: [String]; synthesized attribute undocNames :: [String]; -nonterminal CommentItem with body, loc, doEmit, stub, docNames, undocNames; +tracked nonterminal CommentItem with body, loc, doEmit, stub, docNames, undocNames; {- Used by other productions to construct diff --git a/grammars/silver/compiler/extension/doc/core/DataDcl.sv b/grammars/silver/compiler/extension/doc/core/DataDcl.sv index 3d83fad3e..9330b5d72 100644 --- a/grammars/silver/compiler/extension/doc/core/DataDcl.sv +++ b/grammars/silver/compiler/extension/doc/core/DataDcl.sv @@ -36,14 +36,12 @@ top::DataConstructors ::= h::DataConstructor comment::DocComment_t '|' t::DataCo | consDataConstructor(h1, _, t1) -> consDataConstructor( h, '|', - consDataConstructor(documentedConstructor(comment, h1, location=h1.location), '|', t1, location=t.location), - location=top.location) + consDataConstructor(documentedConstructor(comment, h1), '|', t1)) | oneDataConstructor(h1) -> consDataConstructor( h, '|', - oneDataConstructor(documentedConstructor(comment, h1, location=h1.location), location=t.location), - location=top.location) - | nilDataConstructor() -> consDataConstructor(h, '|', t, location=top.location) + oneDataConstructor(documentedConstructor(comment, h1))) + | nilDataConstructor() -> consDataConstructor(h, '|', t) end; } @@ -69,7 +67,7 @@ top::DataConstructor ::= comment::DocComment_t item::DataConstructor else [dclCommentItem(top.docForName, forward.docUnparse, forward.grammarName, item.location, parsed)]; top.docErrors <- if isDoubleComment - then [wrn(parsed.location, "Doc comment not immediately preceding constructor, so association is ambiguous. Treating as standalone comment. Mark with @@{- instead of @{- to silence this warning.")] + then [wrnFromOrigin(parsed, "Doc comment not immediately preceding constructor, so association is ambiguous. Treating as standalone comment. Mark with @@{- instead of @{- to silence this warning.")] else []; forwards to item; diff --git a/grammars/silver/compiler/extension/doc/core/DocConfig.sv b/grammars/silver/compiler/extension/doc/core/DocConfig.sv index cf1b052f4..ca1e59d07 100644 --- a/grammars/silver/compiler/extension/doc/core/DocConfig.sv +++ b/grammars/silver/compiler/extension/doc/core/DocConfig.sv @@ -4,67 +4,34 @@ grammar silver:compiler:extension:doc:core; - Represents a single setting (key = value) of a doc configuration option. - Some are file-scope, and some are grammar-scope (see @link[fileScope].) -} -nonterminal DocConfigSetting; +data DocConfigSetting + = splitConfig v::Boolean + | fileSplitConfig v::Boolean + | weightConfig v::Integer + | grammarWeightConfig v::Integer + | grammarTitleConfig v::String + | titleConfig v::String + | grammarNoDocsConfig v::Boolean + | fileNoDocsConfig v::Boolean + | tocConfig v::Boolean + ; @{- - Is this @link[DocConfigSetting] local to the file (e.g. @@title) or to the - grammar (e.g. @@grammarTitle)? -} synthesized attribute fileScope::Boolean occurs on DocConfigSetting; - -abstract production splitConfig -top::DocConfigSetting ::= v::Boolean -{ - top.fileScope = false; -} - -abstract production fileSplitConfig -top::DocConfigSetting ::= v::Boolean -{ - top.fileScope = true; -} - -abstract production weightConfig -top::DocConfigSetting ::= v::Integer -{ - top.fileScope = true; -} - -abstract production grammarWeightConfig -top::DocConfigSetting ::= v::Integer -{ - top.fileScope = false; -} - -abstract production grammarTitleConfig -top::DocConfigSetting ::= v::String -{ - top.fileScope = false; -} - -abstract production titleConfig -top::DocConfigSetting ::= v::String -{ - top.fileScope = true; -} - -abstract production grammarNoDocsConfig -top::DocConfigSetting ::= v::Boolean -{ - top.fileScope = false; -} - -abstract production fileNoDocsConfig -top::DocConfigSetting ::= v::Boolean -{ - top.fileScope = true; -} - -abstract production tocConfig -top::DocConfigSetting ::= v::Boolean -{ - top.fileScope = true; -} +aspect fileScope on DocConfigSetting of +| splitConfig(_) -> true +| fileSplitConfig(_) -> true +| weightConfig(_) -> true +| grammarWeightConfig(_) -> false +| grammarTitleConfig(_) -> false +| titleConfig(_) -> true +| grammarNoDocsConfig(_) -> false +| fileNoDocsConfig(_) -> true +| tocConfig(_) -> true +end; -- a grammar with @excludeGrammar containing file(s) with @excludeFile false will diff --git a/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv b/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv index ddab5fb3f..e72419405 100644 --- a/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv +++ b/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv @@ -18,7 +18,7 @@ DclComment ::= conf::Decorated CmdArgs body::DocComment_t { local docCommentContent::String = body.lexeme; local parsed::ParseResult = parseDocComment(docCommentContent, body.location.filename); - local comment::DclComment = if parsed.parseSuccess then parsed.parseTree else errorDclComment(docCommentContent, parsed.parseError, location=body.location); + local comment::DclComment = if parsed.parseSuccess then parsed.parseTree else errorDclComment(docCommentContent, parsed.parseError); return if conf.parseDocs then comment else theEmptyDclComment; } @@ -80,7 +80,7 @@ top::AGDcl ::= comment::DocComment_t dcl::AGDcl else [dclCommentItem(forward.docForName, forward.docUnparse, forward.grammarName, dcl.location, parsed)] ++ if length(forward.docs) > 1 then tail(forward.docs) else []; top.errors <- if isDoubleComment - then [wrn(parsed.location, "Doc comment not immediately preceding AGDcl, so association is ambiguous. Treating as standalone comment. Mark with @@{- instead of @{- to silence this warning.")] + then [wrnFromOrigin(parsed, "Doc comment not immediately preceding AGDcl, so association is ambiguous. Treating as standalone comment. Mark with @@{- instead of @{- to silence this warning.")] else []; forwards to dcl; @@ -109,5 +109,5 @@ layout {} top.docs := [standaloneDclCommentItem(parsed)]; top.unparse = ""; - forwards to emptyAGDcl(location=top.location); + forwards to emptyAGDcl(); } diff --git a/grammars/silver/compiler/extension/doc/core/TypeClassDcls.sv b/grammars/silver/compiler/extension/doc/core/TypeClassDcls.sv index 8ac29a559..8a2a92de0 100644 --- a/grammars/silver/compiler/extension/doc/core/TypeClassDcls.sv +++ b/grammars/silver/compiler/extension/doc/core/TypeClassDcls.sv @@ -81,7 +81,7 @@ top::ClassBodyItem ::= comment::DocComment_t item::ClassBodyItem else [dclCommentItem(top.scopeName ++ "." ++ forward.docForName, forward.docUnparse, forward.grammarName, item.location, parsed)]; top.docErrors <- if isDoubleComment - then [wrn(parsed.location, "Doc comment not immediately preceding ClassBodyItem, so association is ambiguous. Treating as standalone comment. Mark with @@{- instead of @{- to silence this warning.")] + then [wrnFromOrigin(parsed, "Doc comment not immediately preceding ClassBodyItem, so association is ambiguous. Treating as standalone comment. Mark with @@{- instead of @{- to silence this warning.")] else []; forwards to item; @@ -158,7 +158,7 @@ top::InstanceBodyItem ::= comment::DocComment_t item::InstanceBodyItem else [dclCommentItem(top.scopeName ++ "." ++ forward.docForName, forward.docUnparse, forward.grammarName, item.location, parsed)]; top.docErrors <- if isDoubleComment - then [wrn(parsed.location, "Doc comment not immediately preceding InstanceBodyItem, so association is ambiguous. Treating as standalone comment. Mark with @@{- instead of @{- to silence this warning.")] + then [wrnFromOrigin(parsed, "Doc comment not immediately preceding InstanceBodyItem, so association is ambiguous. Treating as standalone comment. Mark with @@{- instead of @{- to silence this warning.")] else []; forwards to item; diff --git a/grammars/silver/compiler/extension/doc/core/doclang/DclComment.sv b/grammars/silver/compiler/extension/doc/core/doclang/DclComment.sv index 13b1acdeb..0159a660c 100644 --- a/grammars/silver/compiler/extension/doc/core/doclang/DclComment.sv +++ b/grammars/silver/compiler/extension/doc/core/doclang/DclComment.sv @@ -33,18 +33,18 @@ synthesized attribute otherBlocks::[Pair]; @{- Config args. -} synthesized attribute configArgs::[Pair]; -nonterminal DclComment layout {} with docEnv, body, errors, location, downDocConfig, upDocConfig; +tracked nonterminal DclComment layout {} with docEnv, body, errors, downDocConfig, upDocConfig; -nonterminal DclCommentBlocks layout {} with paramBlocks, otherBlocks, configArgs, location, docEnv, errors; -nonterminal DclCommentStrictBlocks layout {} with paramBlocks, otherBlocks, configArgs, location, docEnv, errors; -nonterminal DclCommentBlock layout {} with paramBlocks, otherBlocks, configArgs, body, location, docEnv, errors; +tracked nonterminal DclCommentBlocks layout {} with paramBlocks, otherBlocks, configArgs, docEnv, errors; +tracked nonterminal DclCommentStrictBlocks layout {} with paramBlocks, otherBlocks, configArgs, docEnv, errors; +tracked nonterminal DclCommentBlock layout {} with paramBlocks, otherBlocks, configArgs, body, docEnv, errors; -nonterminal ConfigValue layout {} with location; +tracked nonterminal ConfigValue layout {}; -nonterminal DclCommentLines layout {} with body, location, docEnv, errors; +tracked nonterminal DclCommentLines layout {} with body, docEnv, errors; -nonterminal DclCommentParts layout {} with body, location, docEnv, errors; -nonterminal DclCommentPart layout {} with body, location, docEnv, errors; +tracked nonterminal DclCommentParts layout {} with body, docEnv, errors; +tracked nonterminal DclCommentPart layout {} with body, docEnv, errors; propagate docEnv on DclComment, DclCommentBlocks, DclCommentStrictBlocks, DclCommentBlock, @@ -123,8 +123,7 @@ top::DclComment ::= InitialIgnore_t blocks::DclCommentBlocks FinalIgnore_t top.doEmit = ((length(blocks.otherBlocks) + length(paramBlocks)) != 0) && (!doesExcludeFile(top.downDocConfig)) && - (!fromMaybe(false, fromMaybe(kwdValue(terminal(ConfigValueKeyword_t, "off"), - location=top.location), lookup("hide", blocks.configArgs)).asBool)); + (!fromMaybe(false, fromMaybe(kwdValue(terminal(ConfigValueKeyword_t, "off")), lookup("hide", blocks.configArgs)).asBool)); } function getBlocksNamed @@ -206,7 +205,7 @@ ${content} s"Doc Comment Parse Error at ${printLoc.filename} line ${toString(printLoc.line)} column ${toString(printLoc.column)}" ++ s"\n\tExpected a token of one of the following types: [${implode(", ", expected)}]" ++ s"\n\tInput currently matches: [${implode(", ", matched)}]") end - | unknownParseError(s, f) -> wrn(top.location, s"Doc comment unknown parse error: unknownParseError(${s}, ${f})") + | unknownParseError(s, f) -> wrnFromOrigin(top, s"Doc comment unknown parse error: unknownParseError(${s}, ${f})") end; top.errors := [errorMessage]; @@ -315,7 +314,7 @@ top::DclCommentBlock ::= Hide_t { forwards to configBlockImplicitTrue( terminal(Config_t, "@config"), terminal(Whitespace_t, ""), - terminal(Id_t, "hide"), terminal(Whitespace_t, ""), location=top.location); + terminal(Id_t, "hide"), terminal(Whitespace_t, "")); } concrete production configBlock @@ -331,7 +330,7 @@ concrete production configBlockImplicitTrue top::DclCommentBlock ::= Config_t Whitespace_t param::Id_t Whitespace_t { forwards to configBlock($1, $2, $3, $4, terminal(Equals_t, ""), terminal(Whitespace_t, ""), - kwdValue(terminal(ConfigValueKeyword_t, "true"), location=top.location), location=top.location); + kwdValue(terminal(ConfigValueKeyword_t, "true"))); } synthesized attribute asBool::Maybe occurs on ConfigValue; diff --git a/grammars/silver/compiler/extension/easyterminal/TerminalDcl.sv b/grammars/silver/compiler/extension/easyterminal/TerminalDcl.sv index 06d0da632..8f37b6664 100644 --- a/grammars/silver/compiler/extension/easyterminal/TerminalDcl.sv +++ b/grammars/silver/compiler/extension/easyterminal/TerminalDcl.sv @@ -34,11 +34,11 @@ top::RegExpr ::= t::Terminal_t production easyName::String = substring(1, length(t.lexeme) - 1, t.lexeme); top.easyName = just(easyName); - forwards to regExpr(regexLiteral(easyName), location=top.location); + forwards to regExpr(regexLiteral(easyName)); } {-- Abstracts away looking up terminals in the environment -} -nonterminal EasyTerminalRef with config, location, grammarName, unparse, errors, typerep, easyString, env, dcls; +tracked nonterminal EasyTerminalRef with config, grammarName, unparse, errors, typerep, easyString, env, dcls; {-- String literal between quotes. e.g. 'hi"' is hi" -} synthesized attribute easyString :: String; @@ -53,9 +53,9 @@ top::EasyTerminalRef ::= t::Terminal_t top.errors := if null(top.dcls) then - [err(t.location, "Could not find terminal declaration for " ++ t.lexeme )] + [errFromOrigin(t, "Could not find terminal declaration for " ++ t.lexeme )] else if length(top.dcls) > 1 then - [err(t.location, "Found ambiguous possibilities for " ++ t.lexeme ++ "\n" ++ printPossibilities(top.dcls))] + [errFromOrigin(t, "Found ambiguous possibilities for " ++ t.lexeme ++ "\n" ++ printPossibilities(top.dcls))] else []; top.typerep = if null(top.dcls) then errorType() else head(top.dcls).typeScheme.monoType; @@ -71,7 +71,7 @@ top::ProductionRHSElem ::= id::Name '::' reg::EasyTerminalRef top.lambdaBoundVars := [id.name]; -- Needed because we are forwrding based on env - forwards to productionRHSElem(id, $2, typerepTypeExpr(reg.typerep, location=reg.location), location=top.location); + forwards to productionRHSElem(id, $2, typerepTypeExpr(reg.typerep)); } concrete production productionRhsElemTypeEasyReg @@ -83,7 +83,7 @@ top::ProductionRHSElem ::= reg::EasyTerminalRef top.lambdaBoundVars := []; -- Needed because we are forwrding based on env - forwards to productionRHSElemType(typerepTypeExpr(reg.typerep, location=top.location), location=top.location); + forwards to productionRHSElemType(typerepTypeExpr(reg.typerep)); } concrete production aspectRHSElemEasyReg @@ -93,7 +93,7 @@ top::AspectRHSElem ::= reg::EasyTerminalRef propagate env; top.errors <- reg.errors; - forwards to aspectRHSElemNone('_', location=reg.location); -- TODO This isn't checking if the type is right!! + forwards to aspectRHSElemNone('_'); -- TODO This isn't checking if the type is right!! } concrete production aspectRHSElemTypedEasyReg @@ -103,7 +103,7 @@ top::AspectRHSElem ::= id::Name '::' reg::EasyTerminalRef propagate env; top.errors <- reg.errors; - forwards to aspectRHSElemTyped(id, $2, typerepTypeExpr(reg.typerep, location=reg.location), location=top.location); + forwards to aspectRHSElemTyped(id, $2, typerepTypeExpr(reg.typerep)); } {-- Introduce single quoted terminal literals in expressions -} @@ -117,7 +117,7 @@ top::Expr ::= reg::EasyTerminalRef local escapedName :: String = escapeString(reg.easyString); forwards to terminalFunction('terminal', '(', - typerepTypeExpr(reg.typerep, location=reg.location), - ',', stringConst(terminal(String_t, "\"" ++ escapedName ++ "\""), location=reg.location), ')', location=top.location); + typerepTypeExpr(reg.typerep), + ',', stringConst(terminal(String_t, "\"" ++ escapedName ++ "\"")), ')'); } diff --git a/grammars/silver/compiler/extension/implicit_monads/AttributeDefs.sv b/grammars/silver/compiler/extension/implicit_monads/AttributeDefs.sv index 8abc398c4..9c3695154 100644 --- a/grammars/silver/compiler/extension/implicit_monads/AttributeDefs.sv +++ b/grammars/silver/compiler/extension/implicit_monads/AttributeDefs.sv @@ -17,7 +17,7 @@ top::AGDcl ::= 'restricted' 'inherited' 'attribute' a::Name tl::BracketedOptType top.errors <- if length(getAttrDclAll(fName, top.env)) > 1 - then [err(a.location, "Attribute '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(a, "Attribute '" ++ fName ++ "' is already bound.")] else []; top.errors <- tl.errorsTyVars; @@ -25,7 +25,7 @@ top::AGDcl ::= 'restricted' 'inherited' 'attribute' a::Name tl::BracketedOptType production attribute fName :: String; fName = top.grammarName ++ ":" ++ a.name; - local fwd::AGDcl = defsAGDcl([restrictedInhDef(top.grammarName, a.location, fName, tl.freeVariables, te.typerep)], location=top.location); + local fwd::AGDcl = defsAGDcl([restrictedInhDef(top.grammarName, a.location, fName, tl.freeVariables, te.typerep)]); forwards to fwd; } @@ -47,7 +47,7 @@ top::AGDcl ::= 'restricted' 'synthesized' 'attribute' a::Name tl::BracketedOptTy top.errors <- if length(getAttrDclAll(fName, top.env)) > 1 - then [err(a.location, "Attribute '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(a, "Attribute '" ++ fName ++ "' is already bound.")] else []; top.errors <- tl.errorsTyVars; @@ -55,7 +55,7 @@ top::AGDcl ::= 'restricted' 'synthesized' 'attribute' a::Name tl::BracketedOptTy production attribute fName :: String; fName = top.grammarName ++ ":" ++ a.name; - local fwd::AGDcl = defsAGDcl([restrictedSynDef(top.grammarName, a.location, fName, tl.freeVariables, te.typerep)], location=top.location); + local fwd::AGDcl = defsAGDcl([restrictedSynDef(top.grammarName, a.location, fName, tl.freeVariables, te.typerep)]); forwards to fwd; } @@ -77,11 +77,11 @@ top::AGDcl ::= 'implicit' 'inherited' 'attribute' a::Name tl::BracketedOptTypeEx top.errors := if isMonad(te.typerep, top.env) then [] - else [err(top.location, "Implicit attributes must have a monadic type; " ++ + else [errFromOrigin(top, "Implicit attributes must have a monadic type; " ++ prettyType(te.typerep) ++ " is not monadic")]; top.errors <- if length(getAttrDclAll(fName, top.env)) > 1 - then [err(a.location, "Attribute '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(a, "Attribute '" ++ fName ++ "' is already bound.")] else []; top.errors <- tl.errorsTyVars; @@ -89,7 +89,7 @@ top::AGDcl ::= 'implicit' 'inherited' 'attribute' a::Name tl::BracketedOptTypeEx production attribute fName :: String; fName = top.grammarName ++ ":" ++ a.name; - local fwd::AGDcl = defsAGDcl([implicitInhDef(top.grammarName, a.location, fName, tl.freeVariables, te.typerep)], location=top.location); + local fwd::AGDcl = defsAGDcl([implicitInhDef(top.grammarName, a.location, fName, tl.freeVariables, te.typerep)]); forwards to fwd; } @@ -109,11 +109,11 @@ top::AGDcl ::= 'implicit' 'synthesized' 'attribute' a::Name tl::BracketedOptType top.errors := if isMonad(te.typerep, top.env) then [] - else [err(top.location, "Implicit attributes must have a monadic type; " ++ + else [errFromOrigin(top, "Implicit attributes must have a monadic type; " ++ prettyType(te.typerep) ++ " is not monadic")]; top.errors <- if length(getAttrDclAll(fName, top.env)) > 1 - then [err(a.location, "Attribute '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(a, "Attribute '" ++ fName ++ "' is already bound.")] else []; top.errors <- tl.errorsTyVars; @@ -121,7 +121,7 @@ top::AGDcl ::= 'implicit' 'synthesized' 'attribute' a::Name tl::BracketedOptType production attribute fName :: String; fName = top.grammarName ++ ":" ++ a.name; - local fwd::AGDcl = defsAGDcl([implicitSynDef(top.grammarName, a.location, fName, tl.freeVariables, te.typerep)], location=top.location); + local fwd::AGDcl = defsAGDcl([implicitSynDef(top.grammarName, a.location, fName, tl.freeVariables, te.typerep)]); forwards to fwd; } @@ -134,7 +134,7 @@ top::AGDcl ::= 'unrestricted' 'inherited' 'attribute' a::Name tl::BracketedOptTy { top.unparse = "unrestricted inherited attribute " ++ a.unparse ++ tl.unparse ++ " :: " ++ te.unparse ++ ";"; - forwards to attributeDclInh('inherited', 'attribute', a, tl, '::', te, ';', location=top.location); + forwards to attributeDclInh('inherited', 'attribute', a, tl, '::', te, ';'); } @@ -143,6 +143,6 @@ top::AGDcl ::= 'unrestricted' 'synthesized' 'attribute' a::Name tl::BracketedOpt { top.unparse = "unrestricted synthesized attribute " ++ a.unparse ++ tl.unparse ++ " :: " ++ te.unparse ++ ";"; - forwards to attributeDclSyn('synthesized', 'attribute', a, tl, '::', te, ';', location=top.location); + forwards to attributeDclSyn('synthesized', 'attribute', a, tl, '::', te, ';'); } diff --git a/grammars/silver/compiler/extension/implicit_monads/Case.sv b/grammars/silver/compiler/extension/implicit_monads/Case.sv index f188a8728..50ad6dd40 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Case.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Case.sv @@ -38,8 +38,7 @@ top::Expr ::= 'case' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' local basicFailure::Expr = mkStrFunctionInvocation(top.location, "silver:core:error", [stringConst(terminal(String_t, "\"Error: pattern match failed at " ++ top.grammarName ++ - " " ++ top.location.unparse ++ "\\n\""), - location=top.location)]); + " " ++ top.location.unparse ++ "\\n\""))]); {- Inserting fails breaks down if the current monad's fail is expecting something other than a string, integer, float, or list, @@ -92,7 +91,7 @@ top::Expr ::= 'case' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' makeLet(top.location, p.3, monadInnerType(p.1, top.location), p.2, rest), caseExpr(monadStuff.snd, ml.matchRuleList, !isMonadFail(top.expectedMonad, top.env), failure, - outty, location=top.location), + outty), monadStuff.1); monadLocal.mDownSubst = ml.mUpSubst; monadLocal.frame = top.frame; @@ -178,7 +177,7 @@ function monadicMatchTypesNames in if isMonad(ety, env) && fst(monadsMatch(ety, em, sub)) then ((ety, decE.monadRewritten, newName) :: subcall.1, - baseExpr(qName(loc, newName), location=loc) :: subcall.2) + baseExpr(qName(newName)) :: subcall.2) else (subcall.1, new(decE)::subcall.2) end end; @@ -242,7 +241,7 @@ Expr ::= es::[Expr] ml::[AbstractMatchRule] failExpr::Expr retType::Type loc::Lo | matchRule(_, nothing(), e) -> e --cond is a Boolean | matchRule(_, just((cond, nothing())), e) -> - ifThenElse('if', cond, 'then', e, 'else', rest, location=loc) + ifThenElse('if', cond, 'then', e, 'else', rest) --cond is the expression for another match | matchRule(_, just((cond, just(patt))), e) -> Silver_Expr { @@ -301,9 +300,9 @@ Expr ::= matchEs::[Expr] ruleGroups::[[AbstractMatchRule]] finalFail::Expr compileRest, retType, _, env), constructorGroups); local currentConCase::Expr = - matchPrimitive(firstMatchExpr, typerepTypeExpr(retType, location=loc), + matchPrimitive(firstMatchExpr, typerepTypeExpr(retType), foldPrimPatterns(mappedPatterns), - compileRest, location=loc); + compileRest); -- A quick note about that freshType() hack: putting it here means there's ONE fresh type -- generated, puching it inside 'bindHeadPattern' would generate multiple fresh types. @@ -342,7 +341,7 @@ PrimPattern ::= currExpr::Expr restExprs::[Expr] failCase::Expr retType::Type local annos :: [String] = nub(map(fst, flatMap((.patternNamedSubPatternList), map((.headPattern), mrs)))); local annoAccesses :: [Expr] = - map(\ n::String -> access(currExpr, '.', qNameAttrOccur(qName(l, n), location=l), location=l), annos); + map(\ n::String -> access(currExpr, '.', qNameAttrOccur(qName(n))), annos); -- Maybe this one is more reasonable? We need to test examples and see what happens... local l :: Location = head(mrs).headPattern.location; @@ -350,14 +349,14 @@ PrimPattern ::= currExpr::Expr restExprs::[Expr] failCase::Expr retType::Type return case head(mrs).headPattern of | prodAppPattern_named(qn,_,_,_,_,_) -> - prodPattern(qn, '(', convStringsToVarBinders(names, l), ')', terminal(Arrow_kwd, "->", l), subcase, location=l) - | intPattern(it) -> integerPattern(it, terminal(Arrow_kwd, "->", l), subcase, location=l) - | fltPattern(it) -> floatPattern(it, terminal(Arrow_kwd, "->", l), subcase, location=l) - | strPattern(it) -> stringPattern(it, terminal(Arrow_kwd, "->", l), subcase, location=l) - | truePattern(_) -> booleanPattern("true", terminal(Arrow_kwd, "->", l), subcase, location=l) - | falsePattern(_) -> booleanPattern("false", terminal(Arrow_kwd, "->", l), subcase, location=l) - | nilListPattern(_,_) -> nilPattern(subcase, location=l) - | consListPattern(h,_,t) -> conslstPattern(head(names), head(tail(names)), subcase, location=l) + prodPattern(qn, '(', convStringsToVarBinders(names, l), ')', terminal(Arrow_kwd, "->", l), subcase) + | intPattern(it) -> integerPattern(it, terminal(Arrow_kwd, "->", l), subcase) + | fltPattern(it) -> floatPattern(it, terminal(Arrow_kwd, "->", l), subcase) + | strPattern(it) -> stringPattern(it, terminal(Arrow_kwd, "->", l), subcase) + | truePattern(_) -> booleanPattern("true", terminal(Arrow_kwd, "->", l), subcase) + | falsePattern(_) -> booleanPattern("false", terminal(Arrow_kwd, "->", l), subcase) + | nilListPattern(_,_) -> nilPattern(subcase) + | consListPattern(h,_,t) -> conslstPattern(head(names), head(tail(names)), subcase) | _ -> error("Can only have constructor patterns in monadAllConCaseTransform") end; } @@ -370,7 +369,7 @@ top::Expr ::= 'case_any' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' propagate config, frame, env; top.merrors := []; - top.merrors <- if isMonadPlus_instance then [] else [err(top.location, notMonadPlus)]; + top.merrors <- if isMonadPlus_instance then [] else [errFromOrigin(top, notMonadPlus)]; ml.mDownSubst = top.mDownSubst; local monadInExprs::Boolean = @@ -389,13 +388,13 @@ top::Expr ::= 'case_any' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' --we need fresh names for the expressions being matched on, which we will use to only evaluate them once local newNames::[String] = map(\ x::Expr -> "__sv_mcase_var_" ++ toString(genInt()), es.rawExprs); local params::[Pair] = zip(newNames, ml.patternTypeList); - local nameExprs::[Expr] = map(\x::String -> baseExpr(qName(top.location, x), location=top.location), + local nameExprs::[Expr] = map(\x::String -> baseExpr(qName(x)), newNames); --Build a separate case expression for each match rule with mzero as the failure local caseExprs::[Expr] = map(\ x::AbstractMatchRule -> - caseExpr(nameExprs, [x], false, mzero, top.mtyperep, location=top.location), + caseExpr(nameExprs, [x], false, mzero, top.mtyperep), ml.matchRuleList); --Rewrite the case expressions, wrapped in lambdas to provide the names local rewrittenCaseExprs::[Expr] = @@ -454,9 +453,8 @@ top::Expr ::= 'case_any' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' --We need to forward to an errorExpr rather than the rewritten version to avoid flow errors --Because this should only be used in implicit equations, it should be fine - forwards to errorExpr([err(top.location, - "Can only use case_any in implicit equations")], - location=top.location); + forwards to errorExpr([errFromOrigin(top, + "Can only use case_any in implicit equations")]); } {- diff --git a/grammars/silver/compiler/extension/implicit_monads/CopperExpr.sv b/grammars/silver/compiler/extension/implicit_monads/CopperExpr.sv index 6c64ec5aa..549b36de8 100644 --- a/grammars/silver/compiler/extension/implicit_monads/CopperExpr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/CopperExpr.sv @@ -12,9 +12,9 @@ top::Expr ::= q::Decorated! QName top.mUpSubst = top.mDownSubst; top.mtyperep = q.lookupValue.typeScheme.monoType; top.monadicNames = if top.monadicallyUsed - then [baseExpr(q, location=top.location)] + then [baseExpr(q)] else []; - top.monadRewritten = baseExpr(q, location=top.location); + top.monadRewritten = baseExpr(q); } aspect production pluckTerminalReference @@ -24,9 +24,9 @@ top::Expr ::= q::Decorated! QName top.mUpSubst = top.mDownSubst; top.mtyperep = terminalIdType(); top.monadicNames = if top.monadicallyUsed - then [baseExpr(q, location=top.location)] + then [baseExpr(q)] else []; - top.monadRewritten = baseExpr(q, location=top.location); + top.monadRewritten = baseExpr(q); } aspect production terminalIdReference @@ -36,9 +36,9 @@ top::Expr ::= q::Decorated! QName top.mUpSubst = top.mDownSubst; top.mtyperep = terminalIdType(); top.monadicNames = if top.monadicallyUsed - then [baseExpr(q, location=top.location)] + then [baseExpr(q)] else []; - top.monadRewritten = baseExpr(q, location=top.location); + top.monadRewritten = baseExpr(q); } aspect production parserAttributeReference @@ -48,9 +48,9 @@ top::Expr ::= q::Decorated! QName top.mUpSubst = top.mDownSubst; top.mtyperep = q.lookupValue.typeScheme.monoType; top.monadicNames = if top.monadicallyUsed - then [baseExpr(q, location=top.location)] + then [baseExpr(q)] else []; - top.monadRewritten = baseExpr(q, location=top.location); + top.monadRewritten = baseExpr(q); } aspect production termAttrValueReference @@ -60,7 +60,7 @@ top::Expr ::= q::Decorated! QName top.mUpSubst = top.mDownSubst; top.mtyperep = q.lookupValue.typeScheme.monoType; top.monadicNames = if top.monadicallyUsed - then [baseExpr(q, location=top.location)] + then [baseExpr(q)] else []; - top.monadRewritten = baseExpr(q, location=top.location); + top.monadRewritten = baseExpr(q); } diff --git a/grammars/silver/compiler/extension/implicit_monads/DclInfo.sv b/grammars/silver/compiler/extension/implicit_monads/DclInfo.sv index afec71e02..a773d21e9 100644 --- a/grammars/silver/compiler/extension/implicit_monads/DclInfo.sv +++ b/grammars/silver/compiler/extension/implicit_monads/DclInfo.sv @@ -4,13 +4,13 @@ grammar silver:compiler:extension:implicit_monads; abstract production restrictedSynDcl top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type { - top.attrDefDispatcher = restrictedSynAttributeDef(_, _, _, location=_); + top.attrDefDispatcher = restrictedSynAttributeDef; --copied from synDcl - top.decoratedAccessHandler = synDecoratedAccessHandler(_, _, location=_); - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _, location=_), _, _, _); - top.dataAccessHandler = synDataAccessHandler(_, _, location=_); - top.attributionDispatcher = defaultAttributionDcl(_, _, _, _, location=_); + top.decoratedAccessHandler = synDecoratedAccessHandler; + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.dataAccessHandler = synDataAccessHandler; + top.attributionDispatcher = defaultAttributionDcl; top.fullName = fn; propagate compareKey; @@ -25,13 +25,13 @@ top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type abstract production restrictedInhDcl top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type { - top.attrDefDispatcher = restrictedInhAttributeDef(_, _, _, location=_); + top.attrDefDispatcher = restrictedInhAttributeDef; --copied from inhDcl - top.decoratedAccessHandler = inhDecoratedAccessHandler(_, _, location=_); - top.undecoratedAccessHandler = inhUndecoratedAccessErrorHandler(_, _, location=_); - top.dataAccessHandler = inhUndecoratedAccessErrorHandler(_, _, location=_); - top.attributionDispatcher = defaultAttributionDcl(_, _, _, _, location=_); + top.decoratedAccessHandler = inhDecoratedAccessHandler; + top.undecoratedAccessHandler = inhUndecoratedAccessErrorHandler; + top.dataAccessHandler = inhUndecoratedAccessErrorHandler; + top.attributionDispatcher = defaultAttributionDcl; top.fullName = fn; propagate compareKey; @@ -48,13 +48,13 @@ top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type abstract production implicitSynDcl top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type { - top.attrDefDispatcher = implicitSynAttributeDef(_, _, _, location=_); + top.attrDefDispatcher = implicitSynAttributeDef; --copied from synDcl - top.decoratedAccessHandler = synDecoratedAccessHandler(_, _, location=_); - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _, location=_), _, _, _); - top.dataAccessHandler = synDataAccessHandler(_, _, location=_); - top.attributionDispatcher = defaultAttributionDcl(_, _, _, _, location=_); + top.decoratedAccessHandler = synDecoratedAccessHandler; + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.dataAccessHandler = synDataAccessHandler; + top.attributionDispatcher = defaultAttributionDcl; top.fullName = fn; propagate compareKey; @@ -69,13 +69,13 @@ top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type abstract production implicitInhDcl top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type { - top.attrDefDispatcher = implicitInhAttributeDef(_, _, _, location=_); + top.attrDefDispatcher = implicitInhAttributeDef; --copied from inhDcl - top.decoratedAccessHandler = inhDecoratedAccessHandler(_, _, location=_); - top.undecoratedAccessHandler = inhUndecoratedAccessErrorHandler(_, _, location=_); - top.dataAccessHandler = inhUndecoratedAccessErrorHandler(_, _, location=_); - top.attributionDispatcher = defaultAttributionDcl(_, _, _, _, location=_); + top.decoratedAccessHandler = inhDecoratedAccessHandler; + top.undecoratedAccessHandler = inhUndecoratedAccessErrorHandler; + top.dataAccessHandler = inhUndecoratedAccessErrorHandler; + top.attributionDispatcher = defaultAttributionDcl; top.fullName = fn; propagate compareKey; diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index 3a9ffad34..51f7ef4fa 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -39,7 +39,7 @@ top::Expr ::= e::[Message] propagate mDownSubst, mUpSubst; top.mtyperep = errorType(); top.monadicNames = []; - top.monadRewritten = errorExpr(e, location=top.location); + top.monadRewritten = errorExpr(e); } aspect production errorReference @@ -49,7 +49,7 @@ top::Expr ::= msg::[Message] q::Decorated! QName propagate mDownSubst, mUpSubst; top.mtyperep = errorType(); top.monadicNames = []; - top.monadRewritten = baseExpr(q, location=top.location); + top.monadRewritten = baseExpr(q); } aspect production childReference @@ -61,9 +61,9 @@ top::Expr ::= q::Decorated! QName then q.lookupValue.typeScheme.asNtOrDecType else q.lookupValue.typeScheme.monoType; top.monadicNames = if top.monadicallyUsed - then [baseExpr(new(q), location=top.location)] + then [baseExpr(new(q))] else []; - top.monadRewritten = baseExpr(new(q), location=top.location); + top.monadRewritten = baseExpr(new(q)); } aspect production lhsReference @@ -73,9 +73,9 @@ top::Expr ::= q::Decorated! QName propagate mDownSubst, mUpSubst; top.mtyperep = q.lookupValue.typeScheme.asNtOrDecType; top.monadicNames = if top.monadicallyUsed - then [baseExpr(new(q), location=top.location)] + then [baseExpr(new(q))] else []; - top.monadRewritten = baseExpr(new(q), location=top.location); + top.monadRewritten = baseExpr(new(q)); } aspect production localReference @@ -87,9 +87,9 @@ top::Expr ::= q::Decorated! QName then q.lookupValue.typeScheme.asNtOrDecType else q.lookupValue.typeScheme.monoType; top.monadicNames = if top.monadicallyUsed - then [baseExpr(new(q), location=top.location)] + then [baseExpr(new(q))] else []; - top.monadRewritten = baseExpr(new(q), location=top.location); + top.monadRewritten = baseExpr(new(q)); } aspect production forwardReference @@ -100,9 +100,9 @@ top::Expr ::= q::Decorated! QName -- An LHS (and thus, forward) is *always* a decorable (nonterminal) type. top.mtyperep = q.lookupValue.typeScheme.asNtOrDecType; top.monadicNames = if top.monadicallyUsed - then [baseExpr(new(q), location=top.location)] + then [baseExpr(new(q))] else []; - top.monadRewritten = baseExpr(new(q), location=top.location); + top.monadRewritten = baseExpr(new(q)); } aspect production productionReference @@ -112,9 +112,9 @@ top::Expr ::= q::Decorated! QName propagate mDownSubst, mUpSubst; top.mtyperep = q.lookupValue.typeScheme.typerep; top.monadicNames = if top.monadicallyUsed - then [baseExpr(new(q), location=top.location)] + then [baseExpr(new(q))] else []; - top.monadRewritten = baseExpr(new(q), location=top.location); + top.monadRewritten = baseExpr(new(q)); } aspect production functionReference @@ -124,9 +124,9 @@ top::Expr ::= q::Decorated! QName propagate mDownSubst, mUpSubst; top.mtyperep = q.lookupValue.typeScheme.typerep; top.monadicNames = if top.monadicallyUsed - then [baseExpr(new(q), location=top.location)] + then [baseExpr(new(q))] else []; - top.monadRewritten = baseExpr(new(q), location=top.location); + top.monadRewritten = baseExpr(new(q)); } aspect production classMemberReference @@ -136,9 +136,9 @@ top::Expr ::= q::Decorated! QName propagate mDownSubst, mUpSubst; top.mtyperep = q.lookupValue.typeScheme.typerep; top.monadicNames = if top.monadicallyUsed - then [baseExpr(new(q), location=top.location)] + then [baseExpr(new(q))] else []; - top.monadRewritten = baseExpr(new(q), location=top.location); + top.monadRewritten = baseExpr(new(q)); } aspect production globalValueReference @@ -148,9 +148,9 @@ top::Expr ::= q::Decorated! QName propagate mDownSubst, mUpSubst; top.mtyperep = q.lookupValue.typeScheme.typerep; top.monadicNames = if top.monadicallyUsed - then [baseExpr(new(q), location=top.location)] + then [baseExpr(new(q))] else []; - top.monadRewritten = baseExpr(new(q), location=top.location); + top.monadRewritten = baseExpr(new(q)); } aspect production application @@ -263,19 +263,18 @@ top::Expr ::= e::Expr '(' es::AppExprs ',' anns::AnnoAppExprs ')' buildMonadApplicationLambda(nes.realTypes, nes.monadTypesLocations, nanns.monadAnns, top.expectedMonad, ety, funIsMonadic, wrapReturn, top.location); local expanded_args::AppExprs = - snocAppExprs(nanns.fullArgs, ',', presentAppExpr(ne.monadRewritten, location=top.location), - location=top.location); + snocAppExprs(nanns.fullArgs, ',', presentAppExpr(ne.monadRewritten)); top.monadRewritten = if areMonadicArgs || funIsMonadic - then applicationExpr(lambda_fun, '(', expanded_args, ')', location=top.location) - else application(ne.monadRewritten, '(', nes.monadRewritten, ',', nanns.monadRewritten, ')', location=top.location); + then applicationExpr(lambda_fun, '(', expanded_args, ')') + else application(ne.monadRewritten, '(', nes.monadRewritten, ',', nanns.monadRewritten, ')'); } aspect production functionInvocation top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs { - forward t = application(e, '(', es, ',', anns, ')', location=top.location); + forward t = application(e, '(', es, ',', anns, ')'); top.merrors := t.merrors; top.mUpSubst = t.mUpSubst; @@ -302,25 +301,21 @@ Expr ::= realtys::[Type] monadTysLocs::[Pair] monadAnns::[(Type, Q ([], length(realtys) + length(monadAnns)), monadAnns).1; local body::Expr = buildMonadApplicationBody(monadTysLocs ++ actualMonadAnns, funargs, funannargs, head(monadTysLocs).fst, funType, bindFun, wrapReturn, loc); - return lambdap(params, body, location=loc); + return lambdap(params, body); } --build the parameters for the lambda applied to all the original arguments plus the function function buildMonadApplicationParams ProductionRHS ::= realtys::[Type] currentLoc::Integer funType::Type loc::Location { return if null(realtys) - then productionRHSCons(productionRHSElem(name("f", loc), + then productionRHSCons(productionRHSElem(name("f"), '::', - typerepTypeExpr(funType, location=loc), - location=loc), - productionRHSNil(location=loc), - location=loc) + typerepTypeExpr(funType)), + productionRHSNil()) else productionRHSCons(productionRHSElem(name("a"++toString(currentLoc), loc), '::', - typerepTypeExpr(dropDecorated(head(realtys)), location=loc), - location=loc), - buildMonadApplicationParams(tail(realtys), currentLoc+1, funType, loc), - location=loc); + typerepTypeExpr(dropDecorated(head(realtys)))), + buildMonadApplicationParams(tail(realtys), currentLoc+1, funType, loc)); } --build the arguments for the application inside all the binds --currentIndex is the numerical index of the argument for the name (a, like a3) @@ -328,12 +323,10 @@ function buildFunArgs AppExprs ::= currentIndex::Integer loc::Location { return if currentIndex == 0 - then emptyAppExprs(location=loc) + then emptyAppExprs() else snocAppExprs(buildFunArgs(currentIndex - 1, loc), ',', presentAppExpr(baseExpr(qName(loc, - "a"++toString(currentIndex)), - location=loc), - location=loc), location=loc); + "a"++toString(currentIndex))))); } --build the annotation arguments for the application inside all the binds --annotations are the annotations given to the original call @@ -342,13 +335,11 @@ function buildFunAnnArgs AnnoAppExprs ::= annotations::[(Type, QName, Boolean)] currentIndex::Integer loc::Location { return case annotations of - | [] -> emptyAnnoAppExprs(location=loc) + | [] -> emptyAnnoAppExprs() | (ty, q, _)::rest -> snocAnnoAppExprs(buildFunAnnArgs(rest, currentIndex + 1, loc), ',', annoExpr(q, '=', - presentAppExpr(baseExpr(qName(loc, "a" ++ toString(currentIndex)), - location=loc), location=loc), location=loc), - location=loc) + presentAppExpr(baseExpr(qName("a" ++ toString(currentIndex)))))) end; } --build the body of the lambda which includes all the binds @@ -364,49 +355,36 @@ Expr ::= monadTysLocs::[Pair] funargs::AppExprs annargs::AnnoAppEx productionRHSCons(productionRHSElem(name("a"++toString(head(monadTysLocs).snd), loc), '::', - typerepTypeExpr(monadInnerType(argty, loc), - location=loc), - location=loc), - productionRHSNil(location=loc), - location=loc); + typerepTypeExpr(monadInnerType(argty, loc))), + productionRHSNil()); local bindargs::AppExprs = snocAppExprs( oneAppExprs(presentAppExpr( - baseExpr(qName(loc,"a"++toString(head(monadTysLocs).snd)), - location=loc), - location=loc), - location=loc), + baseExpr(qName(loc,"a"++toString(head(monadTysLocs).snd))))), ',', - presentAppExpr(lambdap(binding, sub, location=loc), - location=loc), - location=loc); + presentAppExpr(lambdap(binding, sub))); - local step::Expr = applicationExpr(bind, '(', bindargs, ')', location=loc); + local step::Expr = applicationExpr(bind, '(', bindargs, ')'); --the function is always going to be bound into the name "f", so we hard code that here - local baseapp::Expr = application(baseExpr(qName(loc, "f"), location=loc), - '(', funargs, ',', annargs, ')', location=loc); + local baseapp::Expr = application(baseExpr(qName("f")), + '(', funargs, ',', annargs, ')'); local funapp::Expr = if wrapReturn then Silver_Expr { $Expr {monadReturn(loc)}($Expr {baseapp}) } else baseapp; local funbinding::ProductionRHS = - productionRHSCons(productionRHSElem(name("f", loc), '::', - typerepTypeExpr(funTy, location=loc), location=loc), - productionRHSNil(location=loc), - location=loc); + productionRHSCons(productionRHSElem(name("f"), '::', + typerepTypeExpr(funTy)), + productionRHSNil()); local funbindargs::AppExprs = snocAppExprs( oneAppExprs(presentAppExpr( - baseExpr(qName(loc,"f"), location=loc), - location=loc), - location=loc), + baseExpr(qName(loc,"f")))), ',', - presentAppExpr(lambdap(funbinding, funapp, location=loc), - location=loc), - location=loc); + presentAppExpr(lambdap(funbinding, funapp))); local fullfun::Expr = if bindFun - then applicationExpr(bind, '(', funbindargs, ')', location=loc) + then applicationExpr(bind, '(', funbindargs, ')') else funapp; return if null(monadTysLocs) @@ -452,7 +430,7 @@ top::Expr ::= 'attachNote' note::Expr 'on' e::Expr 'end' e.monadicallyUsed = top.monadicallyUsed; top.monadicNames = e.monadicNames; - top.monadRewritten = noteAttachment('attachNote', note, 'on', e.monadRewritten, 'end', location=top.location); + top.monadRewritten = noteAttachment('attachNote', note, 'on', e.monadRewritten, 'end'); } aspect production forwardAccess @@ -494,7 +472,7 @@ top::Expr ::= e::Expr '.' 'forward' top.mtyperep = ne.mtyperep; top.monadicNames = ne.monadicNames; - top.monadRewritten = forwardAccess(ne.monadRewritten, '.', 'forward', location=top.location); + top.monadRewritten = forwardAccess(ne.monadRewritten, '.', 'forward'); } aspect production errorAccessHandler @@ -502,7 +480,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur { e.monadicallyUsed = false; --this needs to change when we decorate monadic trees top.monadicNames = if top.monadicallyUsed - then [access(e, '.', q, location=top.location)] ++ e.monadicNames + then [access(e, '.', q)] ++ e.monadicNames else e.monadicNames; propagate mDownSubst, mUpSubst; @@ -513,7 +491,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur | implicitSynDcl(_, _, _) -> [] | implicitInhDcl(_, _, _) -> [] | annoDcl(_, _, _) -> [] - | _ -> [err(top.location, "Attributes accessed in implicit equations must " ++ + | _ -> [errFromOrigin(top, "Attributes accessed in implicit equations must " ++ "be either implicit or restricted; " ++ q.unparse ++ " is neither")] end; @@ -525,14 +503,14 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur if e.mtyperep.isDecorated then Silver_Expr{ silver:core:new($Expr {e.monadRewritten}) } else e.monadRewritten; - local noMonad::Expr = access(e.monadRewritten, '.', q, location=top.location); + local noMonad::Expr = access(e.monadRewritten, '.', q); local isEMonad::Expr = Silver_Expr { $Expr {monadBind(top.location)} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> $Expr {monadReturn(top.location)} - (x.$QName {qName(q.location, q.name)}) + (x.$QName {qName(q.name)}) ) ) }; @@ -540,8 +518,8 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur Silver_Expr { $Expr {monadBind(top.location)} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location), location=top.location)} -> - (x.$QName {qName(q.location, q.name)}) + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> + (x.$QName {qName(q.name)}) ) ) }; @@ -578,21 +556,21 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur e.mDownSubst = top.mDownSubst; e.monadicallyUsed = false; --this needs to change when we decorate monadic trees top.monadicNames = if top.monadicallyUsed - then [access(e, '.', q, location=top.location)] ++ e.monadicNames + then [access(e, '.', q)] ++ e.monadicNames else e.monadicNames; local eUnDec::Expr = if e.mtyperep.isDecorated then Silver_Expr{ silver:core:new($Expr {e.monadRewritten}) } else e.monadRewritten; - local noMonad::Expr = access(e.monadRewritten, '.', q, location=top.location); + local noMonad::Expr = access(e.monadRewritten, '.', q); local isEMonad::Expr = Silver_Expr { $Expr {monadBind(top.location)} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> $Expr {monadReturn(top.location)} - (x.$QName {qName(q.location, q.name)}) + (x.$QName {qName(q.name)}) ) ) }; @@ -600,8 +578,8 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur Silver_Expr { $Expr {monadBind(top.location)} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location), location=top.location)} -> - (x.$QName {qName(q.location, q.name)}) + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> + (x.$QName {qName(q.name)}) ) ) }; @@ -637,21 +615,21 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur e.mDownSubst = top.mDownSubst; e.monadicallyUsed = false; --this needs to change when we decorate monadic trees top.monadicNames = if top.monadicallyUsed - then [access(e, '.', q, location=top.location)] ++ e.monadicNames + then [access(e, '.', q)] ++ e.monadicNames else e.monadicNames; local eUnDec::Expr = if e.mtyperep.isDecorated then Silver_Expr{ silver:core:new($Expr {e.monadRewritten}) } else e.monadRewritten; - local noMonad::Expr = access(e.monadRewritten, '.', q, location=top.location); + local noMonad::Expr = access(e.monadRewritten, '.', q); local isEMonad::Expr = Silver_Expr { $Expr {monadBind(top.location)} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> $Expr {monadReturn(top.location)} - (x.$QName {qName(q.location, q.name)}) + (x.$QName {qName(q.name)}) ) ) }; @@ -659,8 +637,8 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur Silver_Expr { $Expr {monadBind(top.location)} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location), location=top.location)} -> - (x.$QName {qName(q.location, q.name)}) + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> + (x.$QName {qName(q.name)}) ) ) }; @@ -688,7 +666,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur | implicitSynDcl(_, _, _) -> [] | implicitInhDcl(_, _, _) -> [] | annoDcl(_, _, _) -> [] - | _ -> [err(top.location, "Attributes accessed in implicit equations must " ++ + | _ -> [errFromOrigin(top, "Attributes accessed in implicit equations must " ++ "be either implicit or restricted; " ++ q.unparse ++ " is neither")] end; @@ -714,21 +692,21 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur e.monadicallyUsed = false; --this needs to change when we decorate monadic trees top.monadicNames = if top.monadicallyUsed - then [access(e, '.', q, location=top.location)] ++ e.monadicNames + then [access(e, '.', q)] ++ e.monadicNames else e.monadicNames; local eUnDec::Expr = if e.mtyperep.isDecorated then Silver_Expr{ silver:core:new($Expr {e.monadRewritten}) } else e.monadRewritten; - local noMonad::Expr = access(e.monadRewritten, '.', q, location=top.location); + local noMonad::Expr = access(e.monadRewritten, '.', q); local isEMonad::Expr = Silver_Expr { $Expr {monadBind(top.location)} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> $Expr {monadReturn(top.location)} - (x.$QName {qName(q.location, q.name)}) + (x.$QName {qName(q.name)}) ) ) }; @@ -758,21 +736,21 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur e.mDownSubst = top.mDownSubst; e.monadicallyUsed = false; --this needs to change when we decorate monadic trees top.monadicNames = if top.monadicallyUsed - then [access(e, '.', q, location=top.location)] ++ e.monadicNames + then [access(e, '.', q)] ++ e.monadicNames else e.monadicNames; local eUnDec::Expr = if e.mtyperep.isDecorated then Silver_Expr{ silver:core:new($Expr {e.monadRewritten}) } else e.monadRewritten; - local noMonad::Expr = access(e.monadRewritten, '.', q, location=top.location); + local noMonad::Expr = access(e.monadRewritten, '.', q); local isEMonad::Expr = Silver_Expr { $Expr {monadBind(top.location)} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> $Expr {monadReturn(top.location)} - (x.$QName {qName(q.location, q.name)}) + (x.$QName {qName(q.name)}) ) ) }; @@ -780,8 +758,8 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur Silver_Expr { $Expr {monadBind(top.location)} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location), location=top.location)} -> - (x.$QName {qName(q.location, q.name)}) + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> + (x.$QName {qName(q.name)}) ) ) }; @@ -809,7 +787,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur | implicitSynDcl(_, _, _) -> [] | implicitInhDcl(_, _, _) -> [] | annoDcl(_, _, _) -> [] - | _ -> [err(top.location, "Attributes accessed in implicit equations must " ++ + | _ -> [errFromOrigin(top, "Attributes accessed in implicit equations must " ++ "be either implicit or restricted; " ++ q.unparse ++ " is neither")] end; @@ -831,21 +809,21 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur e.mDownSubst = top.mDownSubst; e.monadicallyUsed = false; --this needs to change when we decorate monadic trees top.monadicNames = if top.monadicallyUsed - then [access(e, '.', q, location=top.location)] ++ e.monadicNames + then [access(e, '.', q)] ++ e.monadicNames else e.monadicNames; local eUnDec::Expr = if e.mtyperep.isDecorated then Silver_Expr{ silver:core:new($Expr {e.monadRewritten}) } else e.monadRewritten; - local noMonad::Expr = access(e.monadRewritten, '.', q, location=top.location); + local noMonad::Expr = access(e.monadRewritten, '.', q); local isEMonad::Expr = Silver_Expr { $Expr {monadBind(top.location)} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> $Expr {monadReturn(top.location)} - (x.$QName {qName(q.location, q.name)}) + (x.$QName {qName(q.name)}) ) ) }; @@ -853,8 +831,8 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur Silver_Expr { $Expr {monadBind(top.location)} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location), location=top.location)} -> - (x.$QName {qName(q.location, q.name)}) + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> + (x.$QName {qName(q.name)}) ) ) }; @@ -882,7 +860,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur | implicitSynDcl(_, _, _) -> [] | implicitInhDcl(_, _, _) -> [] | annoDcl(_, _, _) -> [] - | _ -> [err(top.location, "Attributes accessed in implicit equations must " ++ + | _ -> [errFromOrigin(top, "Attributes accessed in implicit equations must " ++ "be either implicit or restricted; " ++ q.unparse ++ " is neither")] end; @@ -904,7 +882,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur { e.monadicallyUsed = false; --this needs to change when we decorate monadic trees top.monadicNames = if top.monadicallyUsed - then [access(e, '.', q, location=top.location)] ++ e.monadicNames + then [access(e, '.', q)] ++ e.monadicNames else e.monadicNames; propagate mDownSubst, mUpSubst; @@ -913,7 +891,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur -- TODO: restricted translation attributes? -- | restrictedSynDcl(_, _, _) -> [] -- | restrictedInhDcl(_, _, _) -> [] - | _ -> [err(top.location, "Attributes accessed in implicit equations must " ++ + | _ -> [errFromOrigin(top, "Attributes accessed in implicit equations must " ++ "be either implicit or restricted; " ++ q.unparse ++ " is neither")] end; @@ -922,14 +900,14 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur if e.mtyperep.isDecorated then Silver_Expr{ silver:core:new($Expr {e.monadRewritten}) } else e.monadRewritten; - local noMonad::Expr = access(e.monadRewritten, '.', q, location=top.location); + local noMonad::Expr = access(e.monadRewritten, '.', q); local isEMonad::Expr = Silver_Expr { $Expr {monadBind(top.location)} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> $Expr {monadReturn(top.location)} - (x.$QName {qName(q.location, q.name)}) + (x.$QName {qName(q.name)}) ) ) }; @@ -968,14 +946,14 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur if e.mtyperep.isDecorated then Silver_Expr{ silver:core:new($Expr {e.monadRewritten}) } else e.monadRewritten; - local noMonad::Expr = access(e.monadRewritten, '.', q, location=top.location); + local noMonad::Expr = access(e.monadRewritten, '.', q); local isEMonad::Expr = Silver_Expr { $Expr {monadBind(top.location)} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> $Expr {monadReturn(top.location)} - (x.$QName {qName(q.location, q.name)}) + (x.$QName {qName(q.name)}) ) ) }; @@ -983,8 +961,8 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur Silver_Expr { $Expr {monadBind(top.location)} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location), location=top.location)} -> - (x.$QName {qName(q.location, q.name)}) + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> + (x.$QName {qName(q.name)}) ) ) }; @@ -1011,7 +989,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur | implicitSynDcl(_, _, _) -> [] | implicitInhDcl(_, _, _) -> [] | annoDcl(_, _, _) -> [] - | _ -> [err(top.location, "Attributes accessed in implicit equations must " ++ + | _ -> [errFromOrigin(top, "Attributes accessed in implicit equations must " ++ "be either implicit or restricted; " ++ q.unparse ++ " is neither")] end; @@ -1033,7 +1011,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur { e.monadicallyUsed = false; --this needs to change when we decorate monadic trees top.monadicNames = if top.monadicallyUsed - then [access(e, '.', q, location=top.location)] ++ e.monadicNames + then [access(e, '.', q)] ++ e.monadicNames else e.monadicNames; propagate mDownSubst, mUpSubst; @@ -1042,7 +1020,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur -- TODO: restricted translation attributes? -- | restrictedSynDcl(_, _, _) -> [] -- | restrictedInhDcl(_, _, _) -> [] - | _ -> [err(top.location, "Attributes accessed in implicit equations must " ++ + | _ -> [errFromOrigin(top, "Attributes accessed in implicit equations must " ++ "be either implicit or restricted; " ++ q.unparse ++ " is neither")] end; @@ -1054,14 +1032,14 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur if e.mtyperep.isDecorated then Silver_Expr{ silver:core:new($Expr {e.monadRewritten}) } else e.monadRewritten; - local noMonad::Expr = access(e.monadRewritten, '.', q, location=top.location); + local noMonad::Expr = access(e.monadRewritten, '.', q); local isEMonad::Expr = Silver_Expr { $Expr {monadBind(top.location)} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> $Expr {monadReturn(top.location)} - (x.$QName {qName(q.location, q.name)}) + (x.$QName {qName(q.name)}) ) ) }; @@ -1087,7 +1065,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur { e.monadicallyUsed = false; --this needs to change when we decorate monadic trees top.monadicNames = if top.monadicallyUsed - then [access(e, '.', q, location=top.location)] ++ e.monadicNames + then [access(e, '.', q)] ++ e.monadicNames else e.monadicNames; propagate mDownSubst, mUpSubst; @@ -1096,7 +1074,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur -- TODO: restricted translation attributes? -- | restrictedSynDcl(_, _, _) -> [] -- | restrictedInhDcl(_, _, _) -> [] - | _ -> [err(top.location, "Attributes accessed in implicit equations must " ++ + | _ -> [errFromOrigin(top, "Attributes accessed in implicit equations must " ++ "be either implicit or restricted; " ++ q.unparse ++ " is neither")] end; @@ -1108,14 +1086,14 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur if e.mtyperep.isDecorated then Silver_Expr{ silver:core:new($Expr {e.monadRewritten}) } else e.monadRewritten; - local noMonad::Expr = access(e.monadRewritten, '.', q, location=top.location); + local noMonad::Expr = access(e.monadRewritten, '.', q); local isEMonad::Expr = Silver_Expr { $Expr {monadBind(top.location)} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> $Expr {monadReturn(top.location)} - (x.$QName {qName(q.location, q.name)}) + (x.$QName {qName(q.name)}) ) ) }; @@ -1168,10 +1146,8 @@ top::Expr ::= 'decorate' e::Expr 'with' '{' inh::ExprInhs '}' local params::ProductionRHS = productionRHSCons(productionRHSElem(name(newname, top.location), '::', - typerepTypeExpr(monadInnerType(e.mtyperep, top.location), location=top.location), - location=top.location), - productionRHSNil(location=top.location), - location=top.location); + typerepTypeExpr(monadInnerType(e.mtyperep, top.location))), + productionRHSNil()); local eUnDec::Expr = if e.mtyperep.isDecorated then Silver_Expr {new($Expr {e.monadRewritten})} @@ -1185,12 +1161,12 @@ top::Expr ::= 'decorate' e::Expr 'with' '{' inh::ExprInhs '}' Silver_Expr{ $Expr{monadReturn(top.location)} ($Expr{decorateExprWith('decorate', - baseExpr(qName(top.location, newname), location=top.location), - 'with', '{', inh.monadRewritten, '}', location=top.location)}) - }, location=top.location)}) + baseExpr(qName(newname)), + 'with', '{', inh.monadRewritten, '}')}) + })}) } else decorateExprWith('decorate', e.monadRewritten, 'with', - '{', inh.monadRewritten, '}', location=top.location); + '{', inh.monadRewritten, '}'); } attribute monadRewritten, merrors, mDownSubst, mUpSubst, monadicNames, expectedMonad occurs on ExprInhs; @@ -1205,7 +1181,7 @@ top::ExprInhs ::= top.monadicNames = []; - top.monadRewritten = exprInhsEmpty(location=top.location); + top.monadRewritten = exprInhsEmpty(); } aspect production exprInhsOne @@ -1215,7 +1191,7 @@ top::ExprInhs ::= lhs::ExprInh top.monadicNames = lhs.monadicNames; - top.monadRewritten = exprInhsOne(lhs.monadRewritten, location=top.location); + top.monadRewritten = exprInhsOne(lhs.monadRewritten); } aspect production exprInhsCons @@ -1225,7 +1201,7 @@ top::ExprInhs ::= lhs::ExprInh inh::ExprInhs top.monadicNames = lhs.monadicNames ++ inh.monadicNames; - top.monadRewritten = exprInhsCons(lhs.monadRewritten, inh.monadRewritten, location=top.location); + top.monadRewritten = exprInhsCons(lhs.monadRewritten, inh.monadRewritten); } aspect production exprInh @@ -1236,7 +1212,7 @@ top::ExprInh ::= lhs::ExprLHSExpr '=' e::Expr ';' e.monadicallyUsed = false; top.monadicNames = e.monadicNames; - top.monadRewritten = exprInh(lhs, '=', e.monadRewritten, ';', location=top.location); + top.monadRewritten = exprInh(lhs, '=', e.monadRewritten, ';'); } @@ -1246,7 +1222,7 @@ top::Expr ::= '@' e::Expr top.mtyperep = e.mtyperep.decoratedType; top.merrors := e.merrors; top.monadicNames = e.monadicNames; - top.monadRewritten = decorationSiteExpr('@', e.monadRewritten, location=top.location); + top.monadRewritten = decorationSiteExpr('@', e.monadRewritten); e.monadicallyUsed = false; local attribute errCheck1 :: TypeCheck; errCheck1.finalSubst = top.finalSubst; @@ -1256,7 +1232,7 @@ top::Expr ::= '@' e::Expr errCheck1 = check(e.typerep, uniqueDecoratedType(freshType(), inhSetType([]))); top.merrors <- if errCheck1.typeerror - then [err(top.location, "Operand to @ must be a unique reference with no inherited attributes. Instead it is of type " ++ errCheck1.leftpp)] + then [errFromOrigin(top, "Operand to @ must be a unique reference with no inherited attributes. Instead it is of type " ++ errCheck1.leftpp)] else []; } @@ -1267,7 +1243,7 @@ top::Expr ::= 'true' top.mtyperep = boolType(); top.merrors := []; top.monadicNames = []; - top.monadRewritten = trueConst('true', location=top.location); + top.monadRewritten = trueConst('true'); } aspect production falseConst @@ -1277,7 +1253,7 @@ top::Expr ::= 'false' top.mtyperep = boolType(); top.merrors := []; top.monadicNames = []; - top.monadRewritten = falseConst('false', location=top.location); + top.monadRewritten = falseConst('false'); } aspect production and @@ -1288,14 +1264,14 @@ top::Expr ::= e1::Expr '&&' e2::Expr if isMonad(e1.mtyperep, top.env) then if monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst then [] - else [err(top.location, "Can only use " ++ monadToString(top.expectedMonad) ++ + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ " implicitly in this '&&', not " ++ monadToString(e1.mtyperep))] else []; top.merrors <- if isMonad(e2.mtyperep, top.env) then if monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst then [] - else [err(top.location, "Can only use " ++ monadToString(top.expectedMonad) ++ + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ " implicitly in this '&&', not " ++ monadToString(e2.mtyperep))] else []; @@ -1335,8 +1311,8 @@ top::Expr ::= e1::Expr '&&' e2::Expr Silver_Expr { $Expr {monadBind(top.location)} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location), location=top.location)} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} + y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> if x then y else $Expr {monadReturn(top.location)}(false)) (_, $Expr {e2UnDec})) }; --e1 >>= ( (\x y -> Return(x && y))(_, e2) ) @@ -1344,8 +1320,8 @@ top::Expr ::= e1::Expr '&&' e2::Expr Silver_Expr { $Expr {monadBind(top.location)} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location), location=top.location)} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location))} + y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> $Expr {monadReturn(top.location)} (x && y))(_, $Expr {e2UnDec})) }; @@ -1360,7 +1336,7 @@ top::Expr ::= e1::Expr '&&' e2::Expr else bind1 else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst then bind2 - else and(e1.monadRewritten, '&&', e2.monadRewritten, location=top.location); + else and(e1.monadRewritten, '&&', e2.monadRewritten); } aspect production or @@ -1371,14 +1347,14 @@ top::Expr ::= e1::Expr '||' e2::Expr if isMonad(e1.mtyperep, top.env) then if monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst then [] - else [err(top.location, "Can only use " ++ monadToString(top.expectedMonad) ++ + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ " implicitly in this '||', not " ++ monadToString(e1.mtyperep))] else []; top.merrors <- if isMonad(e2.mtyperep, top.env) then if monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst then [] - else [err(top.location, "Can only use " ++ monadToString(top.expectedMonad) ++ + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ " implicitly in this '||', not " ++ monadToString(e2.mtyperep))] else []; @@ -1418,8 +1394,8 @@ top::Expr ::= e1::Expr '||' e2::Expr Silver_Expr { $Expr {monadBind(top.location)} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location), location=top.location)} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} + y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> if x then $Expr {monadReturn(top.location)}(true) else y) (_, $Expr {e2UnDec})) }; --e1 >>= ( (\x y -> Return(x || y))(_, e2) ) @@ -1427,8 +1403,8 @@ top::Expr ::= e1::Expr '||' e2::Expr Silver_Expr { $Expr {monadBind(top.location)} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location), location=top.location)} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location))} + y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> $Expr {monadReturn(top.location)} (x || y))(_, $Expr {e2UnDec})) }; @@ -1443,7 +1419,7 @@ top::Expr ::= e1::Expr '||' e2::Expr else bind1 else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst then bind2 - else or(e1.monadRewritten, '||', e2.monadRewritten, location=top.location); + else or(e1.monadRewritten, '||', e2.monadRewritten); } aspect production notOp @@ -1454,7 +1430,7 @@ top::Expr ::= '!' e::Expr if isMonad(e.mtyperep, top.env) && monadsMatch(top.expectedMonad, e.mtyperep, top.mDownSubst).fst then if monadsMatch(top.expectedMonad, e.mtyperep, top.mDownSubst).fst then [] - else [err(top.location, "Can only use " ++ monadToString(top.expectedMonad) ++ + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ " implicitly in this '!', not " ++ monadToString(e.mtyperep))] else []; @@ -1482,7 +1458,7 @@ top::Expr ::= '!' e::Expr \x::Boolean -> $Expr {monadReturn(top.location)}(!x)) } - else notOp('!', e.monadRewritten, location=top.location); + else notOp('!', e.monadRewritten); } concrete production ifThen @@ -1495,13 +1471,13 @@ top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'end' --this is easier than anything if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst then if monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst then [] - else [err(top.location, "Can only use " ++ monadToString(top.expectedMonad) ++ + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ " implicitly in this 'if-then', not " ++ monadToString(e1.mtyperep))] else []; top.merrors <- if isMonadFail(top.expectedMonad, top.env) then [] - else [err(top.location, monadToString(top.expectedMonad) ++ + else [errFromOrigin(top, monadToString(top.expectedMonad) ++ " is not an instance of MonadFail and cannot be used with if-then")]; local ec::TypeCheck = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst @@ -1537,7 +1513,7 @@ top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'end' --this is easier than anything e1.isRoot = false; e2.isRoot = false; - forwards to ifThenElse('if', e1, 'then', e2, 'else', monadFail(top.location), location=top.location); + forwards to ifThenElse('if', e1, 'then', e2, 'else', monadFail(top.location)); } aspect production ifThenElse @@ -1548,7 +1524,7 @@ top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'else' e3::Expr if isMonad(e1.mtyperep, top.env) then if monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst then [] - else [err(top.location, "Can only use " ++ monadToString(top.expectedMonad) ++ + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ " implicitly in this 'if-then-els', not " ++ monadToString(e1.mtyperep))] else []; @@ -1602,10 +1578,10 @@ top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'else' e3::Expr $Expr {monadBind(top.location)} ($Expr {e1UnDec}, (\c::Boolean - x::$TypeExpr {typerepTypeExpr(dropDecorated(e2Type), location=top.location)} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e3Type), location=top.location)} -> - --x::$TypeExpr {typerepTypeExpr(e2Type, location=top.location)} - --y::$TypeExpr {typerepTypeExpr(e3Type, location=top.location)} -> + x::$TypeExpr {typerepTypeExpr(dropDecorated(e2Type))} + y::$TypeExpr {typerepTypeExpr(dropDecorated(e3Type))} -> + --x::$TypeExpr {typerepTypeExpr(e2Type)} + --y::$TypeExpr {typerepTypeExpr(e3Type)} -> if c then $Expr { if isMonad(e2.mtyperep, top.env) then Silver_Expr {x} @@ -1641,7 +1617,7 @@ top::Expr ::= i::Int_t propagate mDownSubst, mUpSubst; top.mtyperep = intType(); top.monadicNames = []; - top.monadRewritten = intConst(i, location=top.location); + top.monadRewritten = intConst(i); } aspect production floatConst @@ -1651,7 +1627,7 @@ top::Expr ::= f::Float_t propagate mDownSubst, mUpSubst; top.mtyperep = floatType(); top.monadicNames = []; - top.monadRewritten = floatConst(f, location=top.location); + top.monadRewritten = floatConst(f); } aspect production plus @@ -1662,14 +1638,14 @@ top::Expr ::= e1::Expr '+' e2::Expr if isMonad(e1.mtyperep, top.env) then if monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst then [] - else [err(top.location, "Can only use " ++ monadToString(top.expectedMonad) ++ + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ " implicitly in this '+', not " ++ monadToString(e1.mtyperep))] else []; top.merrors <- if isMonad(e2.mtyperep, top.env) then if monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst then [] - else [err(top.location, "Can only use " ++ monadToString(top.expectedMonad) ++ + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ " implicitly in this '+', not " ++ monadToString(e2.mtyperep))] else []; @@ -1707,11 +1683,11 @@ top::Expr ::= e1::Expr '+' e2::Expr Silver_Expr { $Expr {monadBind(top.location)} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location), location=top.location)} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} + y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> $Expr {monadBind(top.location)} (y, - \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location), location=top.location)} -> + \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} -> $Expr {monadReturn(top.location)} (x + z))) (_, $Expr {e2UnDec})) }; @@ -1720,8 +1696,8 @@ top::Expr ::= e1::Expr '+' e2::Expr Silver_Expr { $Expr {monadBind(top.location)} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location), location=top.location)} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location))} + y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> $Expr {monadReturn(top.location)} (x + y))(_, $Expr {e2UnDec})) }; @@ -1730,8 +1706,8 @@ top::Expr ::= e1::Expr '+' e2::Expr Silver_Expr { $Expr {monadBind(top.location)} ($Expr {e2UnDec}, - (\x::$TypeExpr {typerepTypeExpr(e1.mtyperep, location=top.location)} - y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(e1.mtyperep)} + y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} -> $Expr {monadReturn(top.location)} (x + y))($Expr {e1UnDec}, _)) }; @@ -1741,7 +1717,7 @@ top::Expr ::= e1::Expr '+' e2::Expr else bind1 else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst then bind2 - else plus(e1.monadRewritten, '+', e2.monadRewritten, location=top.location); + else plus(e1.monadRewritten, '+', e2.monadRewritten); } aspect production minus @@ -1752,14 +1728,14 @@ top::Expr ::= e1::Expr '-' e2::Expr if isMonad(e1.mtyperep, top.env) then if monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst then [] - else [err(top.location, "Can only use " ++ monadToString(top.expectedMonad) ++ + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ " implicitly in this '-', not " ++ monadToString(e1.mtyperep))] else []; top.merrors <- if isMonad(e2.mtyperep, top.env) then if monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst then [] - else [err(top.location, "Can only use " ++ monadToString(top.expectedMonad) ++ + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ " implicitly in this '-', not " ++ monadToString(e2.mtyperep))] else []; @@ -1797,11 +1773,11 @@ top::Expr ::= e1::Expr '-' e2::Expr Silver_Expr { $Expr {monadBind(top.location)} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location), location=top.location)} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} + y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> $Expr {monadBind(top.location)} (y, - \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location), location=top.location)} -> + \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} -> $Expr {monadReturn(top.location)} (x - z))) (_, $Expr {e2UnDec})) }; @@ -1810,8 +1786,8 @@ top::Expr ::= e1::Expr '-' e2::Expr Silver_Expr { $Expr {monadBind(top.location)} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location), location=top.location)} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location))} + y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> $Expr {monadReturn(top.location)} (x - y))(_, $Expr {e2UnDec})) }; @@ -1820,8 +1796,8 @@ top::Expr ::= e1::Expr '-' e2::Expr Silver_Expr { $Expr {monadBind(top.location)} ($Expr {e2UnDec}, - (\x::$TypeExpr {typerepTypeExpr(e1.mtyperep, location=top.location)} - y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(e1.mtyperep)} + y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} -> $Expr {monadReturn(top.location)} (x - y))($Expr {e1UnDec}, _)) }; @@ -1831,7 +1807,7 @@ top::Expr ::= e1::Expr '-' e2::Expr else bind1 else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst then bind2 - else minus(e1.monadRewritten, '-', e2.monadRewritten, location=top.location); + else minus(e1.monadRewritten, '-', e2.monadRewritten); } aspect production multiply @@ -1842,14 +1818,14 @@ top::Expr ::= e1::Expr '*' e2::Expr if isMonad(e1.mtyperep, top.env) then if monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst then [] - else [err(top.location, "Can only use " ++ monadToString(top.expectedMonad) ++ + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ " implicitly in this '*', not " ++ monadToString(e1.mtyperep))] else []; top.merrors <- if isMonad(e2.mtyperep, top.env) then if monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst then [] - else [err(top.location, "Can only use " ++ monadToString(top.expectedMonad) ++ + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ " implicitly in this '*', not " ++ monadToString(e2.mtyperep))] else []; @@ -1887,11 +1863,11 @@ top::Expr ::= e1::Expr '*' e2::Expr Silver_Expr { $Expr {monadBind(top.location)} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location), location=top.location)} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} + y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> $Expr {monadBind(top.location)} (y, - \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location), location=top.location)} -> + \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} -> $Expr {monadReturn(top.location)} (x * z))) (_, $Expr {e2UnDec})) }; @@ -1900,8 +1876,8 @@ top::Expr ::= e1::Expr '*' e2::Expr Silver_Expr { $Expr {monadBind(top.location)} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location), location=top.location)} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location))} + y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> $Expr {monadReturn(top.location)} (x * y))(_, $Expr {e2UnDec})) }; @@ -1910,8 +1886,8 @@ top::Expr ::= e1::Expr '*' e2::Expr Silver_Expr { $Expr {monadBind(top.location)} ($Expr {e2UnDec}, - (\x::$TypeExpr {typerepTypeExpr(e1.mtyperep, location=top.location)} - y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(e1.mtyperep)} + y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} -> $Expr {monadReturn(top.location)} (x * y))($Expr {e1UnDec}, _)) }; @@ -1921,7 +1897,7 @@ top::Expr ::= e1::Expr '*' e2::Expr else bind1 else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst then bind2 - else multiply(e1.monadRewritten, '*', e2.monadRewritten, location=top.location); + else multiply(e1.monadRewritten, '*', e2.monadRewritten); } aspect production divide @@ -1932,14 +1908,14 @@ top::Expr ::= e1::Expr '/' e2::Expr if isMonad(e1.mtyperep, top.env) then if monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst then [] - else [err(top.location, "Can only use " ++ monadToString(top.expectedMonad) ++ + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ " implicitly in this '/', not " ++ monadToString(e1.mtyperep))] else []; top.merrors <- if isMonad(e2.mtyperep, top.env) then if monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst then [] - else [err(top.location, "Can only use " ++ monadToString(top.expectedMonad) ++ + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ " implicitly in this '/', not " ++ monadToString(e2.mtyperep))] else []; @@ -1977,11 +1953,11 @@ top::Expr ::= e1::Expr '/' e2::Expr Silver_Expr { $Expr {monadBind(top.location)} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location), location=top.location)} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} + y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> $Expr {monadBind(top.location)} (y, - \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location), location=top.location)} -> + \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} -> $Expr {monadReturn(top.location)} (x / z))) (_, $Expr {e2UnDec})) }; @@ -1990,8 +1966,8 @@ top::Expr ::= e1::Expr '/' e2::Expr Silver_Expr { $Expr {monadBind(top.location)} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location), location=top.location)} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location))} + y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> $Expr {monadReturn(top.location)} (x / y))(_, $Expr {e2UnDec})) }; @@ -2000,8 +1976,8 @@ top::Expr ::= e1::Expr '/' e2::Expr Silver_Expr { $Expr {monadBind(top.location)} ($Expr {e2UnDec}, - (\x::$TypeExpr {typerepTypeExpr(e1.mtyperep, location=top.location)} - y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(e1.mtyperep)} + y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} -> $Expr {monadReturn(top.location)} (x / y))($Expr {e1UnDec}, _)) }; @@ -2011,7 +1987,7 @@ top::Expr ::= e1::Expr '/' e2::Expr else bind1 else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst then bind2 - else divide(e1.monadRewritten, '/', e2.monadRewritten, location=top.location); + else divide(e1.monadRewritten, '/', e2.monadRewritten); } aspect production modulus @@ -2022,14 +1998,14 @@ top::Expr ::= e1::Expr '%' e2::Expr if isMonad(e1.mtyperep, top.env) then if monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst then [] - else [err(top.location, "Can only use " ++ monadToString(top.expectedMonad) ++ + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ " implicitly in this '%', not " ++ monadToString(e1.mtyperep))] else []; top.merrors <- if isMonad(e2.mtyperep, top.env) then if monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst then [] - else [err(top.location, "Can only use " ++ monadToString(top.expectedMonad) ++ + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ " implicitly in this '%', not " ++ monadToString(e2.mtyperep))] else []; @@ -2067,11 +2043,11 @@ top::Expr ::= e1::Expr '%' e2::Expr Silver_Expr { $Expr {monadBind(top.location)} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location), location=top.location)} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} + y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> $Expr {monadBind(top.location)} (y, - \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location), location=top.location)} -> + \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} -> $Expr {monadReturn(top.location)} (x % z))) (_, $Expr {e2UnDec})) }; @@ -2080,8 +2056,8 @@ top::Expr ::= e1::Expr '%' e2::Expr Silver_Expr { $Expr {monadBind(top.location)} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location), location=top.location)} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location))} + y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> $Expr {monadReturn(top.location)} (x % y))(_, $Expr {e2UnDec})) }; @@ -2090,8 +2066,8 @@ top::Expr ::= e1::Expr '%' e2::Expr Silver_Expr { $Expr {monadBind(top.location)} ($Expr {e2UnDec}, - (\x::$TypeExpr {typerepTypeExpr(e1.mtyperep, location=top.location)} - y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location), location=top.location)} -> + (\x::$TypeExpr {typerepTypeExpr(e1.mtyperep)} + y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} -> $Expr {monadReturn(top.location)} (x % y))($Expr {e1UnDec}, _)) }; @@ -2101,7 +2077,7 @@ top::Expr ::= e1::Expr '%' e2::Expr else bind1 else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst then bind2 - else modulus(e1.monadRewritten, '%', e2.monadRewritten, location=top.location); + else modulus(e1.monadRewritten, '%', e2.monadRewritten); } aspect production neg @@ -2125,10 +2101,10 @@ top::Expr ::= '-' e::Expr then Silver_Expr { $Expr {monadBind(top.location)} ($Expr {eUnDec}, - \x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location), location=top.location)} -> + \x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> $Expr {monadReturn(top.location)}(-x)) } - else neg('-', e.monadRewritten, location=top.location); + else neg('-', e.monadRewritten); } aspect production terminalConstructor @@ -2149,10 +2125,10 @@ top::Expr ::= 'terminal' '(' t::TypeExpr ',' es::Expr ',' el::Expr ')' local ret::Expr = monadReturn(top.location); local esty::TypeExpr = typerepTypeExpr(if isMonad(es.mtyperep, top.env) then es.mtyperep - else monadInnerType(es.mtyperep, top.location), location=top.location); + else monadInnerType(es.mtyperep, top.location)); local elty::TypeExpr = typerepTypeExpr(if isMonad(es.mtyperep, top.env) then es.mtyperep - else monadInnerType(es.mtyperep, top.location), location=top.location); + else monadInnerType(es.mtyperep, top.location)); local bindes::Expr = Silver_Expr { $Expr {bind} @@ -2176,7 +2152,7 @@ top::Expr ::= 'terminal' '(' t::TypeExpr ',' es::Expr ',' el::Expr ')' $Expr {bind} ($Expr {es.monadRewritten}, (\x::$TypeExpr {elty} - y::$TypeExpr {typerepTypeExpr(es.mtyperep, location=top.location)} -> + y::$TypeExpr {typerepTypeExpr(es.mtyperep)} -> $Expr {bind} (y, \z::$TypeExpr {elty} -> @@ -2201,7 +2177,7 @@ top::Expr ::= s::String_t top.mtyperep = stringType(); top.monadicNames = []; - top.monadRewritten = stringConst(s, location=top.location); + top.monadRewritten = stringConst(s); } @@ -2233,7 +2209,7 @@ top::AppExpr ::= '_' { top.merrors := []; propagate mDownSubst, mUpSubst; - top.monadRewritten = missingAppExpr('_', location=top.location); + top.monadRewritten = missingAppExpr('_'); top.realTypes = []; top.monadTypesLocations = []; top.monadicNames = []; @@ -2274,25 +2250,25 @@ top::AppExpr ::= e::Expr if isMonadic then if !errCheck2a.typeerror then [] - else [err(top.location, "Argument " ++ toString(top.appExprIndex+1) ++ " of function '" ++ + else [errFromOrigin(top, "Argument " ++ toString(top.appExprIndex+1) ++ " of function '" ++ top.appExprApplied ++ "' expected " ++ errCheck1a.rightpp ++ " or a monad of " ++ errCheck1a.rightpp ++ " but argument is of type " ++ errCheck1a.leftpp)] else if !errCheck1a.typeerror then [] - else [err(top.location, "Argument " ++ toString(top.appExprIndex+1) ++ " of function '" ++ + else [errFromOrigin(top, "Argument " ++ toString(top.appExprIndex+1) ++ " of function '" ++ top.appExprApplied ++ "' expected " ++ errCheck1a.rightpp ++ " or a monad of " ++ errCheck1a.rightpp ++ " but argument is of type " ++ errCheck1a.leftpp)]; --Functions are not allowed to take monad-typed arguments top.merrors <- if fst(monadsMatch(top.appExprTyperep, top.expectedMonad, top.mDownSubst)) && !top.monadArgumentsAllowed - then [err(top.location, "Implicit equations may not use functions with " ++ + then [errFromOrigin(top, "Implicit equations may not use functions with " ++ "monad-typed arguments, specifically " ++ errCheck2a.rightpp)] else []; - top.monadRewritten = presentAppExpr(e.monadRewritten, location=top.location); + top.monadRewritten = presentAppExpr(e.monadRewritten); } propagate monadArgumentsAllowed, mDownSubst, mUpSubst on AppExprs; @@ -2308,7 +2284,7 @@ top::AppExprs ::= es::AppExprs ',' e::AppExpr top.monadicNames = es.monadicNames ++ e.monadicNames; - top.monadRewritten = snocAppExprs(es.monadRewritten, ',', e.monadRewritten, location=top.location); + top.monadRewritten = snocAppExprs(es.monadRewritten, ',', e.monadRewritten); } aspect production oneAppExprs top::AppExprs ::= e::AppExpr @@ -2321,7 +2297,7 @@ top::AppExprs ::= e::AppExpr top.monadicNames = e.monadicNames; - top.monadRewritten = oneAppExprs(e.monadRewritten, location=top.location); + top.monadRewritten = oneAppExprs(e.monadRewritten); } aspect production emptyAppExprs top::AppExprs ::= @@ -2334,7 +2310,7 @@ top::AppExprs ::= top.monadicNames = []; - top.monadRewritten = emptyAppExprs(location=top.location); + top.monadRewritten = emptyAppExprs(); } propagate monadArgumentsAllowed, mDownSubst, mUpSubst on AnnoAppExprs; @@ -2357,7 +2333,7 @@ top::AnnoExpr ::= qn::QName '=' e::AppExpr e.mDownSubst = top.mDownSubst; top.mUpSubst = e.mUpSubst; - top.monadRewritten = annoExpr(qn, '=', e.monadRewritten, location=top.location); + top.monadRewritten = annoExpr(qn, '=', e.monadRewritten); top.rewrittenArg = e.monadRewritten; } @@ -2373,10 +2349,10 @@ top::AnnoAppExprs ::= es::AnnoAppExprs ',' e::AnnoExpr top.monadicNames = es.monadicNames ++ e.monadicNames; - top.monadRewritten = snocAnnoAppExprs(es.monadRewritten, ',', e.monadRewritten, location=top.location); + top.monadRewritten = snocAnnoAppExprs(es.monadRewritten, ',', e.monadRewritten); es.previousArgs = top.previousArgs; - top.fullArgs = snocAppExprs(es.fullArgs, ',', e.rewrittenArg, location=top.location); + top.fullArgs = snocAppExprs(es.fullArgs, ',', e.rewrittenArg); } aspect production oneAnnoAppExprs @@ -2390,9 +2366,9 @@ top::AnnoAppExprs ::= e::AnnoExpr top.monadicNames = e.monadicNames; - top.monadRewritten = oneAnnoAppExprs(e.monadRewritten, location=top.location); + top.monadRewritten = oneAnnoAppExprs(e.monadRewritten); - top.fullArgs = snocAppExprs(top.previousArgs, ',', e.rewrittenArg, location=top.location); + top.fullArgs = snocAppExprs(top.previousArgs, ',', e.rewrittenArg); } aspect production emptyAnnoAppExprs @@ -2406,7 +2382,7 @@ top::AnnoAppExprs ::= top.monadicNames = []; - top.monadRewritten = emptyAnnoAppExprs(location=top.location); + top.monadRewritten = emptyAnnoAppExprs(); top.fullArgs = top.previousArgs; } diff --git a/grammars/silver/compiler/extension/implicit_monads/Lambda.sv b/grammars/silver/compiler/extension/implicit_monads/Lambda.sv index 52e5ea30f..542a38971 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Lambda.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Lambda.sv @@ -11,7 +11,7 @@ top::Expr ::= params::ProductionRHS e::Expr e.monadicallyUsed = false; top.monadicNames = e.monadicNames; - top.monadRewritten = lambdap(params, e.monadRewritten, location=top.location); + top.monadRewritten = lambdap(params, e.monadRewritten); } @@ -23,7 +23,7 @@ top::Expr ::= q::Decorated! QName propagate mDownSubst, mUpSubst; top.mtyperep = q.lookupValue.typeScheme.monoType; top.monadicNames = if top.monadicallyUsed - then [baseExpr(new(q), location=top.location)] + then [baseExpr(new(q))] else []; - top.monadRewritten = baseExpr(new(q), location=top.location); + top.monadRewritten = baseExpr(new(q)); } diff --git a/grammars/silver/compiler/extension/implicit_monads/Let.sv b/grammars/silver/compiler/extension/implicit_monads/Let.sv index 17c408ebf..e7a870e51 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Let.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Let.sv @@ -52,15 +52,14 @@ top::Expr ::= la::AssignExpr e::Expr -} top.monadRewritten = letp(la.fixedAssigns, - boundIn, - location=top.location); + boundIn); local inside::Expr = if isMonad(ne.mtyperep, top.env) || null(la.bindInList) then ne.monadRewritten else Silver_Expr { $Expr{mreturn}($Expr{ne.monadRewritten}) }; local boundIn::Expr = foldr(\x::Pair y::Expr -> buildApplication(mbind, - [baseExpr(qName(top.location, x.fst.name), location=top.location), + [baseExpr(qName(x.fst.name)), buildLambda(x.fst.name, decorate x.snd with {env=top.env; grammarName=top.grammarName; config=top.config; flowEnv=top.flowEnv;}.typerep, @@ -90,7 +89,7 @@ top::AssignExpr ::= a1::AssignExpr a2::AssignExpr top.bindInList = a1.bindInList ++ a2.bindInList; - top.fixedAssigns = appendAssignExpr(a1.fixedAssigns, a2.fixedAssigns, location=top.location); + top.fixedAssigns = appendAssignExpr(a1.fixedAssigns, a2.fixedAssigns); } aspect production assignExpr @@ -98,7 +97,7 @@ top::AssignExpr ::= id::Name '::' t::TypeExpr '=' e::Expr { top.merrors := e.merrors; top.merrors <- if isMonad(t.typerep, top.env) && fst(monadsMatch(top.expectedMonad, t.typerep, top.mDownSubst)) - then [err(top.location, "Let bindings may not use a monad type")] + then [errFromOrigin(top, "Let bindings may not use a monad type")] else []; local errCheck::TypeCheck = if isMonad(e.mtyperep, top.env) && fst(monadsMatch(e.mtyperep, top.expectedMonad, top.mDownSubst)) then check(t.typerep, monadInnerType(e.mtyperep, top.location)) @@ -115,7 +114,7 @@ top::AssignExpr ::= id::Name '::' t::TypeExpr '=' e::Expr e.monadicallyUsed = isMonad(e.mtyperep, top.env) && fst(monadsMatch(e.mtyperep, top.expectedMonad, top.mDownSubst)) && !isMonad(t.typerep, top.env); top.monadicNames = e.monadicNames; - top.mdefs = [lexicalLocalDef(top.grammarName, id.location, fName, + top.mdefs = [lexicalLocalDef(top.grammarName, id.nameLoc, fName, performSubstitution(t.typerep, top.mUpSubst), e.flowVertexInfo, e.flowDeps, e.uniqueRefs)]; @@ -125,10 +124,9 @@ top::AssignExpr ::= id::Name '::' t::TypeExpr '=' e::Expr top.fixedAssigns = if isMonad(e.mtyperep, top.env) && fst(monadsMatch(e.mtyperep, top.expectedMonad, top.mUpSubst)) --use t.typerep to get typechecking when we create the ultimate monadRewritten - then assignExpr(id, '::', typerepTypeExpr(monadOfType(top.expectedMonad, t.typerep), - location=top.location), - '=', e.monadRewritten, location=top.location) - else assignExpr(id, '::', t, '=', e.monadRewritten, location=top.location); + then assignExpr(id, '::', typerepTypeExpr(monadOfType(top.expectedMonad, t.typerep)), + '=', e.monadRewritten) + else assignExpr(id, '::', t, '=', e.monadRewritten); } @@ -141,7 +139,7 @@ top::Expr ::= q::Decorated! QName _ _ _ propagate mDownSubst, mUpSubst; top.mtyperep = q.lookupValue.typeScheme.monoType; top.monadicNames = if top.monadicallyUsed - then [baseExpr(new(q), location=top.location)] + then [baseExpr(new(q))] else []; - top.monadRewritten = baseExpr(new(q), location=top.location); + top.monadRewritten = baseExpr(new(q)); } diff --git a/grammars/silver/compiler/extension/implicit_monads/PrimitiveMatch.sv b/grammars/silver/compiler/extension/implicit_monads/PrimitiveMatch.sv index 375e2f2c8..76c961f72 100644 --- a/grammars/silver/compiler/extension/implicit_monads/PrimitiveMatch.sv +++ b/grammars/silver/compiler/extension/implicit_monads/PrimitiveMatch.sv @@ -50,7 +50,7 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr top.merrors := e.merrors ++ pr.merrors ++ f.merrors; top.merrors <- if prPattIsMonadic - then [err(top.location, "Cannot match on implicit monadic type " ++ prettyType(pr.patternType))] + then [errFromOrigin(top, "Cannot match on implicit monadic type " ++ prettyType(pr.patternType))] else []; e.mDownSubst = top.mDownSubst; @@ -64,14 +64,14 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr local freshname::String = "__sv_bindingInAMatchExpression_" ++ toString(genInt()); local eBind::Expr = monadBind(top.location); - local eInnerType::TypeExpr = typerepTypeExpr(monadInnerType(e.mtyperep, top.location), location=top.location); + local eInnerType::TypeExpr = typerepTypeExpr(monadInnerType(e.mtyperep, top.location)); local binde_lambdaparams::ProductionRHS = productionRHSCons(productionRHSElem(name(freshname, top.location), '::', - eInnerType, location=top.location), - productionRHSNil(location=top.location), location=top.location); + eInnerType), + productionRHSNil()); --Since we sometimes need to just use pure() over the top of everything to get a -- monad out, we use a fresh type rather than the top.mtyperep - local outty::TypeExpr = typerepTypeExpr(freshType(), location=top.location); + local outty::TypeExpr = typerepTypeExpr(freshType()); {-We need to make sure that, if we are matching on a decorable type, it is decorated. We need to check both whether the type is @@ -87,12 +87,12 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr (!performSubstitution(e.mtyperep, e.mUpSubst).isDecorated && isDecorable(pr.patternType, top.env)); local decName::Expr = if eMTyDecorable - then decorateExprWithEmpty('decorate', baseExpr(qName(top.location, freshname), location=top.location), - 'with', '{', '}', location=top.location) - else baseExpr(qName(top.location, freshname), location=top.location); + then decorateExprWithEmpty('decorate', baseExpr(qName(freshname)), + 'with', '{', '}') + else baseExpr(qName(freshname)); local decE::Expr = if eMTyDecorable - then decorateExprWithEmpty('decorate', e.monadRewritten, 'with', '{', '}', location=top.location) + then decorateExprWithEmpty('decorate', e.monadRewritten, 'with', '{', '}') else e.monadRewritten; --bind e, just do the rest @@ -100,9 +100,7 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr buildApplication(eBind, [e.monadRewritten, lambdap(binde_lambdaparams, matchPrimitiveReal(decName, - outty, pr.monadRewritten, f.monadRewritten, - location=top.location), - location=top.location)], + outty, pr.monadRewritten, f.monadRewritten))], top.location); --bind e, return f based on e's type local bind_e_return_f::Expr = @@ -111,9 +109,7 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr matchPrimitiveReal(decName, outty, pr.monadRewritten, buildApplication(monadReturn(top.location), - [f.monadRewritten], top.location), - location=top.location), - location=top.location)], + [f.monadRewritten], top.location)))], top.location); --bind e, returnify pr based on e's type local prReturnify::PrimPatterns = pr.monadRewritten; @@ -126,8 +122,7 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr [e.monadRewritten, lambdap(binde_lambdaparams, matchPrimitiveReal(decName, outty, prReturnify.returnify, - f.monadRewritten, location=top.location), - location=top.location)], + f.monadRewritten))], top.location); --bind e, returnify pr, return f based on e's type local bind_e_returnify_pr_return_f::Expr = @@ -136,15 +131,12 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr matchPrimitiveReal(decName, outty, prReturnify.returnify, buildApplication(monadReturn(top.location), - [f.monadRewritten], top.location), - location=top.location), - location=top.location)], + [f.monadRewritten], top.location)))], top.location); --return f from pr's return type local return_f::Expr = matchPrimitiveReal(decE, outty, pr.monadRewritten, - buildApplication(monadReturn(top.location), [f.monadRewritten], top.location), - location=top.location); + buildApplication(monadReturn(top.location), [f.monadRewritten], top.location)); --returnify pr from f's type local ret_pr_from_f::PrimPatterns = pr.monadRewritten; ret_pr_from_f.returnFun = monadReturn(top.location); @@ -152,15 +144,15 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr ret_pr_from_f.env = top.env; ret_pr_from_f.config = top.config; local returnify_pr::Expr = matchPrimitiveReal(decE, outty, ret_pr_from_f.returnify, - f.monadRewritten, location=top.location); + f.monadRewritten); --just use monadRewritten local just_rewrite::Expr = matchPrimitiveReal(decE, outty, pr.monadRewritten, - f.monadRewritten, location=top.location); + f.monadRewritten); --t is monadic and nothing else is, so return over whole thing local return_whole_thing::Expr = buildApplication(monadReturn(top.location), [matchPrimitiveReal(decE, outty, pr.monadRewritten, - f.monadRewritten, location=top.location)], + f.monadRewritten)], top.location); --pick the right rewriting local mRw::Expr = @@ -199,8 +191,8 @@ top::PrimPatterns ::= p::PrimPattern top.monadicNames = p.monadicNames; p.returnFun = top.returnFun; - top.returnify = onePattern(p.returnify, location=top.location); - top.monadRewritten = onePattern(p.monadRewritten, location=top.location); + top.returnify = onePattern(p.returnify); + top.monadRewritten = onePattern(p.monadRewritten); } aspect production consPattern top::PrimPatterns ::= p::PrimPattern vbar::Vbar_kwd ps::PrimPatterns @@ -222,11 +214,10 @@ top::PrimPatterns ::= p::PrimPattern vbar::Vbar_kwd ps::PrimPatterns p.returnFun = top.returnFun; ps.returnFun = top.returnFun; - top.returnify = consPattern(p.returnify, terminal(Vbar_kwd, "|"), ps.returnify, location=top.location); + top.returnify = consPattern(p.returnify, terminal(Vbar_kwd, "|"), ps.returnify); --when both are monads or both aren't, so we don't need to change anything - local basicRewritten::PrimPatterns = consPattern(p.monadRewritten, terminal(Vbar_kwd, "|"), ps.monadRewritten, - location=top.location); + local basicRewritten::PrimPatterns = consPattern(p.monadRewritten, terminal(Vbar_kwd, "|"), ps.monadRewritten); --when the current clause is a monad but the rest aren't, wrap all of them in Return() local psReturnify::PrimPatterns = ps.monadRewritten; psReturnify.returnFun = monadReturn(top.location); @@ -234,8 +225,7 @@ top::PrimPatterns ::= p::PrimPattern vbar::Vbar_kwd ps::PrimPatterns psReturnify.config = top.config; psReturnify.grammarName = top.grammarName; local returnifyRewritten::PrimPatterns = consPattern(p.monadRewritten, terminal(Vbar_kwd, "|"), - psReturnify.returnify, - location=top.location); + psReturnify.returnify); --when the current clause is not a monad but the rest are, wrap the current one in Return() local pReturnify::PrimPattern = p.monadRewritten; pReturnify.returnFun = monadReturn(top.location); @@ -243,8 +233,7 @@ top::PrimPatterns ::= p::PrimPattern vbar::Vbar_kwd ps::PrimPatterns pReturnify.config = top.config; pReturnify.env = top.env; local returnRewritten::PrimPatterns = consPattern(pReturnify.returnify, terminal(Vbar_kwd, "|"), - ps.monadRewritten, - location=top.location); + ps.monadRewritten); top.monadRewritten = if isMonad(p.mtyperep, top.env) && monadsMatch(p.mtyperep, top.expectedMonad, top.mDownSubst).fst then if isMonad(ps.mtyperep, top.env) && monadsMatch(ps.mtyperep, top.expectedMonad, top.mDownSubst).fst then basicRewritten --both monads @@ -291,9 +280,8 @@ top::PrimPattern ::= qn::Decorated QName ns::VarBinders e::Expr top.patternType = prod_type.outputType; top.returnify = prodPatternNormal(qn, ns, - Silver_Expr { $Expr{top.returnFun}($Expr{e}) }, - location=top.location); - top.monadRewritten = prodPatternNormal(qn, ns, e.monadRewritten, location=top.location); + Silver_Expr { $Expr{top.returnFun}($Expr{e}) }); + top.monadRewritten = prodPatternNormal(qn, ns, e.monadRewritten); } aspect production prodPatternGadt @@ -309,9 +297,8 @@ top::PrimPattern ::= qn::Decorated QName ns::VarBinders e::Expr top.patternType = prod_type.outputType; top.returnify = prodPatternGadt(qn, ns, - Silver_Expr { $Expr{top.returnFun}($Expr{e}) }, - location=top.location); - top.monadRewritten = prodPatternGadt(qn, ns, e.monadRewritten, location=top.location); + Silver_Expr { $Expr{top.returnFun}($Expr{e}) }); + top.monadRewritten = prodPatternGadt(qn, ns, e.monadRewritten); } @@ -329,9 +316,8 @@ top::PrimPattern ::= i::Int_t arr::Arrow_kwd e::Expr top.patternType = intType(); top.returnify = integerPattern(i, terminal(Arrow_kwd, "->"), - Silver_Expr { $Expr{top.returnFun}($Expr{e}) }, - location=top.location); - top.monadRewritten = integerPattern(i, terminal(Arrow_kwd, "->"), e.monadRewritten, location=top.location); + Silver_Expr { $Expr{top.returnFun}($Expr{e}) }); + top.monadRewritten = integerPattern(i, terminal(Arrow_kwd, "->"), e.monadRewritten); } aspect production floatPattern top::PrimPattern ::= f::Float_t arr::Arrow_kwd e::Expr @@ -346,9 +332,8 @@ top::PrimPattern ::= f::Float_t arr::Arrow_kwd e::Expr top.patternType = floatType(); top.returnify = floatPattern(f, terminal(Arrow_kwd, "->"), - Silver_Expr { $Expr{top.returnFun}($Expr{e}) }, - location=top.location); - top.monadRewritten = floatPattern(f, terminal(Arrow_kwd, "->"), e.monadRewritten, location=top.location); + Silver_Expr { $Expr{top.returnFun}($Expr{e}) }); + top.monadRewritten = floatPattern(f, terminal(Arrow_kwd, "->"), e.monadRewritten); } aspect production stringPattern top::PrimPattern ::= i::String_t arr::Arrow_kwd e::Expr @@ -363,9 +348,8 @@ top::PrimPattern ::= i::String_t arr::Arrow_kwd e::Expr top.patternType = stringType(); top.returnify = stringPattern(i, terminal(Arrow_kwd, "->"), - Silver_Expr { $Expr{top.returnFun}($Expr{e}) }, - location=top.location); - top.monadRewritten = stringPattern(i, terminal(Arrow_kwd, "->"), e.monadRewritten, location=top.location); + Silver_Expr { $Expr{top.returnFun}($Expr{e}) }); + top.monadRewritten = stringPattern(i, terminal(Arrow_kwd, "->"), e.monadRewritten); } aspect production booleanPattern top::PrimPattern ::= i::String arr::Arrow_kwd e::Expr @@ -380,9 +364,8 @@ top::PrimPattern ::= i::String arr::Arrow_kwd e::Expr top.patternType = stringType(); top.returnify = booleanPattern(i, terminal(Arrow_kwd, "->"), - Silver_Expr { $Expr{top.returnFun}($Expr{e}) }, - location=top.location); - top.monadRewritten = booleanPattern(i, terminal(Arrow_kwd, "->"), e.monadRewritten, location=top.location); + Silver_Expr { $Expr{top.returnFun}($Expr{e}) }); + top.monadRewritten = booleanPattern(i, terminal(Arrow_kwd, "->"), e.monadRewritten); } aspect production nilPattern top::PrimPattern ::= e::Expr @@ -397,9 +380,8 @@ top::PrimPattern ::= e::Expr local attribute thisListType::Type = listType(freshType()); top.patternType = thisListType; - top.returnify = nilPattern(Silver_Expr { $Expr{top.returnFun}($Expr{e}) }, - location=top.location); - top.monadRewritten = nilPattern(e.monadRewritten, location=top.location); + top.returnify = nilPattern(Silver_Expr { $Expr{top.returnFun}($Expr{e}) }); + top.monadRewritten = nilPattern(e.monadRewritten); } aspect production conslstPattern top::PrimPattern ::= h::Name t::Name e::Expr @@ -414,9 +396,8 @@ top::PrimPattern ::= h::Name t::Name e::Expr local elemType :: Type = freshType(); top.patternType = listType(elemType); - top.returnify = conslstPattern(h, t, Silver_Expr { $Expr{top.returnFun}($Expr{e}) }, - location=top.location); - top.monadRewritten = conslstPattern(h, t, e.monadRewritten, location=top.location); + top.returnify = conslstPattern(h, t, Silver_Expr { $Expr{top.returnFun}($Expr{e}) }); + top.monadRewritten = conslstPattern(h, t, e.monadRewritten); } diff --git a/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv b/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv index 8dcfc4e60..5111a47f7 100644 --- a/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv +++ b/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv @@ -26,14 +26,14 @@ top::ProductionStmt ::= 'implicit' dl::DefLHS '.' attr::QNameAttrOccur '=' ';' local merrors::[Message] = (if isMonadFail(attr.typerep, top.env) then [] - else [err(top.location, monadToString(attr.typerep) ++ + else [errFromOrigin(top, monadToString(attr.typerep) ++ " is not an instance of MonadFail and cannot " ++ "be used in an empty equation")]) ++ ( if attr.found && dl.found then case attr.attrDcl of | implicitInhDcl(_, _, _) -> [] | implicitSynDcl(_, _, _) -> [] - | _ -> [err(top.location, "Implicit equations can only be used for " ++ + | _ -> [errFromOrigin(top, "Implicit equations can only be used for " ++ "attributes declared to be implicit; " ++ attr.unparse ++ " is not implicit")] end @@ -45,13 +45,13 @@ top::ProductionStmt ::= 'implicit' dl::DefLHS '.' attr::QNameAttrOccur '=' ';' forwards to if null(merrors) then attr.attrDcl.attrDefDispatcher(dl, attr, monadFail(top.location), top.location) - else errorProductionStmt(merrors, location=top.location); + else errorProductionStmt(merrors); } -global partialDefaultAttributeDef::(ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr Location) = +global partialDefaultAttributeDef::(ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr) = \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr loc::Location -> - attributeDef(newUnique(dl), '.', newUnique(attr), '=', e, ';', location=loc); + attributeDef(newUnique(dl), '.', newUnique(attr), '=', e, ';'); concrete production implicitAttributeDef top::ProductionStmt ::= 'implicit' dl::DefLHS '.' attr::QNameAttrOccur '=' e::Expr ';' @@ -72,7 +72,7 @@ top::ProductionStmt ::= 'implicit' dl::DefLHS '.' attr::QNameAttrOccur '=' e::Ex then case attr.attrDcl of | implicitSynDcl(_, _, _) -> [] | implicitInhDcl(_, _, _) -> [] - | _ -> [err(top.location, "Implicit equations can only be used for " ++ + | _ -> [errFromOrigin(top, "Implicit equations can only be used for " ++ "attributes declared to be implicit; " ++ attr.unparse ++ " is not implicit")] end @@ -87,7 +87,7 @@ top::ProductionStmt ::= 'implicit' dl::DefLHS '.' attr::QNameAttrOccur '=' e::Ex then attr.attrDcl.attrDefDispatcher --if not found, let the normal dispatcher handle it else partialDefaultAttributeDef - else errorAttributeDef(merrors, _, _, _, location=_))(dl, attr, e, top.location); + else errorAttributeDef(merrors, _, _, _))(dl, attr, e, top.location); } @@ -113,7 +113,7 @@ top::ProductionStmt ::= 'restricted' dl::DefLHS '.' attr::QNameAttrOccur '=' e:: then case attr.attrDcl of | restrictedSynDcl(_, _, _) -> [] | restrictedInhDcl(_, _, _) -> [] - | _ -> [err(top.location, "Restricted equations can only be used for " ++ + | _ -> [errFromOrigin(top, "Restricted equations can only be used for " ++ "attributes declared to be restricted; " ++ attr.unparse ++ " is not restricted")] end @@ -128,7 +128,7 @@ top::ProductionStmt ::= 'restricted' dl::DefLHS '.' attr::QNameAttrOccur '=' e:: then attr.attrDcl.attrDefDispatcher --if not found, let the normal dispatcher handle it else partialDefaultAttributeDef - else errorAttributeDef(merrors, _, _, _, location=_))(dl, attr, e, top.location); + else errorAttributeDef(merrors, _, _, _))(dl, attr, e, top.location); } @@ -152,20 +152,20 @@ top::ProductionStmt ::= 'unrestricted' dl::DefLHS '.' attr::QNameAttrOccur '=' e top.containsPluck = false; local restrictedErr::[Message] = - [err(top.location, + [errFromOrigin(top, "Unrestricted equations can only be used for attributes " ++ "not declared to be restricted or implicit; " ++ attr.unparse ++ " is restricted")]; local implicitErr::[Message] = - [err(top.location, + [errFromOrigin(top, "Unrestricted equations can only be used for attributes " ++ "not declared to be restricted or implicit; " ++ attr.unparse ++ " is implicit")]; forwards to (if attr.found then case attr.attrDcl of - | restrictedSynDcl(_, _, _) -> errorAttributeDef(restrictedErr, _, _, _, location=_) - | restrictedInhDcl(_, _, _) -> errorAttributeDef(restrictedErr, _, _, _, location=_) - | implicitSynDcl(_, _, _) -> errorAttributeDef(implicitErr, _, _, _, location=_) - | implicitInhDcl(_, _, _) -> errorAttributeDef(implicitErr, _, _, _, location=_) + | restrictedSynDcl(_, _, _) -> errorAttributeDef(restrictedErr, _, _, _) + | restrictedInhDcl(_, _, _) -> errorAttributeDef(restrictedErr, _, _, _) + | implicitSynDcl(_, _, _) -> errorAttributeDef(implicitErr, _, _, _) + | implicitInhDcl(_, _, _) -> errorAttributeDef(implicitErr, _, _, _) | _ -> partialDefaultAttributeDef end --if not found, let the normal dispatcher handle it @@ -195,7 +195,7 @@ function buildExplicitAttrErrors abstract production restrictedSynAttributeDef top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr { - undecorates to attributeDef(dl, '.', attr, '=', e, ';', location=top.location); + undecorates to attributeDef(dl, '.', attr, '=', e, ';'); top.unparse = dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; propagate grammarName, compiledGrammars, config, frame, env, flowEnv, finalSubst, originRules; @@ -214,15 +214,15 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e: forwards to (if null(merrors) - then synthesizedAttributeDef(_, _, _, location=_) - else errorAttributeDef(merrors, _, _, _, location=_))(dl, attr, e, top.location); + then synthesizedAttributeDef(_, _, _) + else errorAttributeDef(merrors, _, _, _))(dl, attr, e, top.location); } abstract production restrictedInhAttributeDef top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr { - undecorates to attributeDef(dl, '.', attr, '=', e, ';', location=top.location); + undecorates to attributeDef(dl, '.', attr, '=', e, ';'); top.unparse = dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; propagate grammarName, compiledGrammars, config, frame, env, flowEnv, finalSubst, originRules; @@ -241,8 +241,8 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e: forwards to (if null(merrors) - then inheritedAttributeDef(_, _, _, location=_) - else errorAttributeDef(merrors, _, _, _, location=_))(dl, attr, e, top.location); + then inheritedAttributeDef(_, _, _) + else errorAttributeDef(merrors, _, _, _))(dl, attr, e, top.location); } @@ -252,7 +252,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e: abstract production implicitSynAttributeDef top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr { - undecorates to attributeDef(dl, '.', attr, '=', e, ';', location=top.location); + undecorates to attributeDef(dl, '.', attr, '=', e, ';'); top.unparse = dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; propagate grammarName, compiledGrammars, config, frame, env, flowEnv, originRules; @@ -272,19 +272,19 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e: forwards to (if null(e.merrors) then if fst(monadsMatch(attr.typerep, e.mtyperep, e.mUpSubst)) - then synthesizedAttributeDef(_, _, e.monadRewritten, location=_) + then synthesizedAttributeDef(_, _, e.monadRewritten) else synthesizedAttributeDef(_, _, Silver_Expr { $Expr {monadReturn(top.location)} ($Expr {e.monadRewritten}) - }, location=_) - else errorAttributeDef(e.merrors, _, _, e.monadRewritten, location=_))(dl, attr, top.location); + }) + else errorAttributeDef(e.merrors, _, _, e.monadRewritten))(dl, attr, top.location); } abstract production implicitInhAttributeDef top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr { - undecorates to attributeDef(dl, '.', attr, '=', e, ';', location=top.location); + undecorates to attributeDef(dl, '.', attr, '=', e, ';'); top.unparse = dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; propagate grammarName, compiledGrammars, config, frame, env, flowEnv, originRules; @@ -304,11 +304,11 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e: forwards to (if null(e.merrors) then if fst(monadsMatch(attr.typerep, e.mtyperep, e.mUpSubst)) - then inheritedAttributeDef(_, _, e.monadRewritten, location=_) + then inheritedAttributeDef(_, _, e.monadRewritten) else inheritedAttributeDef(_, _, Silver_Expr { $Expr {monadReturn(top.location)} ($Expr {e.monadRewritten}) - }, location=_) - else errorAttributeDef(e.merrors, _, _, e.monadRewritten, location=_))(dl, attr, top.location); + }) + else errorAttributeDef(e.merrors, _, _, e.monadRewritten))(dl, attr, top.location); } diff --git a/grammars/silver/compiler/extension/implicit_monads/Util.sv b/grammars/silver/compiler/extension/implicit_monads/Util.sv index b65a9b5f7..4c3727d95 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Util.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Util.sv @@ -154,12 +154,12 @@ String ::= ty::Type function monadBind Expr ::= l::Location { - return baseExpr(qNameId(name("silver:core:bind", l), location=l), location=l); + return baseExpr(qNameId(name("silver:core:bind", l))); } function monadReturn Expr ::= l::Location { - return baseExpr(qNameId(name("silver:core:pure", l), location=l), location=l); + return baseExpr(qNameId(name("silver:core:pure", l))); } --We want to produce a value, not a function, so we apply it to an argument @@ -168,7 +168,7 @@ Expr ::= l::Location { return buildApplication - (baseExpr(qNameId(name("silver:core:fail", l), location=l), location=l), + (baseExpr(qNameId(name("silver:core:fail", l))), [stringConst(terminal(String_t, "\"Automatically-inserted fail at " ++ l.unparse ++ "\""), location=l)], l); @@ -178,12 +178,12 @@ Expr ::= l::Location function monadPlus Expr ::= l::Location { - return baseExpr(qNameId(name("silver:core:alt", l), location=l), location=l); + return baseExpr(qNameId(name("silver:core:alt", l))); } function monadZero Expr ::= l::Location { - return baseExpr(qNameId(name("silver:core:empty", l), location=l), location=l); + return baseExpr(qNameId(name("silver:core:empty", l))); } @@ -199,7 +199,7 @@ Expr ::= l::Location function buildApplication Expr ::= fun::Expr args::[Expr] loc::Location { - return applicationExpr(fun, '(', buildApplicationReverseArgs(reverse(args), loc), ')', location=loc); + return applicationExpr(fun, '(', buildApplicationReverseArgs(reverse(args), loc), ')'); } --because the AST is set up as a snoc list, we build the arguments in reverse @@ -208,10 +208,10 @@ function buildApplicationReverseArgs AppExprs ::= args::[Expr] loc::Location { return case args of - | [] -> emptyAppExprs(location=loc) + | [] -> emptyAppExprs() | hd::tl -> snocAppExprs(buildApplicationReverseArgs(tl, loc), ',', - presentAppExpr(hd, location=loc), location=loc) + presentAppExpr(hd)) end; } @@ -224,12 +224,9 @@ Expr ::= n::String ty::Type body::Expr loc::Location return lambdap( productionRHSCons(productionRHSElem(name(n, loc), '::', - typerepTypeExpr(ty, location=loc), - location=loc), - productionRHSNil(location=loc), - location=loc), - body, - location=loc); + typerepTypeExpr(ty)), + productionRHSNil()), + body); } @@ -241,10 +238,10 @@ Expr ::= names::[Pair] body::Expr loc::Location case pr of | (n, ty) -> productionRHSCons(productionRHSElem(name(n, loc), '::', - typerepTypeExpr(ty, location=loc), location=loc), - p, location=loc) + typerepTypeExpr(ty)), + p) end, - productionRHSNil(location=loc), names); - return lambdap(sig, body, location=loc); + productionRHSNil(), names); + return lambdap(sig, body); } diff --git a/grammars/silver/compiler/extension/patternmatching/Case.sv b/grammars/silver/compiler/extension/patternmatching/Case.sv index 171850119..ef7133135 100644 --- a/grammars/silver/compiler/extension/patternmatching/Case.sv +++ b/grammars/silver/compiler/extension/patternmatching/Case.sv @@ -26,7 +26,7 @@ terminal When_kwd 'when' lexer classes {KEYWORD,RESERVED}; terminal Matches_kwd 'matches' lexer classes {KEYWORD}; -- MR | ... -nonterminal MRuleList with location, config, unparse, env, frame, errors, freeVars, matchRuleList, matchRulePatternSize; +tracked nonterminal MRuleList with config, unparse, env, frame, errors, freeVars, matchRuleList, matchRulePatternSize; propagate config, frame, env, errors, freeVars, matchRulePatternSize on MRuleList; -- Turns MRuleList (of MatchRules) into [AbstractMatchRule] @@ -35,8 +35,8 @@ synthesized attribute matchRuleList :: [AbstractMatchRule]; inherited attribute matchRulePatternSize :: Integer; -- P -> E -nonterminal MatchRule with location, config, unparse, env, frame, errors, freeVars, matchRuleList, matchRulePatternSize; -nonterminal AbstractMatchRule with location, unparse, frame, freeVars, headPattern, isVarMatchRule, expandHeadPattern, hasCondition; +tracked nonterminal MatchRule with config, unparse, env, frame, errors, freeVars, matchRuleList, matchRulePatternSize; +tracked nonterminal AbstractMatchRule with unparse, frame, freeVars, headPattern, isVarMatchRule, expandHeadPattern, hasCondition; -- The head pattern of a match rule synthesized attribute headPattern :: Decorated Pattern; @@ -48,7 +48,7 @@ synthesized attribute expandHeadPattern :: (AbstractMatchRule ::= [String]); synthesized attribute hasCondition::Boolean; -- P , ... -nonterminal PatternList with location, config, unparse, patternList, env, frame, errors, patternVars, patternVarEnv; +tracked nonterminal PatternList with config, unparse, patternList, env, frame, errors, patternVars, patternVarEnv; propagate config, frame, env, errors on PatternList; -- Turns PatternList into [Pattern] @@ -83,8 +83,8 @@ top::Expr ::= 'case' es::Exprs 'of' Opt_Vbar_t ml::MRuleList 'end' caseExpr(es.rawExprs, ml.matchRuleList, true, mkStrFunctionInvocation(top.location, "silver:core:error", [stringConst(terminal(String_t, - "\"Error: pattern match failed at " ++ top.grammarName ++ " " ++ top.location.unparse ++ "\\n\""), location=top.location)]), - freshType(), location=top.location); + "\"Error: pattern match failed at " ++ top.grammarName ++ " " ++ top.location.unparse ++ "\\n\""))]), + freshType()); } @@ -307,7 +307,7 @@ Expr ::= es::[Expr] ml::[AbstractMatchRule] failExpr::Expr retType::Type | matchRule(_, nothing(), e) -> e --cond is a Boolean | matchRule(_, just((cond, nothing())), e) -> - ifThenElse('if', cond, 'then', e, 'else', rest, location=loc) + ifThenElse('if', cond, 'then', e, 'else', rest) --cond is the expression for another match | matchRule(_, just((cond, just(patt))), e) -> Silver_Expr { @@ -361,13 +361,13 @@ Expr ::= matchEs::[Expr] ruleGroups::[[AbstractMatchRule]] finalFail::Expr local constructorGroups::[[AbstractMatchRule]] = groupMRules(firstGroup); local mappedPatterns::[PrimPattern] = map(allConCaseTransform(head(matchEs), tail(matchEs), - baseExpr(qName(loc, failName), location=loc), + baseExpr(qName(failName)), retType, _, env), constructorGroups); local currentConCase::Expr = - matchPrimitive(firstMatchExpr, typerepTypeExpr(retType, location=loc), + matchPrimitive(firstMatchExpr, typerepTypeExpr(retType), foldPrimPatterns(mappedPatterns), - baseExpr(qName(loc, failName), location=loc), location=loc); + baseExpr(qName(failName))); -- A quick note about that freshType() hack: putting it here means there's ONE fresh type -- generated, puching it inside 'bindHeadPattern' would generate multiple fresh types. @@ -376,7 +376,7 @@ Expr ::= matchEs::[Expr] ruleGroups::[[AbstractMatchRule]] finalFail::Expr map(bindHeadPattern(firstMatchExpr, freshType(), _), firstGroup); local currentVarCase::Expr = compileCaseExpr(tail(matchEs), boundVarRules, - baseExpr(qName(loc, failName), location=loc), + baseExpr(qName(failName)), retType, loc, env); local bindFailName::Expr = @@ -420,7 +420,7 @@ PrimPattern ::= currExpr::Expr restExprs::[Expr] failCase::Expr local annos :: [String] = nub(map(fst, flatMap((.patternNamedSubPatternList), map((.headPattern), mrs)))); local annoAccesses :: [Expr] = - map(\ n::String -> access(currExpr, '.', qNameAttrOccur(qName(l, n), location=l), location=l), annos); + map(\ n::String -> access(currExpr, '.', qNameAttrOccur(qName(n))), annos); -- Maybe this one is more reasonable? We need to test examples and see what happens... local l :: Location = head(mrs).headPattern.location; @@ -428,14 +428,14 @@ PrimPattern ::= currExpr::Expr restExprs::[Expr] failCase::Expr return case head(mrs).headPattern of | prodAppPattern_named(qn,_,_,_,_,_) -> - prodPattern(qn, '(', convStringsToVarBinders(names, l), ')', '->', subcase, location=l) - | intPattern(it) -> integerPattern(it, '->', subcase, location=l) - | fltPattern(it) -> floatPattern(it, '->', subcase, location=l) - | strPattern(it) -> stringPattern(it, '->', subcase, location=l) - | truePattern(_) -> booleanPattern("true", '->', subcase, location=l) - | falsePattern(_) -> booleanPattern("false", '->', subcase, location=l) - | nilListPattern(_,_) -> nilPattern(subcase, location=l) - | consListPattern(h,_,t) -> conslstPattern(head(names), head(tail(names)), subcase, location=l) + prodPattern(qn, '(', convStringsToVarBinders(names, l), ')', '->', subcase) + | intPattern(it) -> integerPattern(it, '->', subcase) + | fltPattern(it) -> floatPattern(it, '->', subcase) + | strPattern(it) -> stringPattern(it, '->', subcase) + | truePattern(_) -> booleanPattern("true", '->', subcase) + | falsePattern(_) -> booleanPattern("false", '->', subcase) + | nilListPattern(_,_) -> nilPattern(subcase) + | consListPattern(h,_,t) -> conslstPattern(head(names), head(tail(names)), subcase) | _ -> error("Can only have constructor patterns in allConCaseTransform: " ++ head(mrs).headPattern.unparse) end; } @@ -534,7 +534,7 @@ function allConCaseCheckOverlapping local annos :: [String] = nub(map(fst, flatMap((.patternNamedSubPatternList), map((.headPattern), mrs)))); local annoAccesses :: [Expr] = - map(\ n::String -> access(head(es), '.', qNameAttrOccur(qName(l, n), location=l), location=l), annos); + map(\ n::String -> access(head(es), '.', qNameAttrOccur(qName(n))), annos); local subCaseCheck::[Message] = checkOverlappingPatterns( @@ -1065,11 +1065,11 @@ top::MatchRule ::= pt::PatternList '->' e::Expr top.errors <- if length(pt.patternList) == top.matchRulePatternSize then [] - else [err(pt.location, "case expression matching against " ++ toString(top.matchRulePatternSize) ++ " values, but this rule has " ++ toString(length(pt.patternList)) ++ " patterns")]; + else [errFromOrigin(pt, "case expression matching against " ++ toString(top.matchRulePatternSize) ++ " values, but this rule has " ++ toString(length(pt.patternList)) ++ " patterns")]; pt.patternVarEnv = []; - top.matchRuleList = [matchRule(pt.patternList, nothing(), e, location=top.location)]; + top.matchRuleList = [matchRule(pt.patternList, nothing(), e)]; } concrete production matchRuleWhen_c @@ -1083,11 +1083,11 @@ top::MatchRule ::= pt::PatternList 'when' cond::Expr '->' e::Expr top.errors <- if length(pt.patternList) == top.matchRulePatternSize then [] - else [err(pt.location, "case expression matching against " ++ toString(top.matchRulePatternSize) ++ " values, but this rule has " ++ toString(length(pt.patternList)) ++ " patterns")]; + else [errFromOrigin(pt, "case expression matching against " ++ toString(top.matchRulePatternSize) ++ " values, but this rule has " ++ toString(length(pt.patternList)) ++ " patterns")]; pt.patternVarEnv = []; - top.matchRuleList = [matchRule(pt.patternList, just((cond, nothing())), e, location=top.location)]; + top.matchRuleList = [matchRule(pt.patternList, just((cond, nothing())), e)]; } concrete production matchRuleWhenMatches_c @@ -1101,12 +1101,12 @@ top::MatchRule ::= pt::PatternList 'when' cond::Expr 'matches' p::Pattern '->' e top.errors <- if length(pt.patternList) == top.matchRulePatternSize then [] - else [err(pt.location, "case expression matching against " ++ toString(top.matchRulePatternSize) ++ " values, but this rule has " ++ toString(length(pt.patternList)) ++ " patterns")]; + else [errFromOrigin(pt, "case expression matching against " ++ toString(top.matchRulePatternSize) ++ " values, but this rule has " ++ toString(length(pt.patternList)) ++ " patterns")]; pt.patternVarEnv = []; p.patternVarEnv = pt.patternVars; - top.matchRuleList = [matchRule(pt.patternList, just((cond, just(p))), e, location=top.location)]; + top.matchRuleList = [matchRule(pt.patternList, just((cond, just(p))), e)]; } abstract production matchRule @@ -1142,12 +1142,12 @@ top::AbstractMatchRule ::= pl::[Decorated Pattern] map( \ n::String -> fromMaybe( - decorate wildcPattern('_', location=top.location) + decorate wildcPattern('_') with { frame = head(pl).frame; config=head(pl).config; env=head(pl).env; patternVarEnv = []; }, lookup(n, head(pl).patternNamedSubPatternList)), named) ++ tail(pl), - cond, e, location=top.location); + cond, e); top.hasCondition = cond.isJust; } @@ -1167,7 +1167,7 @@ top::PatternList ::= ps::PatternList ',' p::Pattern { top.unparse = ps.unparse ++ ", " ++ p.unparse; - forwards to appendPatternList(ps, patternList_one(p, location=p.location)); + forwards to appendPatternList(ps, patternList_one(p)); } abstract production patternList_more top::PatternList ::= p::Pattern ',' ps1::PatternList @@ -1200,9 +1200,9 @@ PatternList ::= p1::PatternList p2::PatternList return case p1 of | patternList_more(h, _, t) -> - patternList_more(h, ',', appendPatternList(t, p2), location=p1.location) + patternList_more(h, ',', appendPatternList(t, p2)) | patternList_one(h) -> - patternList_more(h, ',', p2, location=p1.location) + patternList_more(h, ',', p2) | patternList_nil() -> p2 end; } @@ -1220,14 +1220,14 @@ Name ::= p::Decorated Pattern function convStringsToVarBinders VarBinders ::= s::[Name] l::Location { - return if null(s) then nilVarBinder(location=l) - else if null(tail(s)) then oneVarBinder(varVarBinder(head(s), location=head(s).location), location=l) - else consVarBinder(varVarBinder(head(s), location=head(s).location), ',', convStringsToVarBinders(tail(s), l), location=l); + return if null(s) then nilVarBinder() + else if null(tail(s)) then oneVarBinder(varVarBinder(head(s), location=head(s).location)) + else consVarBinder(varVarBinder(head(s), location=head(s).location), ',', convStringsToVarBinders(tail(s), l)); } function exprFromName Expr ::= n::Name { - return baseExpr(qNameId(n, location=n.location), location=n.location); + return baseExpr(qNameId(n)); } function foldPrimPatterns @@ -1260,9 +1260,8 @@ AbstractMatchRule ::= headExpr::Expr headType::Type absRule::AbstractMatchRule | just((c, p)) -> just((makeLet(absRule.location, pvn, headType, headExpr, c), p)) | nothing() -> nothing() end, - makeLet(absRule.location, pvn, headType, headExpr, e), - location=absRule.location) - | nothing() -> matchRule(restPat, cond, e, location=absRule.location) + makeLet(absRule.location, pvn, headType, headExpr, e)) + | nothing() -> matchRule(restPat, cond, e) end | r -> r -- Don't crash when we see a rule with too few patterns (should be an error) end; @@ -1276,7 +1275,7 @@ AbstractMatchRule ::= absRule::AbstractMatchRule { return case absRule of | matchRule(headPat :: restPat, cond, e) -> - matchRule(restPat, cond, e, location=absRule.location) + matchRule(restPat, cond, e) | r -> r -- Don't crash when we see a rule with too few patterns (should be an error) end; } @@ -1286,8 +1285,8 @@ Expr ::= l::Location s::String t::Type e::Expr o::Expr { return letp( assignExpr( - name(s, l), '::', typerepTypeExpr(t, location=l), '=', e, location=l), - o, location=l); + name(s, l), '::', typerepTypeExpr(t), '=', e), + o); } instance Eq AbstractMatchRule { diff --git a/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv b/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv index 1f74d87f2..9d1d7c4f0 100644 --- a/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv +++ b/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv @@ -5,7 +5,7 @@ import silver:compiler:modification:list only LSqr_t, RSqr_t; {-- - The forms of syntactic patterns that are permissible in (nested) case expresssions. -} -nonterminal Pattern with location, config, unparse, env, frame, errors, patternVars, patternVarEnv, patternIsVariable, patternVariableName, patternSubPatternList, patternNamedSubPatternList, patternSortKey, isPrimitivePattern, isBoolPattern, isListPattern, patternTypeName; +tracked nonterminal Pattern with config, unparse, env, frame, errors, patternVars, patternVarEnv, patternIsVariable, patternVariableName, patternSubPatternList, patternNamedSubPatternList, patternSortKey, isPrimitivePattern, isBoolPattern, isListPattern, patternTypeName; propagate config, frame, env, errors on Pattern; {-- @@ -76,7 +76,7 @@ top::Pattern ::= prod::QName '(' ps::PatternList ',' nps::NamedPatternList ')' top.errors <- if null(prod.lookupValue.dcls) || length(ps.patternList) == parms then [] - else [err(prod.location, prod.name ++ " has " ++ toString(parms) ++ " parameters but " ++ toString(length(ps.patternList)) ++ " patterns were provided")]; + else [errFromOrigin(prod, prod.name ++ " has " ++ toString(parms) ++ " parameters but " ++ toString(length(ps.patternList)) ++ " patterns were provided")]; top.patternVars = ps.patternVars ++ nps.patternVars; ps.patternVarEnv = top.patternVarEnv; @@ -97,13 +97,13 @@ top::Pattern ::= prod::QName '(' ps::PatternList ',' nps::NamedPatternList ')' concrete production prodAppPattern top::Pattern ::= prod::QName '(' ps::PatternList ')' { - forwards to prodAppPattern_named(prod, '(', ps, ',', namedPatternList_nil(location=top.location), ')', location=top.location); + forwards to prodAppPattern_named(prod, '(', ps, ',', namedPatternList_nil(), ')'); } concrete production propAppPattern_onlyNamed top::Pattern ::= prod::QName '(' nps::NamedPatternList ')' { - forwards to prodAppPattern_named(prod, '(', patternList_nil(location=top.location), ',', nps, ')', location=top.location); + forwards to prodAppPattern_named(prod, '(', patternList_nil(), ',', nps, ')'); } {-- @@ -138,16 +138,16 @@ top::Pattern ::= v::Name top.unparse = v.name; top.errors <- if contains(v.name, top.patternVarEnv) - then [err(v.location, "Duplicate pattern variable " ++ v.name)] + then [errFromOrigin(v, "Duplicate pattern variable " ++ v.name)] else []; top.errors <- if isUpper(substring(0,1,v.name)) - then [err(v.location, "Pattern variable names start with a lower case letter")] + then [errFromOrigin(v, "Pattern variable names start with a lower case letter")] else []; top.errors <- case getValueDcl(v.name, top.env) of | prodDcl(_,_) :: _ -> - [err(v.location, "Pattern variables should not share the name of a production. (Potential confusion between '" ++ v.name ++ "' and '" ++ v.name ++ "()')")] + [errFromOrigin(v, "Pattern variables should not share the name of a production. (Potential confusion between '" ++ v.name ++ "' and '" ++ v.name ++ "()')")] | _ -> [] end; @@ -322,22 +322,22 @@ aspect production patternList_one top::PatternList ::= p::Pattern { top.asListPattern = - consListPattern(p, '::', nilListPattern('[', ']', location=top.location), location=top.location); + consListPattern(p, '::', nilListPattern('[', ']')); } aspect production patternList_more top::PatternList ::= p::Pattern ',' ps1::PatternList { - top.asListPattern = consListPattern(p, '::', ps1.asListPattern, location=top.location); + top.asListPattern = consListPattern(p, '::', ps1.asListPattern); } aspect production patternList_nil top::PatternList ::= { - top.asListPattern = nilListPattern('[', ']', location=top.location); + top.asListPattern = nilListPattern('[', ']'); } synthesized attribute namedPatternList::[Pair]; -nonterminal NamedPatternList with location, config, unparse, frame, env, errors, patternVars, patternVarEnv, namedPatternList; +tracked nonterminal NamedPatternList with config, unparse, frame, env, errors, patternVars, patternVarEnv, namedPatternList; propagate config, frame, env, errors on NamedPatternList; concrete production namedPatternList_one @@ -370,7 +370,7 @@ top::NamedPatternList ::= top.namedPatternList = []; } -nonterminal NamedPattern with location, config, unparse, frame, env, errors, patternVars, patternVarEnv, namedPatternList; +tracked nonterminal NamedPattern with config, unparse, frame, env, errors, patternVars, patternVarEnv, namedPatternList; propagate config, frame, env, patternVarEnv, errors on NamedPattern; concrete production namedPattern @@ -384,7 +384,7 @@ top::NamedPattern ::= qn::QName '=' p::Pattern -- (or more than one) place. top.errors <- if qn.lookupAttribute.found && !qn.lookupAttribute.dcl.isAnnotation - then [err(qn.location, s"${qn.name} is not an annotation")] + then [errFromOrigin(qn, s"${qn.name} is not an annotation")] else []; top.patternVars = p.patternVars; @@ -396,9 +396,9 @@ function buildPatternList PatternList ::= plst::[Pattern] loc::Location { return case plst of - | [] -> patternList_nil(location=loc) + | [] -> patternList_nil() | h::t -> - patternList_more(h, ',', buildPatternList(t, loc), location=loc) + patternList_more(h, ',', buildPatternList(t, loc)) end; } diff --git a/grammars/silver/compiler/extension/regex/Regex.sv b/grammars/silver/compiler/extension/regex/Regex.sv index 13890e4d7..0a4ec72de 100644 --- a/grammars/silver/compiler/extension/regex/Regex.sv +++ b/grammars/silver/compiler/extension/regex/Regex.sv @@ -18,7 +18,7 @@ layout {} propagate freeVars; forwards to if null(getTypeDcl("silver:regex:Regex", top.env)) - then errorExpr([err(top.location, "Use of regexes requires import of silver:regex")], location=top.location) + then errorExpr([errFromOrigin(top, "Use of regexes requires import of silver:regex")]) else translate(top.location, reflect(reg.ast)); } @@ -29,7 +29,7 @@ top::Expr ::= e::Expr '=~' r::Expr propagate frame, freeVars; forwards to if null(getValueDcl("silver:regex:matches", top.env)) - then errorExpr([err(top.location, "Use of regexes requires import of silver:regex")], location=top.location) + then errorExpr([errFromOrigin(top, "Use of regexes requires import of silver:regex")]) else Silver_Expr { silver:regex:matches($Expr{r}, $Expr{e}) }; } diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index f3bc6bd6c..c53c17a7a 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -18,7 +18,7 @@ top::Expr ::= -- Constrain the type of the wrapped expression to the type that was inferred here, -- to allow for any type class constraints to be resolved in the translation. silver:rewrite:anyASTExpr( - let rewrite_rule_anyAST_val__::$TypeExpr{typerepTypeExpr(top.finalType, location=top.location)} = $Expr{top} + let rewrite_rule_anyAST_val__::$TypeExpr{typerepTypeExpr(top.finalType)} = $Expr{top} in rewrite_rule_anyAST_val__ end) }); @@ -44,11 +44,10 @@ top::Expr ::= q::Decorated! QName _ _ _ antiquoteASTExpr( Silver_Expr { silver:rewrite:anyASTExpr( - \ e::$TypeExpr{typerepTypeExpr(top.finalType.decoratedType, location=builtin)} -> + \ e::$TypeExpr{typerepTypeExpr(top.finalType.decoratedType)} -> $Expr{ decorateExprWithEmpty( - 'decorate', Silver_Expr { e }, 'with', '{', '}', - location=top.location)}) + 'decorate', Silver_Expr { e }, 'with', '{', '}')}) }), consASTExpr(varASTExpr(q.name), nilASTExpr()), nilNamedASTExpr()) @@ -182,7 +181,7 @@ top::Expr ::= e::Expr '.' 'forward' antiquoteASTExpr( Silver_Expr { silver:rewrite:anyASTExpr( - \ e::$TypeExpr{typerepTypeExpr(finalTy, location=builtin)} -> e.forward) + \ e::$TypeExpr{typerepTypeExpr(finalTy)} -> e.forward) }), consASTExpr(e.transform, nilASTExpr()), nilNamedASTExpr()); @@ -196,7 +195,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur antiquoteASTExpr( Silver_Expr { silver:rewrite:anyASTExpr( - \ e::$TypeExpr{typerepTypeExpr(e.finalType, location=builtin)} -> e.$qName{q.name}) + \ e::$TypeExpr{typerepTypeExpr(e.finalType)} -> e.$qName{q.name}) }), consASTExpr(e.transform, nilASTExpr()), nilNamedASTExpr()); @@ -210,7 +209,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur antiquoteASTExpr( Silver_Expr { silver:rewrite:anyASTExpr( - \ e::$TypeExpr{typerepTypeExpr(e.finalType, location=builtin)} -> e.$qName{q.name}) + \ e::$TypeExpr{typerepTypeExpr(e.finalType)} -> e.$qName{q.name}) }), consASTExpr(e.transform, nilASTExpr()), nilNamedASTExpr()); @@ -224,7 +223,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur antiquoteASTExpr( Silver_Expr { silver:rewrite:anyASTExpr( - \ e::$TypeExpr{typerepTypeExpr(e.finalType, location=builtin)} -> e.$qName{q.name}) + \ e::$TypeExpr{typerepTypeExpr(e.finalType)} -> e.$qName{q.name}) }), consASTExpr(e.transform, nilASTExpr()), nilNamedASTExpr()); @@ -238,7 +237,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur antiquoteASTExpr( Silver_Expr { silver:rewrite:anyASTExpr( - \ e::$TypeExpr{typerepTypeExpr(e.finalType, location=builtin)} -> e.$qName{q.name}) + \ e::$TypeExpr{typerepTypeExpr(e.finalType)} -> e.$qName{q.name}) }), consASTExpr(e.transform, nilASTExpr()), nilNamedASTExpr()); @@ -268,15 +267,15 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur lambdap( productionRHSCons( productionRHSElem( - name("_e", builtin), '::', - typerepTypeExpr(eUndec.finalType, location=builtin), + name("_e"), '::', + typerepTypeExpr(eUndec.finalType), location=builtin), inh.lambdaParams, location=builtin), Silver_Expr { $Expr{ decorateExprWith( - 'decorate', baseExpr(qName(builtin, "_e"), location=builtin), + 'decorate', baseExpr(qName("_e")), 'with', '{', inh.bodyExprInhTransform, '}', location=builtin)}.$qName{q.name} }, @@ -293,7 +292,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur antiquoteASTExpr( Silver_Expr { silver:rewrite:anyASTExpr( - \ e::$TypeExpr{typerepTypeExpr(e.finalType.decoratedType, location=builtin)} -> e.$qName{q.name}) + \ e::$TypeExpr{typerepTypeExpr(e.finalType.decoratedType)} -> e.$qName{q.name}) }), consASTExpr(varASTExpr(qn.name), nilASTExpr()), nilNamedASTExpr()) @@ -302,7 +301,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur antiquoteASTExpr( Silver_Expr { silver:rewrite:anyASTExpr( - \ e::$TypeExpr{typerepTypeExpr(finalTy, location=builtin)} -> e.$qName{q.name}) + \ e::$TypeExpr{typerepTypeExpr(finalTy)} -> e.$qName{q.name}) }), consASTExpr(e.transform, nilASTExpr()), nilNamedASTExpr()) @@ -325,7 +324,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur antiquoteASTExpr( Silver_Expr { silver:rewrite:anyASTExpr( - \ e::$TypeExpr{typerepTypeExpr(finalTy, location=builtin)} -> e.$qName{q.name}) + \ e::$TypeExpr{typerepTypeExpr(finalTy)} -> e.$qName{q.name}) }), consASTExpr(e.transform, nilASTExpr()), nilNamedASTExpr()); @@ -347,7 +346,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur antiquoteASTExpr( Silver_Expr { silver:rewrite:anyASTExpr( - \ e::$TypeExpr{typerepTypeExpr(finalTy, location=builtin)} -> e.$qName{q.name}) + \ e::$TypeExpr{typerepTypeExpr(finalTy)} -> e.$qName{q.name}) }), consASTExpr(e.transform, nilASTExpr()), nilNamedASTExpr()); @@ -369,7 +368,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur antiquoteASTExpr( Silver_Expr { silver:rewrite:anyASTExpr( - \ e::$TypeExpr{typerepTypeExpr(finalTy, location=builtin)} -> e.$qName{q.name}) + \ e::$TypeExpr{typerepTypeExpr(finalTy)} -> e.$qName{q.name}) }), consASTExpr(e.transform, nilASTExpr()), nilNamedASTExpr()); @@ -391,7 +390,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur antiquoteASTExpr( Silver_Expr { silver:rewrite:anyASTExpr( - \ e::$TypeExpr{typerepTypeExpr(finalTy, location=builtin)} -> e.$qName{q.name}) + \ e::$TypeExpr{typerepTypeExpr(finalTy)} -> e.$qName{q.name}) }), consASTExpr(e.transform, nilASTExpr()), nilNamedASTExpr()); @@ -409,13 +408,13 @@ top::Expr ::= 'decorate' e::Expr 'with' '{' inh::ExprInhs '}' lambdap( productionRHSCons( productionRHSElem( - name("_e", builtin), '::', - typerepTypeExpr(e.finalType, location=builtin), + name("_e"), '::', + typerepTypeExpr(e.finalType), location=builtin), inh.lambdaParams, location=builtin), decorateExprWith( - 'decorate', baseExpr(qName(builtin, "_e"), location=builtin), + 'decorate', baseExpr(qName("_e")), 'with', '{', inh.bodyExprInhTransform, '}', location=builtin), location=builtin)}) @@ -433,7 +432,7 @@ aspect production exprInhsEmpty top::ExprInhs ::= { top.transform = nilASTExpr(); - top.lambdaParams = productionRHSNil(location=builtin); + top.lambdaParams = productionRHSNil(); } aspect production exprInhsOne @@ -441,14 +440,14 @@ top::ExprInhs ::= lhs::ExprInh { top.transform = consASTExpr(lhs.transform, nilASTExpr()); top.lambdaParams = - productionRHSCons(lhs.lambdaParam, productionRHSNil(location=builtin), location=builtin); + productionRHSCons(lhs.lambdaParam, productionRHSNil()); } aspect production exprInhsCons top::ExprInhs ::= lhs::ExprInh inh::ExprInhs { top.transform = consASTExpr(lhs.transform, inh.transform); - top.lambdaParams = productionRHSCons(lhs.lambdaParam, inh.lambdaParams, location=builtin); + top.lambdaParams = productionRHSCons(lhs.lambdaParam, inh.lambdaParams); } attribute transform occurs on ExprInh; @@ -463,11 +462,11 @@ top::ExprInh ::= lhs::ExprLHSExpr '=' e::Expr ';' top.lambdaParam = productionRHSElem( name(paramName, builtin), '::', - typerepTypeExpr(e.finalType, location=builtin), + typerepTypeExpr(e.finalType), location=builtin); top.bodyExprInhTransform = exprInh( - lhs, '=', baseExpr(qName(builtin, paramName), location=builtin), ';', + lhs, '=', baseExpr(qName(paramName)), ';', location=builtin); } @@ -707,8 +706,8 @@ aspect production exprsEmpty top::Exprs ::= { top.transform = nilASTExpr(); - top.lambdaParams = productionRHSNil(location=builtin); - top.lambdaParamRefs = exprsEmpty(location=builtin); + top.lambdaParams = productionRHSNil(); + top.lambdaParamRefs = exprsEmpty(); } aspect production exprsSingle top::Exprs ::= e::Expr @@ -720,13 +719,13 @@ top::Exprs ::= e::Expr productionRHSCons( productionRHSElem( name(lambdaParamName, builtin), '::', - typerepTypeExpr(e.finalType, location=builtin), + typerepTypeExpr(e.finalType), location=builtin), - productionRHSNil(location=builtin), + productionRHSNil(), location=builtin); top.lambdaParamRefs = exprsSingle( - baseExpr(qName(builtin,lambdaParamName), location=builtin), + baseExpr(qName(builtin,lambdaParamName)), location=builtin); } aspect production exprsCons @@ -739,13 +738,13 @@ top::Exprs ::= e1::Expr ',' e2::Exprs productionRHSCons( productionRHSElem( name(lambdaParamName, builtin), '::', - typerepTypeExpr(e1.finalType, location=builtin), + typerepTypeExpr(e1.finalType), location=builtin), e2.lambdaParams, location=builtin); top.lambdaParamRefs = exprsCons( - baseExpr(qName(builtin, lambdaParamName), location=builtin), + baseExpr(qName(lambdaParamName)), ',', e2.lambdaParamRefs, location=builtin); } diff --git a/grammars/silver/compiler/extension/rewriting/Pattern.sv b/grammars/silver/compiler/extension/rewriting/Pattern.sv index 93bacee5c..bffd3851d 100644 --- a/grammars/silver/compiler/extension/rewriting/Pattern.sv +++ b/grammars/silver/compiler/extension/rewriting/Pattern.sv @@ -84,8 +84,7 @@ top::MatchRule ::= pt::PatternList _ e::Expr top.wrappedMatchRuleList = [matchRule( pt.patternList, nothing(), - hackWrapKey(toString(top.ruleIndex), e, location=e.location), - location=top.location)]; + hackWrapKey(toString(top.ruleIndex), e))]; } aspect production matchRuleWhen_c @@ -111,9 +110,8 @@ top::MatchRule ::= pt::PatternList 'when' cond::Expr _ e::Expr top.wrappedMatchRuleList = [matchRule( pt.patternList, - just((hackWrapKey(toString(top.ruleIndex) ++ "_cond", cond, location=e.location), nothing())), - hackWrapKey(toString(top.ruleIndex), e, location=e.location), - location=top.location)]; + just((hackWrapKey(toString(top.ruleIndex) ++ "_cond", cond), nothing())), + hackWrapKey(toString(top.ruleIndex), e))]; } aspect production matchRuleWhenMatches_c @@ -141,9 +139,8 @@ top::MatchRule ::= pt::PatternList 'when' cond::Expr 'matches' p::Pattern _ e::E top.wrappedMatchRuleList = [matchRule( pt.patternList, - just((hackWrapKey(toString(top.ruleIndex) ++ "_cond", cond, location=e.location), just(p))), - hackWrapKey(toString(top.ruleIndex), e, location=e.location), - location=top.location)]; + just((hackWrapKey(toString(top.ruleIndex) ++ "_cond", cond), just(p))), + hackWrapKey(toString(top.ruleIndex), e))]; } abstract production hackWrapKey diff --git a/grammars/silver/compiler/extension/rewriting/Rewriting.sv b/grammars/silver/compiler/extension/rewriting/Rewriting.sv index d4cfb7cc9..6c0edcc1f 100644 --- a/grammars/silver/compiler/extension/rewriting/Rewriting.sv +++ b/grammars/silver/compiler/extension/rewriting/Rewriting.sv @@ -60,7 +60,7 @@ top::Expr ::= 'traverse' n::QName '(' es::AppExprs ',' anns::AnnoAppExprs ')' local localErrors::[Message] = es.errors ++ anns.traverseErrors ++ if null(getTypeDcl("silver:rewrite:Strategy", top.env)) - then [err(top.location, "Term rewriting requires import of silver:rewrite")] + then [errFromOrigin(top, "Term rewriting requires import of silver:rewrite")] else []; propagate downSubst, upSubst, finalSubst, freeVars; @@ -69,22 +69,22 @@ top::Expr ::= 'traverse' n::QName '(' es::AppExprs ',' anns::AnnoAppExprs ')' traversal(n.lookupValue.fullName, es.traverseTransform, anns.traverseTransform); local fwrd::Expr = translate(builtin, reflect(new(transform))); - forwards to if !null(localErrors) then errorExpr(localErrors, location=builtin) else fwrd; + forwards to if !null(localErrors) then errorExpr(localErrors) else fwrd; } concrete production traverseProdAnno top::Expr ::= 'traverse' n::QName '(' anns::AnnoAppExprs ')' { - forwards to traverseProdExprAnno($1, n, $3, emptyAppExprs(location=$3.location), ',', anns, $5, location=top.location); + forwards to traverseProdExprAnno($1, n, $3, emptyAppExprs(), ',', anns, $5); } concrete production traverseProdExpr top::Expr ::= 'traverse' n::QName '(' es::AppExprs ')' { - forwards to traverseProdExprAnno($1, n, $3, es, ',', emptyAnnoAppExprs(location=$4.location), $5, location=top.location); + forwards to traverseProdExprAnno($1, n, $3, es, ',', emptyAnnoAppExprs(), $5); } concrete production traverseProdEmpty top::Expr ::= 'traverse' n::QName '(' ')' { - forwards to traverseProdExprAnno($1, n, $3, emptyAppExprs(location=$3.location), ',', emptyAnnoAppExprs(location=$4.location), $4, location=top.location); + forwards to traverseProdExprAnno($1, n, $3, emptyAppExprs(), ',', emptyAnnoAppExprs(), $4); } abstract production traverseConsList @@ -98,12 +98,12 @@ top::Expr ::= 'traverse' '(' h::AppExpr '::' t::AppExpr ')' concrete production traverseConsListFirstMissing top::Expr ::= 'traverse' '(' h::'_' '::' t::AppExpr ')' { - forwards to traverseConsList($1, $2, missingAppExpr(h, location=h.location), $4, t, $6, location=top.location); + forwards to traverseConsList($1, $2, missingAppExpr(h), $4, t, $6); } concrete production traverseConsListFirstPresent top::Expr ::= 'traverse' '(' h::Expr '::' t::AppExpr ')' { - forwards to traverseConsList($1, $2, presentAppExpr(h, location=h.location), $4, t, $6, location=top.location); + forwards to traverseConsList($1, $2, presentAppExpr(h), $4, t, $6); } concrete production traverseNilList @@ -165,7 +165,7 @@ top::AnnoExpr ::= qn::QName '=' e::AppExpr top.traverseErrors = e.errors ++ if !extractNamedArg(qn.name, top.funcAnnotations).fst.isJust - then [err(qn.location, "Named parameter '" ++ qn.name ++ "' is not appropriate for '" ++ top.appExprApplied ++ "'")] + then [errFromOrigin(qn, "Named parameter '" ++ qn.name ++ "' is not appropriate for '" ++ top.appExprApplied ++ "'")] else []; top.traverseTransform = (qn.lookupAttribute.fullName, e.traverseTransform); } @@ -206,9 +206,9 @@ top::Expr ::= 'rule' 'on' ty::TypeExpr 'of' Opt_Vbar_t ml::MRuleList 'end' -- so we need to decorate one of those here. local checkExpr::Expr = caseExpr( - [hackExprType(ty.typerep, location=builtin)], + [hackExprType(ty.typerep)], ml.wrappedMatchRuleList, false, - errorExpr([], location=builtin), + errorExpr([]), ty.typerep, location=builtin); checkExpr.env = top.env; @@ -233,7 +233,7 @@ top::Expr ::= 'rule' 'on' ty::TypeExpr 'of' Opt_Vbar_t ml::MRuleList 'end' ty.errors ++ ml.errors ++ checkExpr.errors ++ ty.errorsKindStar ++ if null(getTypeDcl("silver:rewrite:Strategy", top.env)) - then [err(top.location, "Term rewriting requires import of silver:rewrite")] + then [errFromOrigin(top, "Term rewriting requires import of silver:rewrite")] else []; -- Can't use an error production here, unfortunately, due to circular dependency issues. @@ -250,7 +250,7 @@ top::Expr ::= 'rule' 'on' ty::TypeExpr 'of' Opt_Vbar_t ml::MRuleList 'end' then requireType(antiquoteASTExpr( Silver_Expr { silver:rewrite:anyASTExpr( - \ $TypeExpr{typerepTypeExpr(finalRuleType, location=builtin)} -> unit()) + \ $TypeExpr{typerepTypeExpr(finalRuleType)} -> unit()) })) <* ml.transform else ml.transform; @@ -265,7 +265,7 @@ abstract production hackExprType top::Expr ::= t::Type { top.typerep = t; - forwards to errorExpr([], location=builtin); + forwards to errorExpr([]); } -- Strategy meta-translation diff --git a/grammars/silver/compiler/extension/silverconstruction/Syntax.sv b/grammars/silver/compiler/extension/silverconstruction/Syntax.sv index f5d615f73..404fc3df2 100644 --- a/grammars/silver/compiler/extension/silverconstruction/Syntax.sv +++ b/grammars/silver/compiler/extension/silverconstruction/Syntax.sv @@ -56,16 +56,15 @@ top::Expr ::= '$Expr' '{' e::Expr '}' top.unparse = s"$$Expr{${e.unparse}}"; forwards to errorExpr( - [err(top.location, "$Expr should not occur outside of quoted Silver literal")], - location=top.location); + [errFromOrigin(top, "$Expr should not occur outside of quoted Silver literal")]); } concrete production antiquoteExprInhs top::ExprInhs ::= '$ExprInhs' '{' e::Expr '}' { top.unparse = s"$$ExprInhs{${e.unparse}}"; - -- TODO: [err(top.location, "$ExprInhs should not occur outside of quoted Silver literal")] - forwards to exprInhsEmpty(location=top.location); + -- TODO: [errFromOrigin(top, "$ExprInhs should not occur outside of quoted Silver literal")] + forwards to exprInhsEmpty(); } concrete production antiquoteTypeExpr @@ -74,16 +73,15 @@ top::TypeExpr ::= '$TypeExpr' '{' e::Expr '}' top.unparse = s"$$TypeExpr{${e.unparse}}"; forwards to errorTypeExpr( - [err(top.location, "$TypeExpr should not occur outside of quoted Silver literal")], - location=top.location); + [errFromOrigin(top, "$TypeExpr should not occur outside of quoted Silver literal")]); } concrete production antiquoteConstraintList top::ConstraintList ::= '$ConstraintList' '{' e::Expr '}' { top.unparse = s"$$ConstraintList{${e.unparse}}"; - -- [err(top.location, "$ConstraintList should not occur outside of quoted Silver Literal.")] - forwards to nilConstraint(location=top.location); + -- [errFromOrigin(top, "$ConstraintList should not occur outside of quoted Silver Literal.")] + forwards to nilConstraint(); } concrete production antiquotePattern @@ -92,22 +90,21 @@ top::Pattern ::= '$Pattern' '{' e::Expr '}' top.unparse = s"$$Pattern{${e.unparse}}"; forwards to errorPattern( - [err(top.location, "$Pattern should not occur outside of quoted Silver literal")], - location=top.location); + [errFromOrigin(top, "$Pattern should not occur outside of quoted Silver literal")]); } concrete production antiquoteProductionRHS top::ProductionRHS ::= '$ProductionRHS' '{' e::Expr '}' { top.unparse = s"$$ProductionRHS{${e.unparse}}"; - forwards to productionRHSNil(location=top.location); + forwards to productionRHSNil(); } concrete production antiquoteAspectRHS top::AspectRHS ::= '$AspectRHS' '{' e::Expr '}' { top.unparse = s"$$AspectRHS{${e.unparse}}"; - forwards to aspectRHSElemNil(location=top.location); + forwards to aspectRHSElemNil(); } concrete production antiquoteProductionStmt @@ -116,8 +113,7 @@ top::ProductionStmt ::= '$ProductionStmt' '{' e::Expr '}' top.unparse = s"$$ProductionStmt{${e.unparse}}"; forwards to errorProductionStmt( - [err(top.location, "$ProductionStmt should not occur outside of quoted Silver Literal.")], - location=top.location); + [errFromOrigin(top, "$ProductionStmt should not occur outside of quoted Silver Literal.")]); } @@ -127,8 +123,7 @@ top::QName ::= '$QName' '{' e::Expr '}' top.unparse = s"$$QName{${e.unparse}}"; forwards to qNameError( - [err(top.location, "$QName should not occur outside of quoted Silver literal")], - location=top.location); + [errFromOrigin(top, "$QName should not occur outside of quoted Silver literal")]); } concrete production antiquoteQNameAttrOccur @@ -138,17 +133,15 @@ top::QNameAttrOccur ::= '$QNameAttrOccur' '{' e::Expr '}' forwards to qNameAttrOccur( qNameError( - [err(top.location, "$QNameAttrOccur should not occur outside of quoted Silver literal")], - location=top.location), - location=top.location); + [errFromOrigin(top, "$QNameAttrOccur should not occur outside of quoted Silver literal")])); } concrete production antiquoteName top::Name ::= '$Name' '{' e::Expr '}' { top.unparse = s"$$Name{${e.unparse}}"; - -- TODO: [err(top.location, "$Name should not occur outside of quoted Silver literal")] - forwards to name("err", top.location); + -- TODO: [errFromOrigin(top, "$Name should not occur outside of quoted Silver literal")] + forwards to name("err"); } concrete production antiquote_qName @@ -157,14 +150,13 @@ top::QName ::= '$qName' '{' e::Expr '}' top.unparse = s"$$qName{${e.unparse}}"; forwards to qNameError( - [err(top.location, "$qName should not occur outside of Silver_Expr")], - location=top.location); + [errFromOrigin(top, "$qName should not occur outside of Silver_Expr")]); } concrete production antiquote_name top::Name ::= '$name' '{' e::Expr '}' { top.unparse = s"$$name{${e.unparse}}"; - -- TODO: [err(top.location, "$Name should not occur outside of quoted Silver literal")] - forwards to name("err", top.location); + -- TODO: [errFromOrigin(top, "$Name should not occur outside of quoted Silver literal")] + forwards to name("err"); } diff --git a/grammars/silver/compiler/extension/silverconstruction/Translation.sv b/grammars/silver/compiler/extension/silverconstruction/Translation.sv index 80e928fe3..a68cc69c5 100644 --- a/grammars/silver/compiler/extension/silverconstruction/Translation.sv +++ b/grammars/silver/compiler/extension/silverconstruction/Translation.sv @@ -30,7 +30,7 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs just( mkFullFunctionInvocation( givenLocation, - baseExpr(qName(givenLocation, "silver:compiler:metatranslation:makeQName"), location=givenLocation), + baseExpr(qName("silver:compiler:metatranslation:makeQName")), [e, locAST.translation], [])) | left(msg) -> error(s"Error in reifying child of production ${prodName}:\n${msg}") @@ -45,7 +45,7 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs just( mkFullFunctionInvocation( givenLocation, - baseExpr(qName(givenLocation, "silver:compiler:metatranslation:makeName"), location=givenLocation), + baseExpr(qName("silver:compiler:metatranslation:makeName")), [e, locAST.translation], [])) | left(msg) -> error(s"Error in reifying child of production ${prodName}:\n${msg}") diff --git a/grammars/silver/compiler/extension/strategyattr/ConcreteSyntax.sv b/grammars/silver/compiler/extension/strategyattr/ConcreteSyntax.sv index 9aa082ec7..781aca6df 100644 --- a/grammars/silver/compiler/extension/strategyattr/ConcreteSyntax.sv +++ b/grammars/silver/compiler/extension/strategyattr/ConcreteSyntax.sv @@ -7,7 +7,7 @@ top::AGDcl ::= 'partial' 'strategy' 'attribute' a::Name '=' e::StrategyExpr_c '; { top.unparse = "strategy attribute " ++ a.unparse ++ "=" ++ e.unparse ++ ";"; e.givenGenName = a.name; - forwards to strategyAttributeDcl(false, a, [], [], e.ast, location=top.location); + forwards to strategyAttributeDcl(false, a, [], [], e.ast); } concrete production totalStrategyAttributeDcl @@ -15,81 +15,81 @@ top::AGDcl ::= 'strategy' 'attribute' a::Name '=' e::StrategyExpr_c ';' { top.unparse = "strategy attribute " ++ a.unparse ++ "=" ++ e.unparse ++ ";"; e.givenGenName = a.name; - forwards to strategyAttributeDcl(true, a, [], [], e.ast, location=top.location); + forwards to strategyAttributeDcl(true, a, [], [], e.ast); } -closed nonterminal StrategyExpr_c with location, givenGenName, unparse, ast; +closed tracked nonterminal StrategyExpr_c with givenGenName, unparse, ast; concrete productions top::StrategyExpr_c | 'id' { top.unparse = "id"; - top.ast = id(genName=top.givenGenName, location=top.location); + top.ast = id(genName=top.givenGenName); } | 'fail' { top.unparse = "fail"; - top.ast = fail(genName=top.givenGenName, location=top.location); + top.ast = fail(genName=top.givenGenName); } | s1::StrategyExpr_c '<*' s2::StrategyExpr_c { top.unparse = s"(${s1.unparse} <* ${s2.unparse})"; - top.ast = sequence(s1.ast, s2.ast, genName=top.givenGenName, location=top.location); + top.ast = sequence(s1.ast, s2.ast, genName=top.givenGenName); s1.givenGenName = top.givenGenName ++ "_fst"; s2.givenGenName = top.givenGenName ++ "_snd"; } | s1::StrategyExpr_c '<+' s2::StrategyExpr_c { top.unparse = s"(${s1.unparse} <+ ${s2.unparse})"; - top.ast = choice(s1.ast, s2.ast, genName=top.givenGenName, location=top.location); + top.ast = choice(s1.ast, s2.ast, genName=top.givenGenName); s1.givenGenName = top.givenGenName ++ "_left"; s2.givenGenName = top.givenGenName ++ "_right"; } | 'all' '(' s::StrategyExpr_c ')' { top.unparse = s"all(${s.unparse})"; - top.ast = allTraversal(s.ast, genName=top.givenGenName, location=top.location); + top.ast = allTraversal(s.ast, genName=top.givenGenName); s.givenGenName = top.givenGenName ++ "_all_arg"; } | 'some' '(' s::StrategyExpr_c ')' { top.unparse = s"some(${s.unparse})"; - top.ast = someTraversal(s.ast, genName=top.givenGenName, location=top.location); + top.ast = someTraversal(s.ast, genName=top.givenGenName); s.givenGenName = top.givenGenName ++ "_some_arg"; } | 'one' '(' s::StrategyExpr_c ')' { top.unparse = s"one(${s.unparse})"; - top.ast = oneTraversal(s.ast, genName=top.givenGenName, location=top.location); + top.ast = oneTraversal(s.ast, genName=top.givenGenName); s.givenGenName = top.givenGenName ++ "_one_arg"; } | id::StrategyQName '(' s::StrategyExprs_c ')' { top.unparse = s"${id.ast.unparse}(${s.unparse})"; - top.ast = prodTraversal(id.ast, s.ast, genName=top.givenGenName, location=top.location); + top.ast = prodTraversal(id.ast, s.ast, genName=top.givenGenName); s.index = 1; s.givenGenName = top.givenGenName ++ "_" ++ id.ast.name; } | 'rec' n::Name Arrow_t s::StrategyExpr_c { top.unparse = s"rec ${n.name} -> (${s.unparse})"; - top.ast = recComb(n, s.ast, genName=top.givenGenName, location=top.location); + top.ast = recComb(n, s.ast, genName=top.givenGenName); s.givenGenName = top.givenGenName; } | 'rule' 'on' id::Name '::' ty::TypeExpr 'of' Opt_Vbar_t ml::MRuleList 'end' { top.unparse = "rule on " ++ id.unparse ++ "::" ++ ty.unparse ++ " of " ++ ml.unparse ++ " end"; - top.ast = rewriteRule(id, ty, ml, genName=top.givenGenName, location=top.location); + top.ast = rewriteRule(id, ty, ml, genName=top.givenGenName); } | 'rule' 'on' ty::TypeExpr 'of' Opt_Vbar_t ml::MRuleList 'end' { top.unparse = "rule on " ++ ty.unparse ++ " of " ++ ml.unparse ++ " end"; - top.ast = rewriteRule(name("top", top.location), ty, ml, genName=top.givenGenName, location=top.location); + top.ast = rewriteRule(name("top"), ty, ml, genName=top.givenGenName); } | id::StrategyQName { top.unparse = id.ast.unparse; - top.ast = nameRef(id.ast, genName=top.givenGenName, location=top.location); + top.ast = nameRef(id.ast, genName=top.givenGenName); } | '(' s::StrategyExpr_c ')' { @@ -100,118 +100,118 @@ concrete productions top::StrategyExpr_c | 'printTerm' { top.unparse = s"printTerm"; - top.ast = printTerm(genName=top.givenGenName, location=top.location); + top.ast = printTerm(genName=top.givenGenName); } | 'try' '(' s::StrategyExpr_c ')' { top.unparse = s"try(${s.unparse})"; - top.ast = try(s.ast, genName=top.givenGenName, location=top.location); + top.ast = try(s.ast, genName=top.givenGenName); s.givenGenName = top.givenGenName ++ "_try_arg"; } | 'repeat' '(' s::StrategyExpr_c ')' { top.unparse = s"repeat(${s.unparse})"; - top.ast = repeatS(s.ast, genName=top.givenGenName, location=top.location); + top.ast = repeatS(s.ast, genName=top.givenGenName); s.givenGenName = top.givenGenName ++ "_repeat_arg"; } | 'reduce' '(' s::StrategyExpr_c ')' { top.unparse = s"reduce(${s.unparse})"; - top.ast = reduce(s.ast, genName=top.givenGenName, location=top.location); + top.ast = reduce(s.ast, genName=top.givenGenName); s.givenGenName = top.givenGenName ++ "_reduce_arg"; } | 'bottomUp' '(' s::StrategyExpr_c ')' { top.unparse = s"bottomUp(${s.unparse})"; - top.ast = bottomUp(s.ast, genName=top.givenGenName, location=top.location); + top.ast = bottomUp(s.ast, genName=top.givenGenName); s.givenGenName = top.givenGenName ++ "_bottomUp_arg"; } | 'topDown' '(' s::StrategyExpr_c ')' { top.unparse = s"topDown(${s.unparse})"; - top.ast = topDown(s.ast, genName=top.givenGenName, location=top.location); + top.ast = topDown(s.ast, genName=top.givenGenName); s.givenGenName = top.givenGenName ++ "_topDown_arg"; } | 'downUp' '(' s1::StrategyExpr_c ',' s2::StrategyExpr_c ')' { top.unparse = s"downUp(${s1.unparse}, ${s2.unparse})"; - top.ast = downUp(s1.ast, s2.ast, genName=top.givenGenName, location=top.location); + top.ast = downUp(s1.ast, s2.ast, genName=top.givenGenName); s1.givenGenName = top.givenGenName ++ "_downUp_arg1"; s2.givenGenName = top.givenGenName ++ "_downUp_arg2"; } | 'allBottomUp' '(' s::StrategyExpr_c ')' { top.unparse = s"allBottomUp(${s.unparse})"; - top.ast = allBottomUp(s.ast, genName=top.givenGenName, location=top.location); + top.ast = allBottomUp(s.ast, genName=top.givenGenName); s.givenGenName = top.givenGenName ++ "_allBottomUp_arg"; } | 'allTopDown' '(' s::StrategyExpr_c ')' { top.unparse = s"allTopDown(${s.unparse})"; - top.ast = allTopDown(s.ast, genName=top.givenGenName, location=top.location); + top.ast = allTopDown(s.ast, genName=top.givenGenName); s.givenGenName = top.givenGenName ++ "_allTopDown_arg"; } | 'allDownUp' '(' s1::StrategyExpr_c ',' s2::StrategyExpr_c ')' { top.unparse = s"allDownUp(${s1.unparse}, ${s2.unparse})"; - top.ast = allDownUp(s1.ast, s2.ast, genName=top.givenGenName, location=top.location); + top.ast = allDownUp(s1.ast, s2.ast, genName=top.givenGenName); s1.givenGenName = top.givenGenName ++ "_allDownUp_arg1"; s2.givenGenName = top.givenGenName ++ "_allDownUp_arg2"; } | 'someBottomUp' '(' s::StrategyExpr_c ')' { top.unparse = s"someBottomUp(${s.unparse})"; - top.ast = someBottomUp(s.ast, genName=top.givenGenName, location=top.location); + top.ast = someBottomUp(s.ast, genName=top.givenGenName); s.givenGenName = top.givenGenName ++ "_someBottomUp_arg"; } | 'someTopDown' '(' s::StrategyExpr_c ')' { top.unparse = s"someTopDown(${s.unparse})"; - top.ast = someTopDown(s.ast, genName=top.givenGenName, location=top.location); + top.ast = someTopDown(s.ast, genName=top.givenGenName); s.givenGenName = top.givenGenName ++ "_someTopDown_arg"; } | 'someDownUp' '(' s1::StrategyExpr_c ',' s2::StrategyExpr_c ')' { top.unparse = s"someDownUp(${s1.unparse}, ${s2.unparse})"; - top.ast = someDownUp(s1.ast, s2.ast, genName=top.givenGenName, location=top.location); + top.ast = someDownUp(s1.ast, s2.ast, genName=top.givenGenName); s1.givenGenName = top.givenGenName ++ "_someDownUp_arg1"; s2.givenGenName = top.givenGenName ++ "_someDownUp_arg2"; } | 'onceBottomUp' '(' s::StrategyExpr_c ')' { top.unparse = s"onceBottomUp(${s.unparse})"; - top.ast = onceBottomUp(s.ast, genName=top.givenGenName, location=top.location); + top.ast = onceBottomUp(s.ast, genName=top.givenGenName); s.givenGenName = top.givenGenName ++ "_onceBottomUp_arg"; } | 'onceTopDown' '(' s::StrategyExpr_c ')' { top.unparse = s"onceTopDown(${s.unparse})"; - top.ast = onceTopDown(s.ast, genName=top.givenGenName, location=top.location); + top.ast = onceTopDown(s.ast, genName=top.givenGenName); s.givenGenName = top.givenGenName ++ "_onceTopDown_arg"; } | 'onceDownUp' '(' s1::StrategyExpr_c ',' s2::StrategyExpr_c ')' { top.unparse = s"onceDownUp(${s1.unparse}, ${s2.unparse})"; - top.ast = onceDownUp(s1.ast, s2.ast, genName=top.givenGenName, location=top.location); + top.ast = onceDownUp(s1.ast, s2.ast, genName=top.givenGenName); s1.givenGenName = top.givenGenName ++ "_onceDownUp_arg1"; s2.givenGenName = top.givenGenName ++ "_onceDownUp_arg2"; } | 'innermost' '(' s::StrategyExpr_c ')' { top.unparse = s"innermost(${s.unparse})"; - top.ast = innermost(s.ast, genName=top.givenGenName, location=top.location); + top.ast = innermost(s.ast, genName=top.givenGenName); s.givenGenName = top.givenGenName ++ "_innermost_arg"; } | 'outermost' '(' s::StrategyExpr_c ')' { top.unparse = s"outermost(${s.unparse})"; - top.ast = outermost(s.ast, genName=top.givenGenName, location=top.location); + top.ast = outermost(s.ast, genName=top.givenGenName); s.givenGenName = top.givenGenName ++ "_outermost_arg"; } inherited attribute index::Integer; -nonterminal StrategyExprs_c with location, index, givenGenName, unparse, ast; +tracked nonterminal StrategyExprs_c with index, givenGenName, unparse, ast; concrete productions top::StrategyExprs_c | h::StrategyExpr_c ',' t::StrategyExprs_c { @@ -233,9 +233,9 @@ concrete productions top::StrategyExprs_c top.ast = nilStrategyExpr(); } -nonterminal StrategyQName with location, ast; +tracked nonterminal StrategyQName with ast; concrete productions top::StrategyQName (strategyQNameOne) | id::StrategyName_t -{ top.ast = qNameId(name(id.lexeme, id.location), location=top.location); } +{ top.ast = qNameId(name(id.lexeme, id.nameLoc)); } (strategyQNameCons) | id::StrategyName_t ':' qn::StrategyQName -{ top.ast = qNameCons(name(id.lexeme, id.location), $2, qn.ast, location=top.location); } +{ top.ast = qNameCons(name(id.lexeme, id.nameLoc), $2, qn.ast); } diff --git a/grammars/silver/compiler/extension/strategyattr/DclInfo.sv b/grammars/silver/compiler/extension/strategyattr/DclInfo.sv index c21f1ae36..a4a4f1dd0 100644 --- a/grammars/silver/compiler/extension/strategyattr/DclInfo.sv +++ b/grammars/silver/compiler/extension/strategyattr/DclInfo.sv @@ -43,12 +43,12 @@ top::AttributeDclInfo ::= top.isSynthesized = true; top.isStrategy = true; - top.decoratedAccessHandler = synDecoratedAccessHandler(_, _, location=_); - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _, location=_), _, _, _); - top.dataAccessHandler = synDataAccessHandler(_, _, location=_); - top.attrDefDispatcher = synthesizedAttributeDef(_, _, _, location=_); -- Allow normal syn equations - top.attributionDispatcher = strategyAttributionDcl(_, _, _, _, location=_); - top.propagateDispatcher = propagateStrategy(_, location=_); + top.decoratedAccessHandler = synDecoratedAccessHandler; + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.dataAccessHandler = synDataAccessHandler; + top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations + top.attributionDispatcher = strategyAttributionDcl; + top.propagateDispatcher = propagateStrategy; top.isTotal = isTotal; top.containsErrors = containsErrors; diff --git a/grammars/silver/compiler/extension/strategyattr/Strategy.sv b/grammars/silver/compiler/extension/strategyattr/Strategy.sv index 8fa7aacc1..b2a31c468 100644 --- a/grammars/silver/compiler/extension/strategyattr/Strategy.sv +++ b/grammars/silver/compiler/extension/strategyattr/Strategy.sv @@ -19,12 +19,12 @@ top::AGDcl ::= isTotal::Boolean a::Name recVarNameEnv::[Pair] rec top.errors <- if length(getAttrDclAll(fName, top.env)) > 1 - then [err(a.location, "Attribute '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(a, "Attribute '" ++ fName ++ "' is already bound.")] else []; top.errors <- if isTotal && !e.isTotal -- Not an error since we can still translate this, but the translation may raise run-time errors in case of failure - then [wrn(e.location, s"Implementation of total strategy ${a.name} is not total")] + then [wrnFromOrigin(e, s"Implementation of total strategy ${a.name} is not total")] else []; e.recVarNameEnv = recVarNameEnv; @@ -35,20 +35,18 @@ top::AGDcl ::= isTotal::Boolean a::Name recVarNameEnv::[Pair] rec local fwrd::AGDcl = foldr( - appendAGDcl(_, _, location=top.location), + appendAGDcl(_, _), defsAGDcl( [attrDef( defaultEnvItem( strategyDcl( fName, isTotal, !null(top.errors), map(fst, e.liftedStrategies), recVarNameEnv, recVarTotalEnv, e.partialRefs, e.totalRefs, e.containsTraversal, e, - sourceGrammar=top.grammarName, sourceLocation=a.location)))], - location=top.location), + sourceGrammar=top.grammarName, sourceLocation=a.location)))]), map( \ d::(String, Decorated StrategyExpr with LiftedInhs) -> strategyAttributeDcl( - d.snd.isTotalNoEnv, name(d.fst, top.location), d.snd.recVarNameEnv, d.snd.recVarTotalNoEnvEnv, new(d.snd), - location=top.location), + d.snd.isTotalNoEnv, name(d.fst, top.location), d.snd.recVarNameEnv, d.snd.recVarTotalNoEnvEnv, new(d.snd)), e.liftedStrategies)); -- Uncomment for debugging @@ -60,7 +58,7 @@ top::AGDcl ::= isTotal::Boolean a::Name recVarNameEnv::[Pair] rec abstract production strategyAttributionDcl top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs { - undecorates to attributionDcl('attribute', at, attl, 'occurs', 'on', nt, nttl, ';', location=top.location); + undecorates to attributionDcl('attribute', at, attl, 'occurs', 'on', nt, nttl, ';'); propagate grammarName, env, flowEnv; production attribute localErrors::[Message] with ++; @@ -68,7 +66,7 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: attl.errors ++ attl.errorsTyVars ++ nt.lookupType.errors ++ nttl.errors ++ nttl.errorsTyVars; localErrors <- if length(attl.types) > 0 - then [err(attl.location, "Explicit type arguments are not allowed for strategy attributes")] + then [errFromOrigin(attl, "Explicit type arguments are not allowed for strategy attributes")] else []; -- Technically we could do this check on the propagate, but it seems clearer to raise it here @@ -76,7 +74,7 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: flatMap( \ totalAttr::String -> if null(getOccursDcl(totalAttr, nt.lookupType.fullName, top.env)) - then [err(top.location, s"Total strategy attribute ${totalAttr} referenced by ${at.name} does not occur on ${nt.name}")] + then [errFromOrigin(top, s"Total strategy attribute ${totalAttr} referenced by ${at.name} does not occur on ${nt.name}")] else [], nub(at.lookupAttribute.dcl.totalRefs)); @@ -94,15 +92,12 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: case nttl of | botlSome(tl) -> appTypeExpr( - nominalTypeExpr(nt.qNameType, location=top.location), - tl, location=top.location) - | botlNone() -> nominalTypeExpr(nt.qNameType, location=top.location) - end, - location=top.location), - '>', location=top.location), - location=top.location), - nt, nttl, - location=top.location); + nominalTypeExpr(nt.qNameType), + tl) + | botlNone() -> nominalTypeExpr(nt.qNameType) + end), + '>')), + nt, nttl); forwards to if null(at.lookupAttribute.dcl.liftedStrategyNames) then @atOccursDcl @@ -110,14 +105,12 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: appendAGDcl( @atOccursDcl, foldr1( - appendAGDcl(_, _, location=top.location), + appendAGDcl(_, _), map( \ n::String -> attributionDcl( - 'attribute', qName(top.location, n), attl, 'occurs', 'on', nt, nttl, ';', - location=top.location), - at.lookupAttribute.dcl.liftedStrategyNames)), - location=top.location); + 'attribute', qName(n), attl, 'occurs', 'on', nt, nttl, ';'), + at.lookupAttribute.dcl.liftedStrategyNames))); } {-- @@ -127,7 +120,7 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: abstract production propagateStrategy top::ProductionStmt ::= attr::Decorated! QName { - undecorates to propagateOneAttr(attr, location=top.location); + undecorates to propagateOneAttr(attr); top.unparse = s"propagate ${attr.unparse}"; production isTotal::Boolean = attr.lookupAttribute.dcl.isTotal; @@ -169,17 +162,16 @@ top::ProductionStmt ::= attr::Decorated! QName local fwrd::ProductionStmt = foldr( - productionStmtAppend(_, _, location=top.location), + productionStmtAppend(_, _), attributeDef( - concreteDefLHS(qName(top.location, top.frame.signature.outputElement.elementName), location=top.location), + concreteDefLHS(qName(top.frame.signature.outputElement.elementName)), '.', - qNameAttrOccur(new(attr), location=top.location), + qNameAttrOccur(new(attr)), '=', if isTotal then e2.totalTranslation else e2.partialTranslation, - ';', - location=top.location), + ';'), map( - \ n::String -> propagateOneAttr(qName(top.location, n), location=top.location), + \ n::String -> propagateOneAttr(qName(n)), attr.lookupAttribute.dcl.liftedStrategyNames)); -- Uncomment for debugging diff --git a/grammars/silver/compiler/extension/strategyattr/StrategyExpr.sv b/grammars/silver/compiler/extension/strategyattr/StrategyExpr.sv index 33114bdb8..5180fe521 100644 --- a/grammars/silver/compiler/extension/strategyattr/StrategyExpr.sv +++ b/grammars/silver/compiler/extension/strategyattr/StrategyExpr.sv @@ -40,19 +40,19 @@ synthesized attribute totalTranslation::Expr; -- a on a, can raise a runtime err -- but probably not much of an improvement. partial strategy attribute genericStep = rule on top::StrategyExpr of - | sequence(fail(), _) -> fail(location=top.location, genName=top.genName) - | sequence(_, fail()) -> fail(location=top.location, genName=top.genName) + | sequence(fail(), _) -> fail(genName=top.genName) + | sequence(_, fail()) -> fail(genName=top.genName) | sequence(id(), s) -> s | sequence(s, id()) -> s | choice(fail(), s) -> s | choice(s, fail()) -> s | choice(s, _) when s.isTotal -> s - | allTraversal(id()) -> id(location=top.location, genName=top.genName) - | someTraversal(fail()) -> fail(location=top.location, genName=top.genName) - | oneTraversal(fail()) -> fail(location=top.location, genName=top.genName) - | prodTraversal(_, ss) when ss.containsFail -> fail(location=top.location, genName=top.genName) + | allTraversal(id()) -> id(genName=top.genName) + | someTraversal(fail()) -> fail(genName=top.genName) + | oneTraversal(fail()) -> fail(genName=top.genName) + | prodTraversal(_, ss) when ss.containsFail -> fail(genName=top.genName) | recComb(n, s) when !contains(n.name, s.freeRecVars) -> s - | inlined(_, fail()) -> fail(location=top.location, genName=top.genName) + | inlined(_, fail()) -> fail(genName=top.genName) end; -- Nonterminal-dependent, production-independent optimizations partial strategy attribute ntStep = @@ -64,27 +64,27 @@ partial strategy attribute ntStep = !contains(n.attrDcl.fullName, top.inlinedStrategies) && null(n.attrDcl.givenRecVarNameEnv) && !n.attrDcl.containsTraversal -> - inlined(n, n.attrDcl.strategyExpr, location=top.location, genName=top.genName) - | partialRef(n) when !n.matchesFrame -> fail(location=top.location, genName=top.genName) - | inlined(n, _) when !n.matchesFrame -> fail(location=top.location, genName=top.genName) - | inlined(n, id()) when n.matchesFrame -> id(location=top.location, genName=top.genName) - | inlined(n1, totalRef(n2)) when n1.matchesFrame -> totalRef(n2, location=top.location, genName=top.genName) + inlined(n, n.attrDcl.strategyExpr, genName=top.genName) + | partialRef(n) when !n.matchesFrame -> fail(genName=top.genName) + | inlined(n, _) when !n.matchesFrame -> fail(genName=top.genName) + | inlined(n, id()) when n.matchesFrame -> id(genName=top.genName) + | inlined(n1, totalRef(n2)) when n1.matchesFrame -> totalRef(n2, genName=top.genName) end; -- Production-dependent optimizations partial strategy attribute prodStep = rule on top::StrategyExpr of - | allTraversal(s) when !attrMatchesChild(top.env, fromMaybe(s.genName, s.attrRefName), top.frame) -> id(location=top.location, genName=top.genName) - | someTraversal(s) when !attrMatchesChild(top.env, fromMaybe(s.genName, s.attrRefName), top.frame) -> fail(location=top.location, genName=top.genName) - | oneTraversal(s) when !attrMatchesChild(top.env, fromMaybe(s.genName, s.attrRefName), top.frame) -> fail(location=top.location, genName=top.genName) - | prodTraversal(p, s) when p.lookupValue.fullName != top.frame.fullName -> fail(location=top.location, genName=top.genName) - | rewriteRule(_, _, ml) when !ml.matchesFrame -> fail(location=top.location, genName=top.genName) + | allTraversal(s) when !attrMatchesChild(top.env, fromMaybe(s.genName, s.attrRefName), top.frame) -> id(genName=top.genName) + | someTraversal(s) when !attrMatchesChild(top.env, fromMaybe(s.genName, s.attrRefName), top.frame) -> fail(genName=top.genName) + | oneTraversal(s) when !attrMatchesChild(top.env, fromMaybe(s.genName, s.attrRefName), top.frame) -> fail(genName=top.genName) + | prodTraversal(p, s) when p.lookupValue.fullName != top.frame.fullName -> fail(genName=top.genName) + | rewriteRule(_, _, ml) when !ml.matchesFrame -> fail(genName=top.genName) end <+ rewriteRule(id, id, elimInfeasibleMRules); partial strategy attribute elimInfeasibleMRules = onceBottomUp( rule on top::MRuleList of | mRuleList_cons(h, _, t) when !h.matchesFrame -> t - | mRuleList_cons(h, _, mRuleList_one(t)) when !t.matchesFrame -> mRuleList_one(h, location=top.location) + | mRuleList_cons(h, _, mRuleList_one(t)) when !t.matchesFrame -> mRuleList_one(h) end); attribute elimInfeasibleMRules occurs on MRuleList; @@ -112,13 +112,13 @@ strategy attribute optimize = id) <* try((genericStep <+ ntStep <+ prodStep) <* optimize); -nonterminal StrategyExpr with - config, grammarName, env, location, unparse, errors, frame, compiledGrammars, flowEnv, -- Normal expression stuff +tracked nonterminal StrategyExpr with + config, grammarName, env, unparse, errors, frame, compiledGrammars, flowEnv, -- Normal expression stuff genName, outerAttr, isOutermost, recVarNameEnv, recVarTotalEnv, recVarTotalNoEnvEnv, liftedStrategies, attrRefName, isId, isFail, isTotal, isTotalNoEnv, freeRecVars, partialRefs, totalRefs, containsTraversal, -- Frame-independent attrs partialTranslation, totalTranslation, matchesFrame, -- Frame-dependent attrs inlinedStrategies, genericStep, ntStep, prodStep, genericSimplify, ntSimplify, optimize; -- Optimization stuff -nonterminal StrategyExprs with +tracked nonterminal StrategyExprs with config, grammarName, env, unparse, errors, compiledGrammars, flowEnv, -- Normal expression stuff outerAttr, recVarNameEnv, recVarTotalEnv, recVarTotalNoEnvEnv, givenInputElements, liftedStrategies, attrRefNames, containsFail, allId, freeRecVars, partialRefs, totalRefs, containsTraversal, -- Frame-independent attrs inlinedStrategies, genericSimplify; -- Optimization stuff @@ -168,7 +168,7 @@ Expr ::= t::Type e::Expr { return Silver_Expr { - let res::$TypeExpr{typerepTypeExpr(t, location=e.location)} = + let res::$TypeExpr{typerepTypeExpr(t)} = silver:core:error("Total result demanded when partial strategy failed") in silver:core:fromMaybe(res, $Expr{e}) end @@ -236,8 +236,8 @@ top::StrategyExpr ::= s1::StrategyExpr s2::StrategyExpr -- the incoming tree and the result of s1 get re-decorated. local allInhs::ExprInhs = foldr( - exprInhsCons(_, _, location=top.location), - exprInhsEmpty(location=top.location), + exprInhsCons(_, _), + exprInhsEmpty(), map( \ attr::String -> -- TODO: translation attributes! @@ -260,7 +260,7 @@ top::StrategyExpr ::= s1::StrategyExpr s2::StrategyExpr | false, true -> Silver_Expr { silver:core:map( - \ res::$TypeExpr{typerepTypeExpr(top.frame.signature.outputElement.typerep, location=top.location)} -> + \ res::$TypeExpr{typerepTypeExpr(top.frame.signature.outputElement.typerep)} -> decorate res with { $ExprInhs{allInhs} }.$name{s2Name}, $Expr{s1.partialTranslation}) } @@ -268,7 +268,7 @@ top::StrategyExpr ::= s1::StrategyExpr s2::StrategyExpr Silver_Expr { silver:core:bind( $Expr{s1.partialTranslation}, - \ res::$TypeExpr{typerepTypeExpr(top.frame.signature.outputElement.typerep, location=top.location)} -> + \ res::$TypeExpr{typerepTypeExpr(top.frame.signature.outputElement.typerep)} -> decorate res with { $ExprInhs{allInhs} }.$name{s2Name}) } end; @@ -359,7 +359,7 @@ top::StrategyExpr ::= s::StrategyExpr $Expr{ mkFullFunctionInvocation( top.location, - baseExpr(qName(top.location, top.frame.fullName), location=top.location), + baseExpr(qName(top.frame.fullName)), map( \ a::Pair -> if a.snd @@ -369,12 +369,10 @@ top::StrategyExpr ::= s::StrategyExpr map( makeAnnoArg(top.location, top.frame.signature.outputElement.elementName, _), top.frame.signature.namedInputElements))}) - }, - location=top.location)], + })], false, Silver_Expr { silver:core:nothing() }, - appType(nonterminalType("silver:core:Maybe", [starKind()], true, false), top.frame.signature.outputElement.typerep), - location=top.location); + appType(nonterminalType("silver:core:Maybe", [starKind()], true, false), top.frame.signature.outputElement.typerep)); top.totalTranslation = if sTotal then @@ -382,7 +380,7 @@ top::StrategyExpr ::= s::StrategyExpr prod(a.s, b, c.s) -} mkFullFunctionInvocation( top.location, - baseExpr(qName(top.location, top.frame.fullName), location=top.location), + baseExpr(qName(top.frame.fullName)), map( \ a::Pair -> if a.snd @@ -433,8 +431,8 @@ top::StrategyExpr ::= s::StrategyExpr Silver_Expr { if $Expr{ foldr( - or(_, '||', _, location=top.location), - falseConst('false', location=top.location), + or(_, '||', _), + falseConst('false'), map( \ a::String -> Silver_Expr { $name{a}.$name{sName}.isJust }, matchingChildren))} @@ -443,7 +441,7 @@ top::StrategyExpr ::= s::StrategyExpr $Expr{ mkFullFunctionInvocation( top.location, - baseExpr(qName(top.location, top.frame.fullName), location=top.location), + baseExpr(qName(top.frame.fullName)), map( \ a::Pair -> if a.snd @@ -462,7 +460,7 @@ top::StrategyExpr ::= s::StrategyExpr prod(a.s, b, c.s) -} mkFullFunctionInvocation( top.location, - baseExpr(qName(top.location, top.frame.fullName), location=top.location), + baseExpr(qName(top.frame.fullName)), map( \ a::Pair -> if a.snd @@ -528,16 +526,16 @@ top::StrategyExpr ::= s::StrategyExpr matchRule( map( \ p::Pattern -> decorate p with { config = top.config; env = top.env; frame = top.frame; patternVarEnv = []; }, - repeat(wildcPattern('_', location=top.location), i) ++ + repeat(wildcPattern('_'), i) ++ Silver_Pattern { silver:core:just($name{childI ++ "_" ++ sBaseName}) } :: - repeat(wildcPattern('_', location=top.location), length(matchingChildren) - (i + 1))), + repeat(wildcPattern('_'), length(matchingChildren) - (i + 1))), nothing(), Silver_Expr { silver:core:just( $Expr{ mkFullFunctionInvocation( top.location, - baseExpr(qName(top.location, top.frame.fullName), location=top.location), + baseExpr(qName(top.frame.fullName)), map( \ a::Pair -> Silver_Expr { $name{a.fst} }, take(childIndex, childAccesses)) ++ @@ -548,14 +546,12 @@ top::StrategyExpr ::= s::StrategyExpr map( makeAnnoArg(top.location, top.frame.signature.outputElement.elementName, _), top.frame.signature.namedInputElements))}) - }, - location=top.location) + }) end end, range(0, length(matchingChildren))), false, Silver_Expr { silver:core:nothing() }, - appType(nonterminalType("silver:core:Maybe", [starKind()], true, false), top.frame.signature.outputElement.typerep), - location=top.location); + appType(nonterminalType("silver:core:Maybe", [starKind()], true, false), top.frame.signature.outputElement.typerep)); top.totalTranslation = if sTotal && !null(matchingChildren) then @@ -563,7 +559,7 @@ top::StrategyExpr ::= s::StrategyExpr prod(a.s, b, c) -} mkFullFunctionInvocation( top.location, - baseExpr(qName(top.location, top.frame.fullName), location=top.location), + baseExpr(qName(top.frame.fullName)), map( \ a::Pair -> if a.fst == head(matchingChildren) @@ -587,7 +583,7 @@ top::StrategyExpr ::= prod::QName s::StrategyExprs local numArgs::Integer = length(s.attrRefNames); top.errors <- if prod.lookupValue.found && numArgs != numParams - then [err(top.location, s"Wrong number of arguments to ${prod.name}: expected ${toString(numParams)}, got ${toString(numArgs)}")] + then [errFromOrigin(top, s"Wrong number of arguments to ${prod.name}: expected ${toString(numParams)}, got ${toString(numArgs)}")] else []; propagate liftedStrategies; @@ -636,7 +632,7 @@ top::StrategyExpr ::= prod::QName s::StrategyExprs $Expr{ mkFullFunctionInvocation( top.location, - baseExpr(qName(top.location, top.frame.fullName), location=top.location), + baseExpr(qName(top.frame.fullName)), map( \ a::Pair> -> case a.snd of @@ -648,12 +644,10 @@ top::StrategyExpr ::= prod::QName s::StrategyExprs map( makeAnnoArg(top.location, top.frame.signature.outputElement.elementName, _), top.frame.signature.namedInputElements))}) - }, - location=top.location)], + })], false, Silver_Expr { silver:core:nothing() }, - appType(nonterminalType("silver:core:Maybe", [starKind()], true, false), top.frame.signature.outputElement.typerep), - location=top.location) + appType(nonterminalType("silver:core:Maybe", [starKind()], true, false), top.frame.signature.outputElement.typerep)) else Silver_Expr { silver:core:nothing() }; } @@ -681,7 +675,7 @@ top::StrategyExprs ::= h::StrategyExpr t::StrategyExprs else nothing()) :: t.attrRefNames; top.errors <- if !null(top.givenInputElements) && !attrMatch && !h.isId - then [wrn(h.location, s"This (non-identity) strategy attribute does not occur on ${prettyType(hType)} and will be treated as identity")] + then [wrnFromOrigin(h, s"This (non-identity) strategy attribute does not occur on ${prettyType(hType)} and will be treated as identity")] else []; top.containsFail <- h.isFail; @@ -758,7 +752,7 @@ top::StrategyExpr ::= id::Name ty::TypeExpr ml::MRuleList -- so we need to decorate one of those here. production checkExpr::Expr = caseExpr( - [hackLHSExprType(ty.typerep.asNtOrDecType, location=top.location)], + [hackLHSExprType(ty.typerep.asNtOrDecType)], -- TODO: matchRuleList on MRuleList depends on frame for some reason. -- Re-decorate ml here as a workaround to avoid checkExpr depending on top.frame decorate ml with { @@ -767,11 +761,10 @@ top::StrategyExpr ::= id::Name ty::TypeExpr ml::MRuleList matchRulePatternSize = 1; frame = error("not needed"); }.matchRuleList, false, - errorExpr([], location=top.location), - ty.typerep, - location=top.location); + errorExpr([]), + ty.typerep); checkExpr.env = - newScopeEnv([lhsDef(top.grammarName, id.location, id.name, ty.typerep)], top.env); + newScopeEnv([lhsDef(top.grammarName, id.nameLoc, id.name, ty.typerep)], top.env); checkExpr.flowEnv = top.flowEnv; checkExpr.decSiteVertexInfo = nothing(); checkExpr.alwaysDecorated = false; @@ -793,7 +786,7 @@ top::StrategyExpr ::= id::Name ty::TypeExpr ml::MRuleList top.errors := checkExpr.errors; top.errors <- if !isDecorable(ty.typerep, top.env) - then [wrn(ty.location, "Only rules on nonterminals can have an effect")] + then [wrnFromOrigin(ty, "Only rules on nonterminals can have an effect")] else []; top.errors <- ty.errorsKindStar; @@ -802,8 +795,7 @@ top::StrategyExpr ::= id::Name ty::TypeExpr ml::MRuleList [Silver_Expr { $name{top.frame.signature.outputElement.elementName} }], ml.translation, false, Silver_Expr { silver:core:nothing() }, - appType(nonterminalType("silver:core:Maybe", [starKind()], true, false), ty.typerep), - location=top.location); + appType(nonterminalType("silver:core:Maybe", [starKind()], true, false), ty.typerep)); top.partialTranslation = if unify(ty.typerep, top.frame.signature.outputElement.typerep).failure then Silver_Expr { silver:core:nothing() } @@ -822,7 +814,7 @@ top::Expr ::= t::Type { top.typerep = t; top.flowVertexInfo = just(lhsVertexType); - forwards to errorExpr([], location=top.location); + forwards to errorExpr([]); } attribute matchesFrame occurs on MRuleList, MatchRule, PatternList, Pattern; @@ -850,8 +842,7 @@ top::MatchRule ::= pt::PatternList _ e::Expr { top.translation = matchRule( - pt.patternList, nothing(), Silver_Expr { silver:core:just($Expr{e}) }, - location=top.location); + pt.patternList, nothing(), Silver_Expr { silver:core:just($Expr{e}) }); } aspect production matchRuleWhen_c @@ -859,8 +850,7 @@ top::MatchRule ::= pt::PatternList 'when' cond::Expr _ e::Expr { top.translation = matchRule( - pt.patternList, just((cond, nothing())), Silver_Expr { silver:core:just($Expr{e}) }, - location=top.location); + pt.patternList, just((cond, nothing())), Silver_Expr { silver:core:just($Expr{e}) }); } aspect production matchRuleWhenMatches_c @@ -868,8 +858,7 @@ top::MatchRule ::= pt::PatternList 'when' cond::Expr 'matches' p::Pattern _ e::E { top.translation = matchRule( - pt.patternList, just((cond, just(p))), Silver_Expr { silver:core:just($Expr{e}) }, - location=top.location); + pt.patternList, just((cond, just(p))), Silver_Expr { silver:core:just($Expr{e}) }); } aspect default production @@ -901,12 +890,12 @@ top::StrategyExpr ::= id::QName local attrDcl::AttributeDclInfo = id.lookupAttribute.dcl; forwards to if lookup(id.name, top.recVarNameEnv).isJust - then recVarRef(id, genName=top.genName, location=top.location) + then recVarRef(id, genName=top.genName) else if !null(id.lookupAttribute.errors) - then errorRef(id.lookupAttribute.errors, id, genName=top.genName, location=top.location) + then errorRef(id.lookupAttribute.errors, id, genName=top.genName) else if attrIsTotal(top.env, id.name) - then totalRef(qNameAttrOccur(id, location=top.location), genName=top.genName, location=top.location) - else partialRef(qNameAttrOccur(id, location=top.location), genName=top.genName, location=top.location); + then totalRef(qNameAttrOccur(id), genName=top.genName) + else partialRef(qNameAttrOccur(id), genName=top.genName); } abstract production errorRef top::StrategyExpr ::= msg::[Message] id::Decorated QName @@ -949,16 +938,16 @@ top::StrategyExpr ::= attr::QNameAttrOccur local attrTypeScheme::PolyType = attrDcl.typeScheme; top.errors := if !attrDcl.isSynthesized - then [err(attr.location, s"Attribute ${attr.name} cannot be used as a partial strategy, because it is not a synthesized attribute")] + then [errFromOrigin(attr, s"Attribute ${attr.name} cannot be used as a partial strategy, because it is not a synthesized attribute")] else case attrTypeScheme.typerep, attrTypeScheme.boundVars of | appType(nonterminalType("silver:core:Maybe", _, _, _), varType(a1)), [a2] when a1 == a2 && attrDcl.isSynthesized -> [] | appType(nonterminalType("silver:core:Maybe", _, _, _), a), _ when (a.baseType, attrDcl.isSynthesized) matches (nonterminalType(nt, _, _, _), true) -> if null(getOccursDcl(attrDcl.fullName, nt, top.env)) - then [wrn(attr.location, s"Attribute ${attr.name} cannot be used as a partial strategy, because it doesn't occur on its own nonterminal type ${nt}")] + then [wrnFromOrigin(attr, s"Attribute ${attr.name} cannot be used as a partial strategy, because it doesn't occur on its own nonterminal type ${nt}")] else [] | errorType(), _ -> [] - | _, _ -> [err(attr.location, s"Attribute ${attr.name} cannot be used as a partial strategy")] + | _, _ -> [errFromOrigin(attr, s"Attribute ${attr.name} cannot be used as a partial strategy")] end; propagate liftedStrategies; @@ -985,15 +974,15 @@ top::StrategyExpr ::= attr::QNameAttrOccur local attrTypeScheme::PolyType = attrDcl.typeScheme; top.errors := if !attrDcl.isSynthesized - then [err(attr.location, s"Attribute ${attr.name} cannot be used as a total strategy, because it is not a synthesized attribute")] + then [errFromOrigin(attr, s"Attribute ${attr.name} cannot be used as a total strategy, because it is not a synthesized attribute")] else case attrTypeScheme.typerep.baseType, attrTypeScheme.boundVars of | varType(a1), [a2] when a1 == a2 -> [] | nonterminalType(nt, _, _, _), _ -> if null(getOccursDcl(attrDcl.fullName, nt, top.env)) - then [wrn(attr.location, s"Attribute ${attr.name} cannot be used as a total strategy, because it doesn't occur on its own nonterminal type ${nt}")] + then [wrnFromOrigin(attr, s"Attribute ${attr.name} cannot be used as a total strategy, because it doesn't occur on its own nonterminal type ${nt}")] else [] | errorType(), _ -> [] - | _, _ -> [err(attr.location, s"Attribute ${attr.name} cannot be used as a total strategy")] + | _, _ -> [errFromOrigin(attr, s"Attribute ${attr.name} cannot be used as a total strategy")] end; propagate liftedStrategies; @@ -1057,7 +1046,7 @@ function attrMatchesFrame Boolean ::= env::Env attrName::String attrFor::Type { return - decorate qNameAttrOccur(qName(loc("", -1, -1, -1, -1, -1, -1), attrName), location=loc("", -1, -1, -1, -1, -1, -1)) + decorate qNameAttrOccur(qName(loc("", -1, -1, -1, -1, -1, -1), attrName)("", -1, -1, -1, -1, -1, -1)) with { env = env; attrFor = attrFor; }.matchesFrame; } diff --git a/grammars/silver/compiler/extension/strategyattr/construction/Construction.sv b/grammars/silver/compiler/extension/strategyattr/construction/Construction.sv index ac4cf220d..765d5d159 100644 --- a/grammars/silver/compiler/extension/strategyattr/construction/Construction.sv +++ b/grammars/silver/compiler/extension/strategyattr/construction/Construction.sv @@ -30,8 +30,8 @@ top::Expr ::= 'Silver_StrategyExpr' '(' genName::Expr ')' '{' cst::StrategyExpr_ s:rewriteWith( s:allTopDown( rule on AnnoExpr of - | annoExpr(n, _, presentAppExpr(e), location=l) when n.name == "genName" -> - annoExpr(n, '=', presentAppExpr(plusPlus(genName, '++', e, location=l), location=l), location=l) + | annoExpr(n, _, presentAppExpr(e)) when n.name == "genName" -> + annoExpr(n, '=', presentAppExpr(plusPlus(genName, '++', e))) end), translate(top.location, reflect(cst.ast))).fromJust; } @@ -40,13 +40,13 @@ concrete production antiquoteStrategyExpr_c top::StrategyExpr_c ::= '$StrategyExpr' '{' e::Expr '}' { top.unparse = s"$$StrategyExpr{${e.unparse}}"; - top.ast = antiquoteStrategyExpr(e, genName=top.givenGenName, location=top.location); + top.ast = antiquoteStrategyExpr(e, genName=top.givenGenName); } concrete production antiquote_strategyQName top::StrategyQName ::= '$strategyQName' '{' e::Expr '}' { - top.ast = antiquote_qName('$qName', $2, e, $4, location=top.location); + top.ast = antiquote_qName('$qName', $2, e, $4); } abstract production antiquoteStrategyExpr diff --git a/grammars/silver/compiler/extension/strategyattr/convenience/Convenience.sv b/grammars/silver/compiler/extension/strategyattr/convenience/Convenience.sv index dea88df5d..ba08700bf 100644 --- a/grammars/silver/compiler/extension/strategyattr/convenience/Convenience.sv +++ b/grammars/silver/compiler/extension/strategyattr/convenience/Convenience.sv @@ -14,9 +14,8 @@ top::AGDcl ::= 'partial' 'strategy' 'attribute' a::Name '=' e::StrategyExpr_c 'o top.unparse = "partial strategy attribute " ++ a.name ++ " occurs on " ++ qs.unparse ++ ";"; forwards to appendAGDcl( - partialStrategyAttributeDcl($1, $2, $3, a, $5, e, $10, location=a.location), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(a, location=a.location), botlNone(location=top.location)), qs.qnames), - location=top.location); + partialStrategyAttributeDcl($1, $2, $3, a, $5, e, $10), + makeOccursDclsHelp($1.location, qNameWithTL(qNameId(a), botlNone()), qs.qnames)); } concrete production totalStrategyAttributeDclMultiple @@ -25,7 +24,6 @@ top::AGDcl ::= 'strategy' 'attribute' a::Name '=' e::StrategyExpr_c 'occurs' 'on top.unparse = "strategy attribute " ++ a.name ++ " occurs on " ++ qs.unparse ++ ";"; forwards to appendAGDcl( - totalStrategyAttributeDcl($1, $2, a, $4, e, $9, location=a.location), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(a, location=a.location), botlNone(location=top.location)), qs.qnames), - location=top.location); + totalStrategyAttributeDcl($1, $2, a, $4, e, $9), + makeOccursDclsHelp($1.location, qNameWithTL(qNameId(a), botlNone()), qs.qnames)); } diff --git a/grammars/silver/compiler/extension/templating/StringTemplating.sv b/grammars/silver/compiler/extension/templating/StringTemplating.sv index 6089ee127..e9fdc5c86 100644 --- a/grammars/silver/compiler/extension/templating/StringTemplating.sv +++ b/grammars/silver/compiler/extension/templating/StringTemplating.sv @@ -22,14 +22,14 @@ concrete production templateExpr top::Expr ::= Template_kwd t::TemplateString layout {} { - forwards to foldr1(stringAppendCall(_, _, location=top.location), t.stringTemplate); + forwards to foldr1(stringAppendCall(_, _), t.stringTemplate); } concrete production singleLineTemplateExpr top::Expr ::= SLTemplate_kwd t::SingleLineTemplateString layout {} { - forwards to foldr1(stringAppendCall(_, _, location=top.location), t.stringTemplate); + forwards to foldr1(stringAppendCall(_, _), t.stringTemplate); } production stringAppendCall @@ -46,18 +46,15 @@ top::Expr ::= a::Expr b::Expr forwards to application( baseExpr( - qName(top.location, "silver:core:stringAppend"), - location=top.location), '(', + qName("silver:core:stringAppend")), '(', snocAppExprs( snocAppExprs( - emptyAppExprs(location=top.location), ',', - presentAppExpr(@a, location=top.location), - location=top.location), ',', - presentAppExpr(@b, location=top.location), - location=top.location), + emptyAppExprs(), ',', + presentAppExpr(@a)), ',', + presentAppExpr(@b)), ',', - emptyAnnoAppExprs(location=top.location), - ')', location=top.location); + emptyAnnoAppExprs(), + ')'); } terminal PPTemplate_kwd 'pp"""' lexer classes {LITERAL, lsp:String_}; @@ -107,7 +104,7 @@ top::TemplateString ::= b::TemplateStringBody _ aspect production templateStringEmpty top::TemplateString ::= _ { - top.stringTemplate = [stringConst(terminal(String_t, "\"\"", top.location), location=top.location)]; + top.stringTemplate = [stringConst(terminal(String_t, "\"\"", top.location))]; top.ppTemplate = notext(); } @@ -121,7 +118,7 @@ top::SingleLineTemplateString ::= b::SingleLineTemplateStringBody _ aspect production singleLineTemplateStringEmpty top::SingleLineTemplateString ::= _ { - top.stringTemplate = [stringConst(terminal(String_t, "\"\"", top.location), location=top.location)]; + top.stringTemplate = [stringConst(terminal(String_t, "\"\"", top.location))]; top.ppTemplate = notext(); } @@ -142,7 +139,7 @@ top::TemplateStringBody ::= h::TemplateStringBodyItem aspect production bodyOneWater top::TemplateStringBody ::= w::Water { - top.stringTemplate = [stringConst(terminal(String_t, "\"" ++ w.waterString ++ "\"", w.location), location=w.location)]; + top.stringTemplate = [stringConst(terminal(String_t, "\"" ++ w.waterString ++ "\"", w.location))]; top.ppTemplate = w.waterDoc; } @@ -163,7 +160,7 @@ top::SingleLineTemplateStringBody ::= h::SingleLineTemplateStringBodyItem aspect production singleLineBodyOneWater top::SingleLineTemplateStringBody ::= w::SingleLineWater { - top.stringTemplate = [stringConst(terminal(String_t, "\"" ++ w.waterString ++ "\"", w.location), location=w.location)]; + top.stringTemplate = [stringConst(terminal(String_t, "\"" ++ w.waterString ++ "\"", w.location))]; top.ppTemplate = w.waterDoc; } @@ -171,7 +168,7 @@ aspect production itemWaterEscape top::TemplateStringBodyItem ::= w::Water nw::NonWater { top.stringTemplate = [ - stringConst(terminal(String_t, "\"" ++ w.waterString ++ "\"", w.location), location=w.location)] ++ + stringConst(terminal(String_t, "\"" ++ w.waterString ++ "\"", w.location))] ++ nw.stringTemplate; top.ppTemplate = cat(w.waterDoc, nw.ppTemplate); } @@ -187,7 +184,7 @@ aspect production singleLineItemWaterEscape top::SingleLineTemplateStringBodyItem ::= w::SingleLineWater nw::NonWater { top.stringTemplate = [ - stringConst(terminal(String_t, "\"" ++ w.waterString ++ "\"", w.location), location=w.location)] ++ + stringConst(terminal(String_t, "\"" ++ w.waterString ++ "\"", w.location))] ++ nw.stringTemplate; top.ppTemplate = cat(w.waterDoc, nw.ppTemplate); } diff --git a/grammars/silver/compiler/extension/templating/syntax/Templating.sv b/grammars/silver/compiler/extension/templating/syntax/Templating.sv index 476dcc2a0..a24006acd 100644 --- a/grammars/silver/compiler/extension/templating/syntax/Templating.sv +++ b/grammars/silver/compiler/extension/templating/syntax/Templating.sv @@ -17,27 +17,27 @@ terminal LiteralBackslashN /\\n/ lexer classes {LITERAL, lsp:String_}; terminal OpenEscape '${'; {-- A string without the first triple quote, with escaped expressions within -} -nonterminal TemplateString with location; +tracked nonterminal TemplateString; {-- A single-line string without the first quote, with escaped expressions within -} -nonterminal SingleLineTemplateString with location; +tracked nonterminal SingleLineTemplateString; {-- A list of alternating String/Exprs -} -nonterminal TemplateStringBody with location; +tracked nonterminal TemplateStringBody; {-- A single-line list of alternating String/Exprs -} -nonterminal SingleLineTemplateStringBody with location; +tracked nonterminal SingleLineTemplateStringBody; {-- Either a String or an Expr -} -nonterminal TemplateStringBodyItem with location; +tracked nonterminal TemplateStringBodyItem; {-- Either a single-line String or an Expr -} -nonterminal SingleLineTemplateStringBodyItem with location; +tracked nonterminal SingleLineTemplateStringBodyItem; {-- An escape -} -nonterminal NonWater with location; +tracked nonterminal NonWater; {-- List that yields a string -} -nonterminal Water with location, waterString, waterDoc; +tracked nonterminal Water with waterString, waterDoc; {-- List that yields a single-line string -} -nonterminal SingleLineWater with location, waterString, waterDoc; +tracked nonterminal SingleLineWater with waterString, waterDoc; {-- Components that yield a string -} -nonterminal WaterItem with location, waterString, waterDoc; +tracked nonterminal WaterItem with waterString, waterDoc; {-- Components that yield a single-line string -} -nonterminal SingleLineWaterItem with location, waterString, waterDoc; +tracked nonterminal SingleLineWaterItem with waterString, waterDoc; {-- The string corresponding to the water -} synthesized attribute waterString :: String; diff --git a/grammars/silver/compiler/extension/testing/EqualityTest.sv b/grammars/silver/compiler/extension/testing/EqualityTest.sv index 0e495affa..03f2ecd5e 100644 --- a/grammars/silver/compiler/extension/testing/EqualityTest.sv +++ b/grammars/silver/compiler/extension/testing/EqualityTest.sv @@ -38,13 +38,13 @@ ag::AGDcl ::= kwd::'equalityTest' localErrors := value.errors ++ expected.errors ++ valueType.errors; localErrors <- if !errCheck1.typeerror then [] - else [err(value.location, "Type of first and second expressions in equalityTest do not match. Instead they are " ++ errCheck1.leftpp ++ " and " ++ errCheck1.rightpp)]; + else [errFromOrigin(value, "Type of first and second expressions in equalityTest do not match. Instead they are " ++ errCheck1.leftpp ++ " and " ++ errCheck1.rightpp)]; localErrors <- if !errCheck2.typeerror then [] - else [err(value.location, "Type of initial expression does not match specified type (3rd argument). Instead they are " ++ errCheck2.leftpp ++ " and " ++ errCheck2.rightpp)]; + else [errFromOrigin(value, "Type of initial expression does not match specified type (3rd argument). Instead they are " ++ errCheck2.leftpp ++ " and " ++ errCheck2.rightpp)]; localErrors <- if !errCheck3.typeerror then [] - else [err(value.location, "Type of second expression does not match specified type (3rd argument). Instead they are " ++ errCheck3.leftpp ++ " and " ++ errCheck3.rightpp)]; + else [errFromOrigin(value, "Type of second expression does not match specified type (3rd argument). Instead they are " ++ errCheck3.leftpp ++ " and " ++ errCheck3.rightpp)]; local eqCtx::Context = instContext("silver:core:Eq", valueType.typerep); eqCtx.env = ag.env; @@ -90,7 +90,7 @@ ag::AGDcl ::= kwd::'equalityTest' -} ag.errors := if null(localErrors) then forward.errors else localErrors; - forwards to appendAGDcl(absProdCS, aspProdCS, location=ag.location); + forwards to appendAGDcl(absProdCS, aspProdCS); {- local absProdCS :: AGDcl = asAGDcl ( @@ -128,27 +128,27 @@ ag::AGDcl ::= kwd::'equalityTest' -} -- TODO: BUG: FIXME: these names should be mangled. I ran into 't' being shadowed in a test I wrote! - local tref :: Name = name("t", ag.location); + local tref :: Name = name("t"); local testNameref :: Name = name(testName, ag.location); - local valueref :: Name = name("value", ag.location); - local expectedref :: Name = name("expected", ag.location); - local msgref :: Name = name("msg", ag.location); - local passref :: Name = name("pass", ag.location); + local valueref :: Name = name("value"); + local expectedref :: Name = name("expected"); + local msgref :: Name = name("msg"); + local passref :: Name = name("pass"); -- TODO: Rewrite as Silver_AGDcl { ... } local absProdCS :: AGDcl = productionDcl('abstract', 'production', testNameref, productionSignature( - nilConstraint(location=ag.location), '=>', + nilConstraint(), '=>', productionLHS(tref, '::', - nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "Test", ag.location), location=ag.location), location=ag.location), location=ag.location), - '::=', productionRHSNil(location=ag.location), location=ag.location), - productionBody('{', foldl(productionStmtsSnoc(_, _, location=ag.location), productionStmtsNil(location=ag.location), [ - localAttributeDcl('local', 'attribute', valueref, '::', valueType, ';', location=ag.location), - valueEq(qNameId(valueref, location=valueref.location), '=', value, ';', location=ag.location), - localAttributeDcl('local', 'attribute', expectedref, '::', valueType, ';', location=ag.location), - valueEq(qNameId(expectedref, location=expectedref.location), '=', expected, ';', location=ag.location), - attributeDef(concreteDefLHS(qNameId(tref, location=tref.location), location=tref.location), '.', qNameAttrOccur(qNameId(msgref, location=msgref.location), location=ag.location), '=', + nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "Test", ag.location)))), + '::=', productionRHSNil()), + productionBody('{', foldl(productionStmtsSnoc(_, _), productionStmtsNil(), [ + localAttributeDcl('local', 'attribute', valueref, '::', valueType, ';'), + valueEq(qNameId(valueref), '=', value, ';'), + localAttributeDcl('local', 'attribute', expectedref, '::', valueType, ';'), + valueEq(qNameId(expectedref), '=', expected, ';'), + attributeDef(concreteDefLHS(qNameId(tref)), '.', qNameAttrOccur(qNameId(msgref)), '=', foldStringExprs([ strCnst("Test at " ++ ag.location.unparse ++ " failed.\nChecking that expression\n " ++ stringifyString(value.unparse) ++ "\nshould be same as expression\n " ++ @@ -156,10 +156,10 @@ ag::AGDcl ::= kwd::'equalityTest' Silver_Expr { silver:testing:showTestValue(value) }, strCnst("\nExpected value: \n "), Silver_Expr { silver:testing:showTestValue(expected) }, - strCnst("\n")]), ';', location=ag.location), - attributeDef(concreteDefLHS(qNameId(tref, location=tref.location), location=tref.location), '.', qNameAttrOccur(qNameId(passref, location=passref.location), location=ag.location), '=', - Silver_Expr { value == expected }, ';', location=ag.location), - forwardsTo('forwards', 'to', mkStrFunctionInvocation(ag.location, "defTest", []), ';', location=ag.location)]), '}', location=ag.location), location=ag.location); + strCnst("\n")]), ';'), + attributeDef(concreteDefLHS(qNameId(tref)), '.', qNameAttrOccur(qNameId(passref)), '=', + Silver_Expr { value == expected }, ';'), + forwardsTo('forwards', 'to', mkStrFunctionInvocation(ag.location, "defTest", []), ';')]), '}')); {- local aspProdCS :: AGDcl = asAGDcl ( @@ -170,22 +170,22 @@ ag::AGDcl ::= kwd::'equalityTest' -} local aspProdCS :: AGDcl = - aspectProductionDcl('aspect', 'production', qNameId(testSuite, location=ag.location), + aspectProductionDcl('aspect', 'production', qNameId(testSuite), aspectProductionSignature( - aspectProductionLHSId(tref, location=ag.location), - '::=', aspectRHSElemNil(location=ag.location), location=ag.location), + aspectProductionLHSId(tref), + '::=', aspectRHSElemNil()), productionBody('{', productionStmtsSnoc( - productionStmtsNil(location=ag.location), + productionStmtsNil(), valContainsAppend( - qName(ag.location, "testsToPerform"), + qName("testsToPerform"), '<-', fullList('[', exprsSingle( applicationEmpty( - baseExpr(qNameId(testNameref, location=ag.location), location=ag.location), '(', ')', location=ag.location), location=ag.location), - ']', location=ag.location), - ';', location=ag.location), location=ag.location), '}', location=ag.location), location=ag.location); + baseExpr(qNameId(testNameref)), '(', ')')), + ']'), + ';')), '}')); local testName :: String = "generatedTest" ++ "_" ++ substitute(":","_",ag.grammarName) ++ "_" ++ diff --git a/grammars/silver/compiler/extension/testing/Helper.sv b/grammars/silver/compiler/extension/testing/Helper.sv index 57239f0bd..09a4770e7 100644 --- a/grammars/silver/compiler/extension/testing/Helper.sv +++ b/grammars/silver/compiler/extension/testing/Helper.sv @@ -14,7 +14,7 @@ import silver:compiler:modification:list; function mkNameExpr Expr ::= name::String l::Location { - return baseExpr(qName(l, name), location=l); + return baseExpr(qName(name)); } -- fold a list of expressions(Expr) into a single "++"-separated Expr @@ -38,7 +38,7 @@ function attrAcc Expr ::= n::String a::String l::Location { return - access(mkNameExpr(n, l), '.', qNameAttrOccur(qName(l, a), location=l), location=l); + access(mkNameExpr(n, l), '.', qNameAttrOccur(qName(a))); } -- replace " characters with two: \ and " diff --git a/grammars/silver/compiler/extension/testing/MainTestSuite.sv b/grammars/silver/compiler/extension/testing/MainTestSuite.sv index efce45377..c976d3224 100644 --- a/grammars/silver/compiler/extension/testing/MainTestSuite.sv +++ b/grammars/silver/compiler/extension/testing/MainTestSuite.sv @@ -20,23 +20,23 @@ top::AGDcl ::= 'makeTestSuite' nme::IdLower_t ';' local sig :: ProductionSignature = productionSignature( - nilConstraint(location=top.location), '=>', - productionLHS(name("t", top.location), '::', - nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "TestSuite", top.location), location=top.location), location=top.location), location=top.location), - '::=', productionRHSNil(location=top.location), location=top.location); + nilConstraint(), '=>', + productionLHS(name("t"), '::', + nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "TestSuite", top.location)))), + '::=', productionRHSNil()); local bod :: [ProductionStmt] = - [forwardsTo('forwards', 'to', mkStrFunctionInvocation(top.location, "testsAsNT", [mkNameExpr("testsToPerform", top.location)]), ';', location=top.location), - collectionAttributeDclProd('production', 'attribute', name("testsToPerform", top.location), '::', - listTypeExpr('[', nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "Test", top.location), location=top.location), location=top.location), ']', location=top.location), - 'with', plusplusOperator('++', location=top.location), ';', location=top.location), - valContainsBase(qName(top.location, "testsToPerform"), ':=', emptyList('[',']', location=top.location), ';', location=top.location) + [forwardsTo('forwards', 'to', mkStrFunctionInvocation(top.location, "testsAsNT", [mkNameExpr("testsToPerform", top.location)]), ';'), + collectionAttributeDclProd('production', 'attribute', name("testsToPerform"), '::', + listTypeExpr('[', nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "Test", top.location))), ']'), + 'with', plusplusOperator('++'), ';'), + valContainsBase(qName("testsToPerform"), ':=', emptyList('[',']'), ';') ]; forwards to - productionDcl('abstract', 'production', nameIdLower(nme, location=nme.location), sig, + productionDcl('abstract', 'production', nameIdLower(nme), sig, productionBody('{', - foldl(productionStmtsSnoc(_, _, location=top.location), productionStmtsNil(location=top.location), bod), '}', location=top.location), location=top.location); + foldl(productionStmtsSnoc(_, _), productionStmtsNil(), bod), '}')); {- abstract production core_tests @@ -58,41 +58,38 @@ top::AGDcl ::= 'mainTestSuite' nme::IdLower_t ';' appendAGDcl( functionDcl( -- function main - 'function', name("main", top.location), + 'function', name("main"), -- IOVal ::= args::[String] mainIO::IOToken functionSignature( - nilConstraint(location=top.location), '=>', + nilConstraint(), '=>', functionLHS( appTypeExpr( - nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "IOVal", top.location), location=top.location), location=top.location), - bTypeList('<', typeListSingle(integerTypeExpr('Integer', location=top.location), location=top.location), '>', location=top.location), location=top.location), location=top.location), + nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "IOVal", top.location))), + bTypeList('<', typeListSingle(integerTypeExpr('Integer')), '>'))), '::=', productionRHSCons( - productionRHSElemType(listTypeExpr('[', stringTypeExpr('String', location=top.location), ']', location=top.location), location=top.location), + productionRHSElemType(listTypeExpr('[', stringTypeExpr('String'), ']')), productionRHSCons( productionRHSElem( - name("mainIO", top.location), - '::', typerepTypeExpr(ioForeignType, location=top.location), location=top.location), - productionRHSNil(location=top.location), - location=top.location), - location=top.location), - location=top.location), + name("mainIO"), + '::', typerepTypeExpr(ioForeignType)), + productionRHSNil()))), -- body::ProductionBody productionBody('{', - foldl(productionStmtsSnoc(_, _, location=top.location), productionStmtsNil(location=top.location), [ + foldl(productionStmtsSnoc(_, _), productionStmtsNil(), [ -- local testResults :: TestSuite; localAttributeDcl( - 'local', 'attribute', name("testResults", top.location), '::', - nominalTypeExpr( qNameTypeId(terminal(IdUpper_t,"TestSuite", top.location), location=top.location), location=top.location), ';', location=top.location), + 'local', 'attribute', name("testResults"), '::', + nominalTypeExpr( qNameTypeId(terminal(IdUpper_t,"TestSuite", top.location))), ';'), -- testResults = name() - valueEq( qName(top.location, "testResults"), '=', - applicationEmpty( baseExpr( qNameId(nameIdLower(nme, location=top.location), location=top.location), location=top.location), - '(', ')', location=top.location), - ';', location=top.location), + valueEq( qName("testResults"), '=', + applicationEmpty( baseExpr( qNameId(nameIdLower(nme))), + '(', ')'), + ';'), -- testResults.ioIn = ... attributeDef( - concreteDefLHS( qName(top.location, "testResults"), location=top.location), '.', qNameAttrOccur(qName(top.location, "ioIn"), location=top.location), - '=', mkNameExpr("mainIO", top.location), ';', location=top.location), + concreteDefLHS( qName("testResults")), '.', qNameAttrOccur(qName("ioIn")), + '=', mkNameExpr("mainIO", top.location), ';'), -- return ... returnDef('return', mkStrFunctionInvocation(top.location, "ioval", @@ -116,13 +113,12 @@ top::AGDcl ::= 'mainTestSuite' nme::IdLower_t ';' attrAcc("testResults", "ioOut", top.location) ]) ]), - intConst( terminal(Int_t, "0", top.location), location=top.location) + intConst( terminal(Int_t, "0", top.location)) ]), - ';', location=top.location) - ]), '}', location=top.location), location=top.location), + ';') + ]), '}')), - makeTestSuite_p( 'makeTestSuite', nme, ';', location=top.location), - location=top.location); + makeTestSuite_p( 'makeTestSuite', nme, ';')); } diff --git a/grammars/silver/compiler/extension/testing/WrongCode.sv b/grammars/silver/compiler/extension/testing/WrongCode.sv index 69af627d3..14b8972c4 100644 --- a/grammars/silver/compiler/extension/testing/WrongCode.sv +++ b/grammars/silver/compiler/extension/testing/WrongCode.sv @@ -24,13 +24,13 @@ top::AGDcl ::= 'wrongCode' s::String_t '{' ags::AGDcls '}' top.errors := if !containsMessage(substring(1, length(s.lexeme) - 1, s.lexeme), 2, ags.errors) - then [err(top.location, "Wrong code did not raise an error containing " ++ s.lexeme ++ ". Bubbling up errors from lines " ++ toString($3.line) ++ " to " ++ toString($5.line))] ++ ags.errors + then [errFromOrigin(top, "Wrong code did not raise an error containing " ++ s.lexeme ++ ". Bubbling up errors from lines " ++ toString($3.line) ++ " to " ++ toString($5.line))] ++ ags.errors else []; -- do extend its environment with its defs ags.env = occursEnv(ags.occursDefs, newScopeEnv(ags.defs, top.env)); - forwards to emptyAGDcl(location=top.location); + forwards to emptyAGDcl(); } concrete production warnDecl @@ -41,7 +41,7 @@ top::AGDcl ::= 'warnCode' s::String_t '{' ags::AGDcls '}' top.errors := if !containsMessage(substring(1, length(s.lexeme) - 1, s.lexeme), 1, ags.errors) - then [err(top.location, "Warn code did not raise a warning containing " ++ s.lexeme ++ ". Bubbling up errors from lines " ++ toString($3.line) ++ " to " ++ toString($5.line))] ++ ags.errors + then [errFromOrigin(top, "Warn code did not raise a warning containing " ++ s.lexeme ++ ". Bubbling up errors from lines " ++ toString($3.line) ++ " to " ++ toString($5.line))] ++ ags.errors else []; forwards to makeAppendAGDclOfAGDcls(ags); @@ -71,7 +71,7 @@ top::AGDcl ::= 'noWarnCode' s::String_t '{' ags::AGDcls '}' top.errors := ags.errors ++ if containsMessage(substring(1, length(s.lexeme) - 1, s.lexeme), 1, ags.errors) - then [err(top.location, "No-warn code raised a warning containing " ++ s.lexeme ++ ". Bubbling up errors from lines " ++ toString($3.line) ++ " to " ++ toString($5.line))] + then [errFromOrigin(top, "No-warn code raised a warning containing " ++ s.lexeme ++ ". Bubbling up errors from lines " ++ toString($3.line) ++ " to " ++ toString($5.line))] else []; forwards to makeAppendAGDclOfAGDcls(ags); @@ -86,12 +86,12 @@ top::AGDcl ::= 'wrongFlowCode' s::String_t '{' ags::AGDcls '}' top.errors := if !containsMessage(substring(1, length(s.lexeme) - 1, s.lexeme), 2, ags.errors) - then [err(top.location, "Wrong code did not raise an error containing " ++ s.lexeme ++ ". Bubbling up errors from lines " ++ toString($3.line) ++ " to " ++ toString($5.line))] ++ ags.errors + then [errFromOrigin(top, "Wrong code did not raise an error containing " ++ s.lexeme ++ ". Bubbling up errors from lines " ++ toString($3.line) ++ " to " ++ toString($5.line))] ++ ags.errors else []; -- These need to be passed up for the flow analysis to work: propagate defs, flowDefs, uniqueRefs; - forwards to emptyAGDcl(location=top.location); + forwards to emptyAGDcl(); } diff --git a/grammars/silver/compiler/extension/treegen/Arbitrary.sv b/grammars/silver/compiler/extension/treegen/Arbitrary.sv index a2d531a47..8b1a3fe52 100644 --- a/grammars/silver/compiler/extension/treegen/Arbitrary.sv +++ b/grammars/silver/compiler/extension/treegen/Arbitrary.sv @@ -44,7 +44,7 @@ top::AGDcl ::= 'generator' n::Name '::' t::TypeExpr '{' grammars::GeneratorCompo -- Build the syntax AST from the specified grammars to extract lexical precedence info production syntax::SyntaxRoot = cstRoot( n.name, t.typerep.typeName, foldr(consSyntax, nilSyntax(), med.syntaxAst), - nothing(), [], [], location=top.location, sourceGrammar=top.grammarName); + nothing(), [], [], sourceGrammar=top.grammarName); production attribute implicitImports::[String] with ++; implicitImports := []; @@ -72,8 +72,8 @@ top::AGDcl ::= 'generator' n::Name '::' t::TypeExpr '{' grammars::GeneratorCompo { $ProductionStmt{ foldr( - productionStmtAppend(_, _, location=top.location), - errorProductionStmt([], location=top.location), -- TODO: No nullProductionStmt? + productionStmtAppend(_, _), + errorProductionStmt([]), -- TODO: No nullProductionStmt? map(genNtLocalDecl(top.location, forward.env, specEnv, _), map((.fullName), syntax.allNonterminals)) ++ map(genTermLocalDecl(top.location, forward.env, specEnv, syntax.dominatingTerminals, _), map((.fullName), syntax.allTerminals)))} return $Expr{genForType(top.location, forward.env, specEnv, Silver_Expr { 0 }, t.typerep)}; @@ -84,8 +84,8 @@ top::AGDcl ::= 'generator' n::Name '::' t::TypeExpr '{' grammars::GeneratorCompo --top.errors := unsafeTracePrint(forward.errors, forward.unparse); } -nonterminal GeneratorComponents with config, grammarName, location, unparse, errors, moduleNames, compiledGrammars, grammarDependencies; -nonterminal GeneratorComponent with config, grammarName, location, unparse, errors, moduleNames, compiledGrammars, grammarDependencies; +tracked nonterminal GeneratorComponents with config, grammarName, unparse, errors, moduleNames, compiledGrammars, grammarDependencies; +tracked nonterminal GeneratorComponent with config, grammarName, unparse, errors, moduleNames, compiledGrammars, grammarDependencies; propagate config, grammarName, compiledGrammars, grammarDependencies, env, errors, moduleNames on GeneratorComponents, GeneratorComponent; @@ -211,25 +211,25 @@ ProductionStmt ::= loc::Location env::Env specEnv::Env nt::String local result::Expr = if null(prods) -- TODO: This could be a compile-time error, in theory - then Silver_Expr { error($Expr{stringConst(terminal(String_t, "\"no generatable productions for nonterminal " ++ nt ++ "\""), location=loc)}) } + then Silver_Expr { error($Expr{stringConst(terminal(String_t, "\"no generatable productions for nonterminal " ++ nt ++ "\""))}) } else Silver_Expr { silver:core:bind( if depth >= maxDepth -- Exclude all but the lowest-arity productions - then randomRange(0, $Expr{intConst(terminal(Int_t, toString(num_lowest_arity - 1)), location=loc)}) + then randomRange(0, $Expr{intConst(terminal(Int_t, toString(num_lowest_arity - 1)))}) else if depth < minDepth -- Exclude all arity-0 productions then randomRange( - $Expr{intConst(terminal(Int_t, toString(if num_nonzero_arity == length(prods) then 0 else num_nonzero_arity)), location=loc)}, - $Expr{intConst(terminal(Int_t, toString(length(prods) - 1)), location=loc)}) + $Expr{intConst(terminal(Int_t, toString(if num_nonzero_arity == length(prods) then 0 else num_nonzero_arity)))}, + $Expr{intConst(terminal(Int_t, toString(length(prods) - 1)))}) -- All productions - else randomRange(0, $Expr{intConst(terminal(Int_t, toString(length(prods) - 1)), location=loc)}), + else randomRange(0, $Expr{intConst(terminal(Int_t, toString(length(prods) - 1)))}), \ i::Integer -> $Expr{generateExprChain(loc, env, specEnv, nt, 0, prods)}) }; return Silver_ProductionStmt { - local $name{"gen_" ++ substitute(":", "_", nt)}::(silver:core:RandomGen<$TypeExpr{nominalTypeExpr(qName(loc, nt).qNameType, location=loc)}> ::= Integer) = + local $name{"gen_" ++ substitute(":", "_", nt)}::(silver:core:RandomGen<$TypeExpr{nominalTypeExpr(qName(nt).qNameType)}> ::= Integer) = \ depth::Integer -> $Expr{result}; }; } @@ -237,7 +237,7 @@ ProductionStmt ::= loc::Location env::Env specEnv::Env nt::String function genTermLocalDecl ProductionStmt ::= loc::Location env::Env specEnv::Env dominatingTerminals::EnvTree t::String { - local te::TypeExpr = nominalTypeExpr(qName(loc, t).qNameType, location=loc); + local te::TypeExpr = nominalTypeExpr(qName(t).qNameType); -- Filter out cantidate lexemes by checking if they match dominating terminal regexes. -- TODO: This a approach is somewhat somewhat inefficient, and fails with @@ -256,8 +256,8 @@ ProductionStmt ::= loc::Location env::Env specEnv::Env dominatingTerminals::E -- same source. local termDominated::Expr = foldr( - or(_, '||', _, location=loc), - falseConst('false', location=loc), + or(_, '||', _), + falseConst('false'), map( \ term::Decorated SyntaxDcl -> Silver_Expr { silver:regex:matches($Expr{translate(loc, reflect(term.terminalRegex))}, term.lexeme) @@ -304,7 +304,7 @@ Expr ::= loc::Location env::Env specEnv::Env nt::String index::Integer lst::[ local lambdaChain::Expr = foldr( \ arg::(String, Type) res::Expr -> - Silver_Expr { \ $name{arg.1}::$TypeExpr{typerepTypeExpr(arg.2, location=loc)} -> $Expr{res} }, + Silver_Expr { \ $name{arg.1}::$TypeExpr{typerepTypeExpr(arg.2)} -> $Expr{res} }, genRes, args); local genProd::Expr = if null(argGenExprs) @@ -316,7 +316,7 @@ Expr ::= loc::Location env::Env specEnv::Env nt::String index::Integer lst::[ return if null(tail(lst)) then genProd else Silver_Expr { - if i == $Expr{intConst(terminal(Int_t, toString(index)), location=loc)} + if i == $Expr{intConst(terminal(Int_t, toString(index)))} then $Expr{genProd} else $Expr{generateExprChain(loc, env, specEnv, nt, index + 1, tail(lst))} }; diff --git a/grammars/silver/compiler/extension/treegen/TerminalGen.sv b/grammars/silver/compiler/extension/treegen/TerminalGen.sv index 1d7fa9d97..a51bd2352 100644 --- a/grammars/silver/compiler/extension/treegen/TerminalGen.sv +++ b/grammars/silver/compiler/extension/treegen/TerminalGen.sv @@ -31,11 +31,11 @@ top::Expr ::= 'genArbTerminal' '(' te::TypeExpr ',' '_' ')' forwards to if null(getAttrDcl("silver:regex:genArbMatch", top.env)) - then errorExpr([err(top.location, "Generation of arbitrary terminal values requires import of silver:regex")], location=top.location) + then errorExpr([errFromOrigin(top, "Generation of arbitrary terminal values requires import of silver:regex")]) else Silver_Expr { let genLexeme::RandomGen = decorate $Expr{translate(top.location, reflect(new(regex)))} with { - starProb = $Expr{floatConst(terminal(Float_t, toString(genRepeatProb)), location=top.location)}; + starProb = $Expr{floatConst(terminal(Float_t, toString(genRepeatProb)))}; altCountIn = 0; }.genArbMatch in \ loc::silver:core:Location -> silver:core:map(\ lexeme::String -> terminal($TypeExpr{te}, lexeme, loc), genLexeme) @@ -49,6 +49,6 @@ top::Expr ::= 'genArbTerminal' '(' te::TypeExpr ',' loc::Expr ')' top.unparse = s"genArbTerminal(${te.unparse}, ${loc.unparse})"; forwards to mkFunctionInvocation(top.location, - genArbTerminalNoLocExpr('genArbTerminal', '(', te, ',', '_', ')', location=top.location), + genArbTerminalNoLocExpr('genArbTerminal', '(', te, ',', '_', ')'), [loc]); } diff --git a/grammars/silver/compiler/extension/treegen/TestFor.sv b/grammars/silver/compiler/extension/treegen/TestFor.sv index 70eece4ce..910ce5640 100644 --- a/grammars/silver/compiler/extension/treegen/TestFor.sv +++ b/grammars/silver/compiler/extension/treegen/TestFor.sv @@ -30,31 +30,31 @@ top::AGDcl ::= 'testFor' testSuite::Name ':' n::Name '::' id::QName ',' e::Expr 'function', name(generatedName, l), sig, - body, location=l); + body); local sig :: FunctionSignature = functionSignature( - nilConstraint(location=l), '=>', - functionLHS(typerepTypeExpr(boolType(), location=l), location=l), + nilConstraint(), '=>', + functionLHS(typerepTypeExpr(boolType())), '::=', productionRHSCons( - productionRHSElem(n, '::', typerepTypeExpr(id.lookupType.typeScheme.typerep, location=l), location=l), - productionRHSNil(location=l), location=l), + productionRHSElem(n, '::', typerepTypeExpr(id.lookupType.typeScheme.typerep)), + productionRHSNil()), location=l); local body :: ProductionBody = - productionBody('{', foldl(productionStmtsSnoc(_, _, location=l), productionStmtsNil(location=l), stmts), '}', location=l); + productionBody('{', foldl(productionStmtsSnoc(_, _), productionStmtsNil(), stmts), '}'); local stmts :: [ProductionStmt] = [ - returnDef('return', e, ';', location=l) + returnDef('return', e, ';') ]; -- emit function taking a ID tree GENERATING FUNCTION and check e on it forwards to foldr( - appendAGDcl(_, _, location=top.location), - emptyAGDcl(location=top.location), + appendAGDcl(_, _), + emptyAGDcl(), fundcl :: map( generateTestFor(_, generatedName, l, testSuite), prods)); @@ -69,38 +69,38 @@ AGDcl ::= d::ValueDclInfo testfunname::String l::Location testSuite::Name local sig :: FunctionSignature = -- id ::= functionSignature( - nilConstraint(location=l), '=>', - functionLHS(typerepTypeExpr(boolType(), location=l), location=l), + nilConstraint(), '=>', + functionLHS(typerepTypeExpr(boolType())), '::=', - productionRHSNil(location=l), + productionRHSNil(), location=l); local body :: ProductionBody = - productionBody('{', foldl(productionStmtsSnoc(_, _, location=l), productionStmtsNil(location=l), stmts), '}', location=l); + productionBody('{', foldl(productionStmtsSnoc(_, _), productionStmtsNil(), stmts), '}'); local stmts :: [ProductionStmt] = [ - shortLocalDecl('local', name("current__depth", l), '::', typerepTypeExpr(intType(), location=l), '=', intConst(terminal(Int_t, "1"), location=l), ';', location=l), - returnDef('return', mkStrFunctionInvocation(l, testfunname, [deriveGenerateOn(d, l)]), ';', location=l) + shortLocalDecl('local', name("current__depth"), '::', typerepTypeExpr(intType()), '=', intConst(terminal(Int_t, "1")), ';'), + returnDef('return', mkStrFunctionInvocation(l, testfunname, [deriveGenerateOn(d, l)]), ';') ]; -- emit function 'testArbitraryProduction_ID' that generates a production-rooted tree, and calls above generating function on it -- emit test case calling 'repeatTestTimes(testArbitraryProduction_ID, 100)' return foldr( - appendAGDcl(_, _, location=l), - emptyAGDcl(location=l), + appendAGDcl(_, _), + emptyAGDcl(), [ functionDcl( 'function', name(generatedName, l), sig, - body, location=l), + body), equalityTest2_p( terminal(EqualityTest_t, "equalityTest", l), '(', - mkStrFunctionInvocation(l, "repeatTestTimes", [baseExpr(qName(l, generatedName), location=l), intConst(terminal(Int_t, "10"), location=l)]), ',', - trueConst('true', location=l), ',', - booleanTypeExpr('Boolean', location=l), ',', + mkStrFunctionInvocation(l, "repeatTestTimes", [baseExpr(qName(generatedName)), intConst(terminal(Int_t, "10"))]), ',', + trueConst('true'), ',', + booleanTypeExpr('Boolean'), ',', testSuite, ')', ';', location=l ) ] diff --git a/grammars/silver/compiler/extension/tuple/PatternMatching.sv b/grammars/silver/compiler/extension/tuple/PatternMatching.sv index befb5c529..b1b8f9a3e 100644 --- a/grammars/silver/compiler/extension/tuple/PatternMatching.sv +++ b/grammars/silver/compiler/extension/tuple/PatternMatching.sv @@ -1,5 +1,5 @@ -- Pattern matching on tuples -nonterminal TuplePatternList with location, unparse; +tracked nonterminal TuplePatternList with unparse; concrete production emptyTuplePattern top::Pattern ::= '(' ')' diff --git a/grammars/silver/compiler/extension/tuple/Tuple.sv b/grammars/silver/compiler/extension/tuple/Tuple.sv index e2dadd54f..0c587f1bd 100644 --- a/grammars/silver/compiler/extension/tuple/Tuple.sv +++ b/grammars/silver/compiler/extension/tuple/Tuple.sv @@ -14,7 +14,7 @@ imports silver:compiler:extension:patternmatching; terminal IntConst /[0-9]+/; -nonterminal TupleList with location, unparse, translation; +tracked nonterminal TupleList with unparse, translation; -- used to convert the comma-separated list of expressions -- that make up the tuple into a pair expression: @@ -59,9 +59,9 @@ top::Expr ::= tuple::Expr '.' a::IntConst local len::Integer = length(ty.tupleElems); forwards to if (accessIndex > len || accessIndex < 1) then - errorExpr([err(top.location, "Invalid tuple selector index.")], location=top.location) + errorExpr([errFromOrigin(top, "Invalid tuple selector index.")]) -- @ prevents exponential type checking - else select(@tuple, 1, accessIndex, len, location=top.location); + else select(@tuple, 1, accessIndex, len); } @@ -77,7 +77,7 @@ top::Expr ::= exp::Expr i::Integer a::Integer len::Integer -- tuple do we simply return the expression itself @exp else Silver_Expr { $Expr{@exp}.fst } - else select(Silver_Expr{ $Expr{@exp}.snd }, i + 1, a, len, location=top.location); + else select(Silver_Expr{ $Expr{@exp}.snd }, i + 1, a, len); } -- TupleList cases: diff --git a/grammars/silver/compiler/extension/tuple/Type.sv b/grammars/silver/compiler/extension/tuple/Type.sv index ad4019138..25036cc28 100644 --- a/grammars/silver/compiler/extension/tuple/Type.sv +++ b/grammars/silver/compiler/extension/tuple/Type.sv @@ -2,7 +2,7 @@ grammar silver:compiler:extension:tuple; imports silver:compiler:modification:list; -nonterminal ListOfTypeExprs with location, unparse, te_translation; +tracked nonterminal ListOfTypeExprs with unparse, te_translation; -- Used to convert the comma-separated list of TypeExprs -- that make up the tuple type expression into a diff --git a/grammars/silver/compiler/langserver/ReferenceLocations.sv b/grammars/silver/compiler/langserver/ReferenceLocations.sv index 86c674c22..72d991968 100644 --- a/grammars/silver/compiler/langserver/ReferenceLocations.sv +++ b/grammars/silver/compiler/langserver/ReferenceLocations.sv @@ -101,9 +101,9 @@ aspect attributeRefLocs on Constraint using <- of end; aspect valueRefLocs on top::ProductionStmt using <- of -| localAttributeDcl(_, _, n, _, _, _) -> map(\dcl :: ValueDclInfo -> (n.location, dcl), getValueDcl(n.name, top.env)) -| productionAttributeDcl(_, _, n, _, _, _) -> map(\dcl :: ValueDclInfo -> (n.location, dcl), getValueDcl(n.name, top.env)) -| forwardProductionAttributeDcl(_, _, _, n, _) -> map(\dcl :: ValueDclInfo -> (n.location, dcl), getValueDcl(n.name, top.env)) +| localAttributeDcl(_, _, n, _, _, _) -> map(\dcl :: ValueDclInfo -> (n.nameLoc, dcl), getValueDcl(n.name, top.env)) +| productionAttributeDcl(_, _, n, _, _, _) -> map(\dcl :: ValueDclInfo -> (n.nameLoc, dcl), getValueDcl(n.name, top.env)) +| forwardProductionAttributeDcl(_, _, _, n, _) -> map(\dcl :: ValueDclInfo -> (n.nameLoc, dcl), getValueDcl(n.name, top.env)) end; aspect valueRefLocs on ProductionStmt using := of @@ -188,11 +188,11 @@ end; -- Productions -- LHS aspect valueRefLocs on top::ProductionLHS using <- of -| productionLHS(n, _, _) -> map(\dcl :: ValueDclInfo -> (n.location, dcl), getValueDcl(n.name, top.env)) +| productionLHS(n, _, _) -> map(\dcl :: ValueDclInfo -> (n.nameLoc, dcl), getValueDcl(n.name, top.env)) end; aspect valueRefLocs on top::AspectProductionLHS using <- of -| aspectProductionLHSFull(n, _) -> map(\dcl :: ValueDclInfo -> (n.location, dcl), getValueDcl(n.name, top.env)) +| aspectProductionLHSFull(n, _) -> map(\dcl :: ValueDclInfo -> (n.nameLoc, dcl), getValueDcl(n.name, top.env)) end; aspect typeRefLocs on ProductionLHS using <- of @@ -209,11 +209,11 @@ end; --RHS aspect valueRefLocs on top::ProductionRHSElem using <- of -| productionRHSElem(n, _, _) -> map(\dcl :: ValueDclInfo -> (n.location, dcl), getValueDcl(n.name, top.env)) +| productionRHSElem(n, _, _) -> map(\dcl :: ValueDclInfo -> (n.nameLoc, dcl), getValueDcl(n.name, top.env)) end; aspect valueRefLocs on top::AspectRHSElem using <- of -| aspectRHSElemFull(n, _) -> map(\dcl :: ValueDclInfo -> (n.location, dcl), getValueDcl(n.name, top.env)) +| aspectRHSElemFull(n, _) -> map(\dcl :: ValueDclInfo -> (n.nameLoc, dcl), getValueDcl(n.name, top.env)) end; aspect typeRefLocs on ProductionRHSElem using <- of diff --git a/grammars/silver/compiler/metatranslation/Translation.sv b/grammars/silver/compiler/metatranslation/Translation.sv index c95ff8c8f..c3f10bb6c 100644 --- a/grammars/silver/compiler/metatranslation/Translation.sv +++ b/grammars/silver/compiler/metatranslation/Translation.sv @@ -115,19 +115,19 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs trans::(String, String, String, String) <- lookup(prodName, collectionAntiquoteProductions); return - errorExpr([err(givenLocation, s"$$${trans.1} may only occur as a member of ${trans.1}")], location=givenLocation); + errorExpr([err(givenLocation, s"$$${trans.1} may only occur as a member of ${trans.1}")]); }; antiquoteTranslation <- if contains(prodName, patternAntiquoteProductions) - then just(errorExpr([err(givenLocation, "Pattern antiquote is invalid in expression context")], location=givenLocation)) + then just(errorExpr([err(givenLocation, "Pattern antiquote is invalid in expression context")])) else nothing(); top.translation = fromMaybe( mkFullFunctionInvocation( givenLocation, - baseExpr(qName(givenLocation, prodName), location=givenLocation), + baseExpr(qName(prodName)), children.translation, filter(\ a::(String, Expr) -> a.1 != "location", annotations.translation)), antiquoteTranslation); @@ -165,14 +165,14 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs patternAntiquoteTranslation <- if contains(prodName, directAntiquoteProductions ++ map(fst, collectionAntiquoteProductions)) - then just(errorPattern([err(givenLocation, "Expression antiquote is invalid in pattern context")], location=givenLocation)) + then just(errorPattern([err(givenLocation, "Expression antiquote is invalid in pattern context")])) else nothing(); -- Note that we intentionally ignore annotations here top.patternTranslation = fromMaybe( prodAppPattern( - qName(givenLocation, prodName), + qName(prodName), '(', children.patternTranslation, ')', @@ -201,11 +201,11 @@ top::AST ::= terminalName::String lexeme::String location::Location location=top.givenLocation), ',', locationAST.translation, - ')', location=top.givenLocation); + ')'); -- TODO: What to do here- warn about this maybe? -- Shouldn't really be an issue unless matching against concrete syntax containing non-fixed terminals - top.patternTranslation = wildcPattern('_', location=top.givenLocation); + top.patternTranslation = wildcPattern('_'); } aspect production listAST @@ -215,13 +215,13 @@ top::AST ::= vals::ASTs fullList( '[', foldr( - exprsCons(_, ',', _, location=top.givenLocation), - exprsEmpty(location=top.givenLocation), + exprsCons(_, ',', _), + exprsEmpty(), vals.translation), ']', location=top.givenLocation); top.patternTranslation = - listPattern('[', vals.patternTranslation, ']', location=top.givenLocation); + listPattern('[', vals.patternTranslation, ']'); } aspect production stringAST @@ -241,18 +241,18 @@ aspect production integerAST top::AST ::= i::Integer { top.translation = - intConst(terminal(Int_t, toString(i), top.givenLocation), location=top.givenLocation); + intConst(terminal(Int_t, toString(i), top.givenLocation)); top.patternTranslation = - intPattern(terminal(Int_t, toString(i), top.givenLocation), location=top.givenLocation); + intPattern(terminal(Int_t, toString(i), top.givenLocation)); } aspect production floatAST top::AST ::= f::Float { top.translation = - floatConst(terminal(Float_t, toString(f), top.givenLocation), location=top.givenLocation); + floatConst(terminal(Float_t, toString(f), top.givenLocation)); top.patternTranslation = - fltPattern(terminal(Float_t, toString(f), top.givenLocation), location=top.givenLocation); + fltPattern(terminal(Float_t, toString(f), top.givenLocation)); } aspect production booleanAST @@ -260,12 +260,12 @@ top::AST ::= b::Boolean { top.translation = if b - then trueConst('true', location=top.givenLocation) - else falseConst('false', location=top.givenLocation); + then trueConst('true') + else falseConst('false'); top.patternTranslation = if b - then truePattern('true', location=top.givenLocation) - else falsePattern('false', location=top.givenLocation); + then truePattern('true') + else falsePattern('false'); } aspect production anyAST @@ -290,7 +290,7 @@ top::ASTs ::= h::AST t::ASTs { top.translation = h.translation :: t.translation; top.patternTranslation = - patternList_more(h.patternTranslation, ',', t.patternTranslation, location=top.givenLocation); + patternList_more(h.patternTranslation, ',', t.patternTranslation); top.foundLocation = -- Try to reify the last child as a location case t of @@ -307,7 +307,7 @@ aspect production nilAST top::ASTs ::= { top.translation = []; - top.patternTranslation = patternList_nil(location=top.givenLocation); + top.patternTranslation = patternList_nil(); top.foundLocation = nothing(); } @@ -353,8 +353,8 @@ Name ::= n::String loc::Location { return if isUpper(head(explode("", n))) - then nameIdUpper(terminal(IdUpper_t, n, loc), location=loc) - else nameIdLower(terminal(IdLower_t, n, loc), location=loc); + then nameIdUpper(terminal(IdUpper_t, n, loc)) + else nameIdLower(terminal(IdLower_t, n, loc)); } function makeQName @@ -363,8 +363,8 @@ QName ::= n::String loc::Location local ns::[Name] = map(makeName(_, loc), explode(":", n)); return foldr( - qNameCons(_, ':', _, location=loc), - qNameId(last(ns), location=loc), + qNameCons(_, ':', _), + qNameId(last(ns)), init(ns)); } @@ -374,7 +374,7 @@ QNameType ::= n::String loc::Location local ns::[String] = explode(":", n); return foldr( - qNameTypeCons(_, ':', _, location=loc), - qNameTypeId(terminal(IdUpper_t, last(ns), loc), location=loc), + qNameTypeCons(_, ':', _), + qNameTypeId(terminal(IdUpper_t, last(ns), loc)), map(makeName(_, loc), init(ns))); } diff --git a/grammars/silver/compiler/modification/collection/Collection.sv b/grammars/silver/compiler/modification/collection/Collection.sv index 1aa0e435c..b85c0fe17 100644 --- a/grammars/silver/compiler/modification/collection/Collection.sv +++ b/grammars/silver/compiler/modification/collection/Collection.sv @@ -8,7 +8,7 @@ import silver:compiler:driver:util; import silver:compiler:definition:flow:driver only ProductionGraph, FlowType, constructAnonymousGraph; import silver:compiler:translation:java:core; -nonterminal NameOrBOperator with config, location, grammarName, compiledGrammars, flowEnv, productionFlowGraphs, errors, env, unparse, operation, operatorForType; +tracked nonterminal NameOrBOperator with config, grammarName, compiledGrammars, flowEnv, productionFlowGraphs, errors, env, unparse, operation, operatorForType; propagate config, grammarName, compiledGrammars, flowEnv, productionFlowGraphs, env on NameOrBOperator; nonterminal Operation with compareTo, isEqual; @@ -36,7 +36,7 @@ top::NameOrBOperator ::= e::Expr top.errors <- if !checkOperationType.typeerror then [] - else [err(top.location, e.unparse ++ " must be of type " ++ checkOperationType.rightpp ++ + else [errFromOrigin(top, e.unparse ++ " must be of type " ++ checkOperationType.rightpp ++ " instead it is of type " ++ checkOperationType.leftpp)]; -- oh no again! @@ -66,7 +66,7 @@ top::NameOrBOperator ::= '++' top.errors := case top.operatorForType of | stringType() -> [] | listType(_) -> [] - | _ -> [err(top.location, "++ operator will only work for collections of type list or String")] + | _ -> [errFromOrigin(top, "++ operator will only work for collections of type list or String")] end; } @@ -78,7 +78,7 @@ top::NameOrBOperator ::= '||' top.operation = borOperation(); top.errors := case top.operatorForType of | boolType() -> [] - | _ -> [err(top.location, "|| operator will only work for collections of type Boolean")] + | _ -> [errFromOrigin(top, "|| operator will only work for collections of type Boolean")] end; } concrete production bandOperator @@ -89,7 +89,7 @@ top::NameOrBOperator ::= '&&' top.operation = bandOperation(); top.errors := case top.operatorForType of | boolType() -> [] - | _ -> [err(top.location, "&& operator will only work for collections of type Boolean")] + | _ -> [errFromOrigin(top, "&& operator will only work for collections of type Boolean")] end; } @@ -101,7 +101,7 @@ top::NameOrBOperator ::= '+' top.operation = addOperation(); top.errors := case top.operatorForType of | intType() -> [] - | _ -> [err(top.location, "+ operator will only work for collections of type Integer")] + | _ -> [errFromOrigin(top, "+ operator will only work for collections of type Integer")] end; } @@ -113,7 +113,7 @@ top::NameOrBOperator ::= '*' top.operation = addOperation(); top.errors := case top.operatorForType of | intType() -> [] - | _ -> [err(top.location, "* operator will only work for collections of type Integer")] + | _ -> [errFromOrigin(top, "* operator will only work for collections of type Integer")] end; } @@ -170,7 +170,7 @@ top::AGDcl ::= 'synthesized' 'attribute' a::Name tl::BracketedOptTypeExprs '::' top.errors <- if length(getAttrDclAll(fName, top.env)) > 1 - then [err(a.location, "Attribute '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(a, "Attribute '" ++ fName ++ "' is already bound.")] else []; } @@ -197,7 +197,7 @@ top::AGDcl ::= 'inherited' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te top.errors <- if length(getAttrDclAll(fName, top.env)) > 1 - then [err(a.location, "Attribute '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(a, "Attribute '" ++ fName ++ "' is already bound.")] else []; } @@ -218,7 +218,7 @@ top::ProductionStmt ::= 'production' 'attribute' a::Name '::' te::TypeExpr 'with q.operatorForType = te.typerep; top.errors <- q.errors; - forwards to productionAttributeDcl($1, $2, a, $4, te, $8, location=top.location); + forwards to productionAttributeDcl($1, $2, a, $4, te, $8); } --- The use semantics ---------------------------------------------------------- @@ -227,24 +227,24 @@ top::ProductionStmt ::= 'production' 'attribute' a::Name '::' te::TypeExpr 'with abstract production errorCollectionValueDef top::ProductionStmt ::= val::Decorated! QName e::Expr { - undecorates to valContainsBase(val, ':=', e, ';', location=top.location); + undecorates to valContainsBase(val, ':=', e, ';'); -- Override to just e.errors since we don't want the standard error message about val cannot be assigned to. top.errors := e.errors; - top.errors <- [err(top.location, "The ':=' and '<-' operators can only be used for collections. " ++ val.name ++ " is not a collection.")]; + top.errors <- [errFromOrigin(top, "The ':=' and '<-' operators can only be used for collections. " ++ val.name ++ " is not a collection.")]; - forwards to errorValueDef(val, @e, location=top.location); + forwards to errorValueDef(val, @e); } abstract production errorColNormalValueDef top::ProductionStmt ::= val::Decorated! QName e::Expr { - undecorates to valueEq(val, '=', e, ';', location=top.location); + undecorates to valueEq(val, '=', e, ';'); -- Override to just e.errors since we don't want the standard error message about val cannot be assigned to. top.errors := e.errors; - top.errors <- [err(top.location, val.name ++ " is a collection attribute, and you must use ':=' or '<-', not '='.")]; + top.errors <- [errFromOrigin(top, val.name ++ " is a collection attribute, and you must use ':=' or '<-', not '='.")]; - forwards to errorValueDef(val, @e, location=top.location); + forwards to errorValueDef(val, @e); } -- NON-ERRORS for PRODUCTIONS @@ -252,20 +252,20 @@ top::ProductionStmt ::= val::Decorated! QName e::Expr abstract production baseCollectionValueDef top::ProductionStmt ::= val::Decorated! QName e::Expr { - undecorates to valContainsBase(val, ':=', e, ';', location=top.location); + undecorates to valContainsBase(val, ':=', e, ';'); top.unparse = "\t" ++ val.unparse ++ " := " ++ e.unparse ++ ";"; -- TODO: We override the translation, so this probably shouldn't be a forwarding production... - forwards to localValueDef(val, @e, location=top.location); + forwards to localValueDef(val, @e); } abstract production appendCollectionValueDef top::ProductionStmt ::= val::Decorated! QName e::Expr { - undecorates to valContainsAppend(val, '<-', e, ';', location=top.location); + undecorates to valContainsAppend(val, '<-', e, ';'); top.unparse = "\t" ++ val.unparse ++ " <- " ++ e.unparse ++ ";"; -- TODO: We override the translation, so this probably shouldn't be a forwarding production... - forwards to localValueDef(val, @e, location=top.location); + forwards to localValueDef(val, @e); } -- NON-ERRORS for SYN ATTRS @@ -273,7 +273,7 @@ top::ProductionStmt ::= val::Decorated! QName e::Expr abstract production synBaseColAttributeDef top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr { - undecorates to attrContainsBase(dl, '.', attr, ':=', e, ';', location=top.location); + undecorates to attrContainsBase(dl, '.', attr, ':=', e, ';'); top.unparse = "\t" ++ dl.unparse ++ "." ++ attr.unparse ++ " := " ++ e.unparse ++ ";"; propagate config, grammarName, compiledGrammars, frame, env, finalSubst, originRules; @@ -288,13 +288,13 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur errCheck1 = check(attr.typerep, e.typerep); top.errors <- if errCheck1.typeerror - then [err(top.location, "Attribute " ++ attr.name ++ " has type " ++ errCheck1.leftpp ++ " but the expression being assigned to it has type " ++ errCheck1.rightpp)] + then [errFromOrigin(top, "Attribute " ++ attr.name ++ " has type " ++ errCheck1.leftpp ++ " but the expression being assigned to it has type " ++ errCheck1.rightpp)] else []; } abstract production synAppendColAttributeDef top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr { - undecorates to attrContainsAppend(dl, '.', attr, '<-', e, ';', location=top.location); + undecorates to attrContainsAppend(dl, '.', attr, '<-', e, ';'); top.unparse = "\t" ++ dl.unparse ++ "." ++ attr.unparse ++ " <- " ++ e.unparse ++ ";"; propagate config, grammarName, compiledGrammars, frame, env, finalSubst, originRules; @@ -309,7 +309,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur errCheck1 = check(attr.typerep, e.typerep); top.errors <- if errCheck1.typeerror - then [err(top.location, "Attribute " ++ attr.name ++ " has type " ++ errCheck1.leftpp ++ " but the expression being assigned to it has type " ++ errCheck1.rightpp)] + then [errFromOrigin(top, "Attribute " ++ attr.name ++ " has type " ++ errCheck1.leftpp ++ " but the expression being assigned to it has type " ++ errCheck1.rightpp)] else []; } @@ -318,7 +318,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur abstract production inhBaseColAttributeDef top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr { - undecorates to attrContainsBase(dl, '.', attr, ':=', e, ';', location=top.location); + undecorates to attrContainsBase(dl, '.', attr, ':=', e, ';'); top.unparse = "\t" ++ dl.unparse ++ "." ++ attr.unparse ++ " := " ++ e.unparse ++ ";"; propagate config, grammarName, compiledGrammars, frame, env, finalSubst, originRules; @@ -333,13 +333,13 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur errCheck1 = check(attr.typerep, e.typerep); top.errors <- if errCheck1.typeerror - then [err(top.location, "Attribute " ++ attr.name ++ " has type " ++ errCheck1.leftpp ++ " but the expression being assigned to it has type " ++ errCheck1.rightpp)] + then [errFromOrigin(top, "Attribute " ++ attr.name ++ " has type " ++ errCheck1.leftpp ++ " but the expression being assigned to it has type " ++ errCheck1.rightpp)] else []; } abstract production inhAppendColAttributeDef top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr { - undecorates to attrContainsAppend(dl, '.', attr, '<-', e, ';', location=top.location); + undecorates to attrContainsAppend(dl, '.', attr, '<-', e, ';'); top.unparse = "\t" ++ dl.unparse ++ "." ++ attr.unparse ++ " <- " ++ e.unparse ++ ";"; propagate config, grammarName, compiledGrammars, frame, env, finalSubst, originRules; @@ -354,7 +354,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur errCheck1 = check(attr.typerep, e.typerep); top.errors <- if errCheck1.typeerror - then [err(top.location, "Attribute " ++ attr.name ++ " has type " ++ errCheck1.leftpp ++ " but the expression being assigned to it has type " ++ errCheck1.rightpp)] + then [errFromOrigin(top, "Attribute " ++ attr.name ++ " has type " ++ errCheck1.leftpp ++ " but the expression being assigned to it has type " ++ errCheck1.rightpp)] else []; } @@ -378,7 +378,7 @@ top::ProductionStmt ::= dl::DefLHS '.' attr::QNameAttrOccur '<-' e::Expr ';' forwards to (if !dl.found || !attr.found - then errorAttributeDef(dl.errors ++ attr.errors, _, _, _, location=_) + then errorAttributeDef(dl.errors ++ attr.errors, _, _, _) else attr.attrDcl.attrAppendDefDispatcher)(dl, attr, e, top.location); } @@ -397,7 +397,7 @@ top::ProductionStmt ::= dl::DefLHS '.' attr::QNameAttrOccur ':=' e::Expr ';' forwards to (if !dl.found || !attr.found - then errorAttributeDef(dl.errors ++ attr.errors, _, _, _, location=_) + then errorAttributeDef(dl.errors ++ attr.errors, _, _, _) else attr.attrDcl.attrBaseDefDispatcher)(dl, attr, e, top.location); } @@ -414,7 +414,7 @@ top::ProductionStmt ::= val::QName '<-' e::Expr ';' forwards to (if null(val.lookupValue.dcls) - then errorValueDef(_, _, location=_) + then errorValueDef(_, _) else val.lookupValue.dcl.appendDefDispatcher)(val, e, top.location); } @@ -431,7 +431,7 @@ top::ProductionStmt ::= val::QName ':=' e::Expr ';' forwards to (if null(val.lookupValue.dcls) - then errorValueDef(_, _, location=_) + then errorValueDef(_, _) else val.lookupValue.dcl.baseDefDispatcher)(val, e, top.location); } diff --git a/grammars/silver/compiler/modification/collection/DclInfo.sv b/grammars/silver/compiler/modification/collection/DclInfo.sv index a1b148ec8..862579aa6 100644 --- a/grammars/silver/compiler/modification/collection/DclInfo.sv +++ b/grammars/silver/compiler/modification/collection/DclInfo.sv @@ -5,11 +5,11 @@ attribute operation, baseDefDispatcher, appendDefDispatcher occurs on ValueDclIn synthesized attribute isCollection::Boolean; -synthesized attribute attrBaseDefDispatcher :: (ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr Location); -synthesized attribute attrAppendDefDispatcher :: (ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr Location); +synthesized attribute attrBaseDefDispatcher :: (ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr); +synthesized attribute attrAppendDefDispatcher :: (ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr); -synthesized attribute baseDefDispatcher :: (ProductionStmt ::= Decorated! QName Expr Location); -synthesized attribute appendDefDispatcher :: (ProductionStmt ::= Decorated! QName Expr Location); +synthesized attribute baseDefDispatcher :: (ProductionStmt ::= Decorated! QName Expr); +synthesized attribute appendDefDispatcher :: (ProductionStmt ::= Decorated! QName Expr); aspect default production top::AttributeDclInfo ::= @@ -26,8 +26,8 @@ top::ValueDclInfo ::= { top.operation = error("Internal compiler error: must be defined for all collection attribute declarations"); - top.baseDefDispatcher = errorCollectionValueDef(_, _, location=_); - top.appendDefDispatcher = errorCollectionValueDef(_, _, location=_); + top.baseDefDispatcher = errorCollectionValueDef; + top.appendDefDispatcher = errorCollectionValueDef; } abstract production synCollectionDcl @@ -46,14 +46,14 @@ top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type o::Operation top.isCollection = true; top.operation = o; - top.decoratedAccessHandler = synDecoratedAccessHandler(_, _, location=_); - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _, location=_), _, _, _); - top.dataAccessHandler = synDataAccessHandler(_, _, location=_); + top.decoratedAccessHandler = synDecoratedAccessHandler; + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _, _); + top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = collectionAttrDefError; - top.attributionDispatcher = defaultAttributionDcl(_, _, _, _, location=_); + top.attributionDispatcher = defaultAttributionDcl; - top.attrBaseDefDispatcher = synBaseColAttributeDef(_, _, _, location=_); - top.attrAppendDefDispatcher = synAppendColAttributeDef(_, _, _, location=_); + top.attrBaseDefDispatcher = synBaseColAttributeDef; + top.attrAppendDefDispatcher = synAppendColAttributeDef; } abstract production inhCollectionDcl top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type o::Operation @@ -71,14 +71,14 @@ top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type o::Operation top.isCollection = true; top.operation = o; - top.decoratedAccessHandler = inhDecoratedAccessHandler(_, _, location=_); - top.undecoratedAccessHandler = inhUndecoratedAccessErrorHandler(_, _, location=_); - top.dataAccessHandler = inhUndecoratedAccessErrorHandler(_, _, location=_); + top.decoratedAccessHandler = inhDecoratedAccessHandler; + top.undecoratedAccessHandler = inhUndecoratedAccessErrorHandler; + top.dataAccessHandler = inhUndecoratedAccessErrorHandler; top.attrDefDispatcher = collectionAttrDefError; - top.attributionDispatcher = defaultAttributionDcl(_, _, _, _, location=_); + top.attributionDispatcher = defaultAttributionDcl; - top.attrBaseDefDispatcher = inhBaseColAttributeDef(_, _, _, location=_); - top.attrAppendDefDispatcher = inhAppendColAttributeDef(_, _, _, location=_); + top.attrBaseDefDispatcher = inhBaseColAttributeDef; + top.attrAppendDefDispatcher = inhAppendColAttributeDef; } abstract production localCollectionDcl @@ -90,12 +90,12 @@ top::ValueDclInfo ::= fn::String ty::Type o::Operation top.typeScheme = monoType(ty); top.operation = o; - top.refDispatcher = localReference(_, location=_); - top.defDispatcher = errorColNormalValueDef(_, _, location=_); - top.defLHSDispatcher = localDefLHS(_, location=_); + top.refDispatcher = localReference; + top.defDispatcher = errorColNormalValueDef; + top.defLHSDispatcher = localDefLHS; - top.baseDefDispatcher = baseCollectionValueDef(_, _, location=_); - top.appendDefDispatcher = appendCollectionValueDef(_, _, location=_); + top.baseDefDispatcher = baseCollectionValueDef; + top.appendDefDispatcher = appendCollectionValueDef; top.substitutedDclInfo = localCollectionDcl(fn, performRenaming(ty, top.givenSubstitution), o, sourceGrammar=top.sourceGrammar, sourceLocation=top.sourceLocation); @@ -104,17 +104,17 @@ top::ValueDclInfo ::= fn::String ty::Type o::Operation forwards to localDcl(fn,ty,false,sourceGrammar=top.sourceGrammar,sourceLocation=top.sourceLocation); } -global nonCollectionAttrBaseDefError::(ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr Location) = +global nonCollectionAttrBaseDefError::(ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr) = \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr l::Location -> - errorAttributeDef([err(l, "The ':=' operator can only be used for collections. " ++ attr.name ++ " is not a collection.")], dl, attr, e, location=l); + errorAttributeDef([err(l, "The ':=' operator can only be used for collections. " ++ attr.name ++ " is not a collection.")], dl, attr, e); -global nonCollectionAttrAppendDefError::(ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr Location) = +global nonCollectionAttrAppendDefError::(ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr) = \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr l::Location -> - errorAttributeDef([err(l, "The '<-' operator can only be used for collections. " ++ attr.name ++ " is not a collection.")], dl, attr, e, location=l); + errorAttributeDef([err(l, "The '<-' operator can only be used for collections. " ++ attr.name ++ " is not a collection.")], dl, attr, e); -global collectionAttrDefError::(ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr Location) = +global collectionAttrDefError::(ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr) = \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr l::Location -> - errorAttributeDef([err(l, attr.name ++ " is a collection attribute, and you must use ':=' or '<-', not '='.")], dl, attr, e, location=l); + errorAttributeDef([err(l, attr.name ++ " is a collection attribute, and you must use ':=' or '<-', not '='.")], dl, attr, e); -- Defs diff --git a/grammars/silver/compiler/modification/copper/ActionCode.sv b/grammars/silver/compiler/modification/copper/ActionCode.sv index 7a0e8df29..b6e628470 100644 --- a/grammars/silver/compiler/modification/copper/ActionCode.sv +++ b/grammars/silver/compiler/modification/copper/ActionCode.sv @@ -12,8 +12,7 @@ top::AGDcl ::= 'concrete' 'production' id::Name ns::ProductionSignature pm::Prod top.syntaxAst := [ syntaxProduction(ns.namedSignature, - foldr(consProductionMod, nilProductionMod(), prodAction(acode.actionCode) :: pm.productionModifiers), - location=top.location, sourceGrammar=top.grammarName) + foldr(consProductionMod, nilProductionMod(), prodAction(acode.actionCode) :: pm.productionModifiers), sourceGrammar=top.grammarName) ]; -- oh no again! @@ -35,14 +34,14 @@ top::AGDcl ::= 'concrete' 'production' id::Name ns::ProductionSignature pm::Prod -- note that we're not merging the typing contexts between action blocks and productions -- this seems reasonable since inference should never have effects across this border... - forwards to concreteProductionDcl($1, $2, id, ns, pm, body, location=top.location); + forwards to concreteProductionDcl($1, $2, id, ns, pm, body); } action { - insert semantic token IdFnProdDcl_t at id.location; + insert semantic token IdFnProdDcl_t at id.nameLoc; sigNames = []; } -nonterminal ActionCode_c with location,config,unparse,actionCode,env,defs,grammarName,errors,frame, compiledGrammars, flowEnv, flowDefs; +tracked nonterminal ActionCode_c withconfig,unparse,actionCode,env,defs,grammarName,errors,frame, compiledGrammars, flowEnv, flowDefs; synthesized attribute actionCode :: String; @@ -61,7 +60,7 @@ top::ActionCode_c ::= '{' stmts::ProductionStmts '}' top.errors := stmts.errors; top.errors <- if top.frame.permitPluck && !stmts.containsPluck then - [err(top.location, "Disambiguation function without pluck")] else []; + [errFromOrigin(top, "Disambiguation function without pluck")] else []; stmts.downSubst = emptySubst(); stmts.originRules = []; @@ -95,7 +94,7 @@ end; aspect errors on top::ProductionStmts using <- of | productionStmtsSnoc(h, t) -> - if top.frame.permitPluck && h.containsPluck then [err(t.location, "Statement after pluck")] else [] + if top.frame.permitPluck && h.containsPluck then [errFromOrigin(t, "Statement after pluck")] else [] end; -- TODO hacky. ideally we'd do this where local attributes are declared, not here. diff --git a/grammars/silver/compiler/modification/copper/DclInfo.sv b/grammars/silver/compiler/modification/copper/DclInfo.sv index c351ac8c9..893785d69 100644 --- a/grammars/silver/compiler/modification/copper/DclInfo.sv +++ b/grammars/silver/compiler/modification/copper/DclInfo.sv @@ -19,11 +19,11 @@ top::ValueDclInfo ::= fn::String ty::Type top.typeScheme = monoType(ty); - top.refDispatcher = parserAttributeReference(_, location=_); - top.defDispatcher = parserAttributeValueDef(_, _, location=_); - top.defLHSDispatcher = parserAttributeDefLHS(_, location=_); - top.transDefLHSDispatcher = \ q::Decorated! QName Decorated! QNameAttrOccur l::Location -> - parserAttributeDefLHS(q, location=l); + top.refDispatcher = parserAttributeReference; + top.defDispatcher = parserAttributeValueDef; + top.defLHSDispatcher = parserAttributeDefLHS; + top.transDefLHSDispatcher = \ q::Decorated! QName Decorated! QNameAttrOccur -> + parserAttributeDefLHS(q); } {-- @@ -39,10 +39,10 @@ top::ValueDclInfo ::= fn::String -- that are not part of the disambiguation set. top.typeScheme = monoType(terminalIdType()); - top.refDispatcher = pluckTerminalReference(_, location=_); - top.defDispatcher = errorValueDef(_, _, location=_); - top.defLHSDispatcher = errorDefLHS(_, location=_); - top.transDefLHSDispatcher = errorTransAttrDefLHS(_, _, location=_); + top.refDispatcher = pluckTerminalReference; + top.defDispatcher = errorValueDef; + top.defLHSDispatcher = errorDefLHS; + top.transDefLHSDispatcher = errorTransAttrDefLHS; } {-- @@ -59,10 +59,10 @@ top::ValueDclInfo ::= fn::String superClasses::[String] -- We wouldn't need a separate namespace, they could just be in the type namespace. -- Currently referencing a lexer class gives a list of its member's TerminalIds. top.typeScheme = monoType(listType(terminalIdType())); - top.refDispatcher = lexerClassReference(_, location=_); - top.defDispatcher = errorValueDef(_, _, location=_); - top.defLHSDispatcher = errorDefLHS(_, location=_); - top.transDefLHSDispatcher = errorTransAttrDefLHS(_, _, location=_); + top.refDispatcher = lexerClassReference; + top.defDispatcher = errorValueDef; + top.defLHSDispatcher = errorDefLHS; + top.transDefLHSDispatcher = errorTransAttrDefLHS; } {-- @@ -76,10 +76,10 @@ top::ValueDclInfo ::= fn::String ty::Type top.typeScheme = monoType(ty); - top.refDispatcher = termAttrValueReference(_, location=_); - top.defDispatcher = termAttrValueValueDef(_, _, location=_); - top.defLHSDispatcher = errorDefLHS(_, location=_); - top.transDefLHSDispatcher = errorTransAttrDefLHS(_, _, location=_); + top.refDispatcher = termAttrValueReference; + top.defDispatcher = termAttrValueValueDef; + top.defLHSDispatcher = errorDefLHS; + top.transDefLHSDispatcher = errorTransAttrDefLHS; } {-- @@ -93,11 +93,11 @@ top::ValueDclInfo ::= fn::String ty::Type top.typeScheme = monoType(ty); - top.refDispatcher = actionChildReference(_, location=_); - top.defDispatcher = errorValueDef(_, _, location=_); - top.defLHSDispatcher = parserAttributeDefLHS(_, location=_); -- TODO: specialize this - top.transDefLHSDispatcher = \ q::Decorated! QName Decorated! QNameAttrOccur l::Location -> - parserAttributeDefLHS(q, location=l); + top.refDispatcher = actionChildReference; + top.defDispatcher = errorValueDef; + top.defLHSDispatcher = parserAttributeDefLHS; -- TODO: specialize this + top.transDefLHSDispatcher = \ q::Decorated! QName Decorated! QNameAttrOccur -> + parserAttributeDefLHS(q); } {-- @@ -112,9 +112,9 @@ top::ValueDclInfo ::= fn::String ty::Type top.typeScheme = monoType(ty); -- TODO: use specialized ones that give better errors messages! - top.refDispatcher = parserAttributeReference(_, location=_); - top.defDispatcher = parserAttributeValueDef(_, _, location=_); - top.defLHSDispatcher = parserAttributeDefLHS(_, location=_); - top.transDefLHSDispatcher = \ q::Decorated! QName Decorated! QNameAttrOccur l::Location -> - parserAttributeDefLHS(q, location=l); + top.refDispatcher = parserAttributeReference; + top.defDispatcher = parserAttributeValueDef; + top.defLHSDispatcher = parserAttributeDefLHS; + top.transDefLHSDispatcher = \ q::Decorated! QName Decorated! QNameAttrOccur -> + parserAttributeDefLHS(q); } diff --git a/grammars/silver/compiler/modification/copper/DisambiguationGroup.sv b/grammars/silver/compiler/modification/copper/DisambiguationGroup.sv index db3a11fbf..10d17c5e8 100644 --- a/grammars/silver/compiler/modification/copper/DisambiguationGroup.sv +++ b/grammars/silver/compiler/modification/copper/DisambiguationGroup.sv @@ -24,7 +24,6 @@ top::AGDcl ::= 'disambiguate' terms::TermList acode::ActionCode_c acode.frame = disambiguationContext(myFlowGraph, sourceGrammar=top.grammarName); top.syntaxAst := - [ syntaxDisambiguationGroup(fName, terms.termList, false, acode.actionCode, - location=top.location, sourceGrammar=top.grammarName) + [ syntaxDisambiguationGroup(fName, terms.termList, false, acode.actionCode, sourceGrammar=top.grammarName) ]; } diff --git a/grammars/silver/compiler/modification/copper/Expr.sv b/grammars/silver/compiler/modification/copper/Expr.sv index 482910c8e..2110ac6d6 100644 --- a/grammars/silver/compiler/modification/copper/Expr.sv +++ b/grammars/silver/compiler/modification/copper/Expr.sv @@ -21,7 +21,7 @@ top::Expr ::= 'disambiguationFailure' abstract production actionChildReference top::Expr ::= q::Decorated! QName { - undecorates to baseExpr(q, location=top.location); + undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars := ts:fromList([q.name]); @@ -38,7 +38,7 @@ top::Expr ::= q::Decorated! QName abstract production pluckTerminalReference top::Expr ::= q::Decorated! QName { - undecorates to baseExpr(q, location=top.location); + undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars := ts:fromList([q.name]); @@ -60,12 +60,12 @@ top::Expr ::= q::Decorated! QName abstract production terminalIdReference top::Expr ::= q::Decorated! QName { - undecorates to baseExpr(q, location=top.location); + undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars := ts:fromList([q.name]); top.errors := if !top.frame.permitActions - then [err(top.location, "References to terminal identifiers can only be made in action blocks")] + then [errFromOrigin(top, "References to terminal identifiers can only be made in action blocks")] else []; top.typerep = terminalIdType(); @@ -79,12 +79,12 @@ top::Expr ::= q::Decorated! QName abstract production lexerClassReference top::Expr ::= q::Decorated! QName { - undecorates to baseExpr(q, location=top.location); + undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars := ts:fromList([q.name]); top.errors := if !top.frame.permitActions - then [err(top.location, "References to lexer class members can only be made in action blocks")] + then [errFromOrigin(top, "References to lexer class members can only be made in action blocks")] else []; -- TODO: This should be a more specific type with type classes @@ -99,12 +99,12 @@ top::Expr ::= q::Decorated! QName abstract production parserAttributeReference top::Expr ::= q::Decorated! QName { - undecorates to baseExpr(q, location=top.location); + undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars := ts:fromList([q.name]); top.errors := if !top.frame.permitActions - then [err(top.location, "References to parser attributes can only be made in action blocks")] + then [errFromOrigin(top, "References to parser attributes can only be made in action blocks")] else []; top.typerep = q.lookupValue.typeScheme.monoType; @@ -119,7 +119,7 @@ top::Expr ::= q::Decorated! QName abstract production termAttrValueReference top::Expr ::= q::Decorated! QName { - undecorates to baseExpr(q, location=top.location); + undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars := ts:fromList([q.name]); diff --git a/grammars/silver/compiler/modification/copper/LexerClass.sv b/grammars/silver/compiler/modification/copper/LexerClass.sv index 87bad0c0f..948b7593e 100644 --- a/grammars/silver/compiler/modification/copper/LexerClass.sv +++ b/grammars/silver/compiler/modification/copper/LexerClass.sv @@ -9,9 +9,9 @@ terminal IdLexerClassDcl_t '' lexer classes {IDENTIFIER, lsp:Class, lsp:Declarat concrete production lexerClassDclEmpty top::AGDcl ::= 'lexer' 'class' id::Name ';' { - forwards to lexerClassDecl($1, $2, id, lexerClassModifiersNone(location=$4.location), $4, location=top.location); + forwards to lexerClassDecl($1, $2, id, lexerClassModifiersNone(), $4); } action { - insert semantic token IdLexerClassDcl_t at id.location; + insert semantic token IdLexerClassDcl_t at id.nameLoc; } concrete production lexerClassDecl @@ -23,10 +23,10 @@ top::AGDcl ::= 'lexer' 'class' id::Name modifiers::LexerClassModifiers ';' production attribute fName :: String; fName = top.grammarName ++ ":" ++ id.name; - top.defs := [lexerClassDef(top.grammarName, id.location, fName, modifiers.superClasses)]; + top.defs := [lexerClassDef(top.grammarName, id.nameLoc, fName, modifiers.superClasses)]; top.errors <- if length(getLexerClassDcl(fName, top.env)) > 1 - then [err(id.location, "Lexer class '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(id, "Lexer class '" ++ fName ++ "' is already bound.")] else []; top.errors := modifiers.errors; @@ -36,11 +36,11 @@ top::AGDcl ::= 'lexer' 'class' id::Name modifiers::LexerClassModifiers ';' foldr(consLexerClassMod, nilLexerClassMod(), modifiers.lexerClassModifiers), location=top.location, sourceGrammar=top.grammarName)]; } action { - insert semantic token IdLexerClassDcl_t at id.location; + insert semantic token IdLexerClassDcl_t at id.nameLoc; } -nonterminal LexerClassModifiers with config, location, unparse, lexerClassModifiers, superClasses, errors, env, grammarName, compiledGrammars, flowEnv; -closed nonterminal LexerClassModifier with config, location, unparse, lexerClassModifiers, superClasses, errors, env, grammarName, compiledGrammars, flowEnv; +tracked nonterminal LexerClassModifiers with config, unparse, lexerClassModifiers, superClasses, errors, env, grammarName, compiledGrammars, flowEnv; +closed tracked nonterminal LexerClassModifier with config, unparse, lexerClassModifiers, superClasses, errors, env, grammarName, compiledGrammars, flowEnv; monoid attribute lexerClassModifiers :: [SyntaxLexerClassModifier]; diff --git a/grammars/silver/compiler/modification/copper/ParserAttributes.sv b/grammars/silver/compiler/modification/copper/ParserAttributes.sv index 998787803..266ad8f5a 100644 --- a/grammars/silver/compiler/modification/copper/ParserAttributes.sv +++ b/grammars/silver/compiler/modification/copper/ParserAttributes.sv @@ -12,7 +12,7 @@ top::AGDcl ::= 'parser' 'attribute' a::Name '::' te::TypeExpr 'action' acode::Ac top.defs := [parserAttrDef(top.grammarName, a.location, fName, te.typerep)]; top.errors <- if length(getValueDclAll(fName, top.env)) > 1 - then [err(a.location, "Attribute '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(a, "Attribute '" ++ fName ++ "' is already bound.")] else []; top.errors <- te.errorsKindStar; @@ -46,7 +46,7 @@ top::AGDcl ::= 'aspect' 'parser' 'attribute' a::QName 'action' acode::ActionCode top.defs := []; top.errors <- if null(a.lookupValue.dcls) - then [err(a.location, "Undefined attribute '" ++ a.name ++ "'.")] + then [errFromOrigin(a, "Undefined attribute '" ++ a.name ++ "'.")] else []; -- oh no again! diff --git a/grammars/silver/compiler/modification/copper/ParserDcl.sv b/grammars/silver/compiler/modification/copper/ParserDcl.sv index 62c71946d..eb0d09ccc 100644 --- a/grammars/silver/compiler/modification/copper/ParserDcl.sv +++ b/grammars/silver/compiler/modification/copper/ParserDcl.sv @@ -22,7 +22,7 @@ top::AGDcl ::= 'parser' n::Name '::' t::TypeExpr '{' m::ParserComponents '}' -- Compute the module exported defs for all grammars in the parser spec to add to the new environment production med :: ModuleExportedDefs = - moduleExportedDefs(top.location, top.compiledGrammars, m.grammarDependencies, m.moduleNames, []); + moduleExportedDefs(top.compiledGrammars, m.grammarDependencies, m.moduleNames, []); t.env = top.env; m.env = appendEnv(toEnv(med.defs, med.occursDefs), top.env); @@ -46,7 +46,7 @@ top::AGDcl ::= 'parser' n::Name '::' t::TypeExpr '{' m::ParserComponents '}' top.parserSpecs := [spec]; -- Note that this is undecorated. } -nonterminal ParserComponents with config, env, flowEnv, grammarName, location, unparse, errors, moduleNames, compiledGrammars, grammarDependencies, terminalPrefixes, grammarTerminalPrefixes, syntaxAst, genFiles; +tracked nonterminal ParserComponents with config, env, flowEnv, grammarName, unparse, errors, moduleNames, compiledGrammars, grammarDependencies, terminalPrefixes, grammarTerminalPrefixes, syntaxAst, genFiles; propagate config, env, flowEnv, grammarName, compiledGrammars, grammarDependencies, errors, moduleNames, terminalPrefixes, grammarTerminalPrefixes, syntaxAst, genFiles on ParserComponents; @@ -62,7 +62,7 @@ top::ParserComponents ::= c1::ParserComponent c2::ParserComponents top.unparse = c1.unparse ++ ", " ++ c2.unparse; } -closed nonterminal ParserComponent with config, env, flowEnv, grammarName, location, unparse, errors, moduleNames, compiledGrammars, grammarDependencies, terminalPrefixes, grammarTerminalPrefixes, syntaxAst, genFiles; +closed tracked nonterminal ParserComponent with config, env, flowEnv, grammarName, unparse, errors, moduleNames, compiledGrammars, grammarDependencies, terminalPrefixes, grammarTerminalPrefixes, syntaxAst, genFiles; propagate config, env, flowEnv, grammarName, compiledGrammars, grammarDependencies, errors, moduleNames, terminalPrefixes, grammarTerminalPrefixes, syntaxAst, genFiles on ParserComponent; @@ -83,7 +83,7 @@ top::ParserComponent ::= m::ModuleName mods::ParserComponentModifiers ';' inherited attribute componentGrammarName::String; {-- Have special env built from just this parser component and the global env -} -nonterminal ParserComponentModifiers with config, env, flowEnv, grammarName, componentGrammarName, compiledGrammars, grammarDependencies, location, unparse, errors, terminalPrefixes, grammarTerminalPrefixes, syntaxAst, genFiles; +tracked nonterminal ParserComponentModifiers with config, env, flowEnv, grammarName, componentGrammarName, compiledGrammars, grammarDependencies, unparse, errors, terminalPrefixes, grammarTerminalPrefixes, syntaxAst, genFiles; propagate config, env, flowEnv, grammarName, componentGrammarName, compiledGrammars, grammarDependencies, errors, terminalPrefixes, grammarTerminalPrefixes, syntaxAst, genFiles on ParserComponentModifiers; @@ -99,7 +99,7 @@ top::ParserComponentModifiers ::= h::ParserComponentModifier t::ParserComponentM top.unparse = h.unparse ++ t.unparse; } -nonterminal ParserComponentModifier with config, env, flowEnv, grammarName, componentGrammarName, compiledGrammars, grammarDependencies, location, unparse, errors, terminalPrefixes, grammarTerminalPrefixes, syntaxAst, genFiles; +tracked nonterminal ParserComponentModifier with config, env, flowEnv, grammarName, componentGrammarName, compiledGrammars, grammarDependencies, unparse, errors, terminalPrefixes, grammarTerminalPrefixes, syntaxAst, genFiles; propagate config, env, flowEnv, grammarName, componentGrammarName, compiledGrammars, grammarDependencies, errors, terminalPrefixes, grammarTerminalPrefixes, syntaxAst, genFiles on ParserComponentModifier; diff --git a/grammars/silver/compiler/modification/copper/Prefix.sv b/grammars/silver/compiler/modification/copper/Prefix.sv index 46e11c98c..afc1fcf8b 100644 --- a/grammars/silver/compiler/modification/copper/Prefix.sv +++ b/grammars/silver/compiler/modification/copper/Prefix.sv @@ -20,7 +20,7 @@ top::ParserComponentModifier ::= 'prefix' ts::TerminalPrefixItems 'with' s::Term inherited attribute prefixedTerminals::[String]; inherited attribute prefixedGrammars::[String]; synthesized attribute terminalPrefix::String; -nonterminal TerminalPrefix with config, env, flowEnv, grammarName, componentGrammarName, compiledGrammars, prefixedTerminals, prefixedGrammars, location, unparse, errors, syntaxAst, genFiles, terminalPrefix; +tracked nonterminal TerminalPrefix with config, env, flowEnv, grammarName, componentGrammarName, compiledGrammars, prefixedTerminals, prefixedGrammars, unparse, errors, syntaxAst, genFiles, terminalPrefix; propagate config, env, flowEnv, grammarName, componentGrammarName, compiledGrammars, errors, syntaxAst, genFiles on TerminalPrefix; @@ -31,7 +31,7 @@ top::TerminalPrefix ::= s::QName top.errors <- s.lookupType.errors; top.terminalPrefix = makeCopperName(s.lookupType.fullName); } action { - insert semantic token IdType_t at s.baseNameLoc; + insert semantic token IdType_t at s.nameLoc; } concrete production newTermModifiersTerminalPrefix @@ -60,7 +60,7 @@ concrete production newTermTerminalPrefix top::TerminalPrefix ::= r::RegExpr { top.unparse = r.unparse; - forwards to newTermModifiersTerminalPrefix(r, terminalModifiersNone(location=top.location), location=top.location); + forwards to newTermModifiersTerminalPrefix(r, terminalModifiersNone()); } concrete production seperatedTerminalPrefix @@ -70,11 +70,11 @@ top::TerminalPrefix ::= t::String_t forwards to newTermModifiersTerminalPrefix( -- We pass the string prefix as a regex that does not contain the prefix separator - regExpr(regexLiteral(substring(1, length(t.lexeme) - 1, t.lexeme)), location=top.location), + regExpr(regexLiteral(substring(1, length(t.lexeme) - 1, t.lexeme))), -- Specify which terminals this prefix prefixes. This is used to find the separator to -- append to the regex when normalizing the CST AST terminalModifierSingle( - terminalModifierUsePrefixSeperatorFor(top.prefixedTerminals, top.prefixedGrammars, location=top.location), + terminalModifierUsePrefixSeperatorFor(top.prefixedTerminals, top.prefixedGrammars), location=top.location), location=top.location); } @@ -91,7 +91,7 @@ top::TerminalModifier ::= terms::[String] grams::[String] synthesized attribute prefixItemNames::[String]; synthesized attribute isAllMarking::Boolean; -nonterminal TerminalPrefixItems with config, env, grammarName, componentGrammarName, compiledGrammars, grammarDependencies, location, unparse, errors, prefixItemNames, isAllMarking; +tracked nonterminal TerminalPrefixItems with config, env, grammarName, componentGrammarName, compiledGrammars, grammarDependencies, unparse, errors, prefixItemNames, isAllMarking; propagate config, env, grammarName, componentGrammarName, compiledGrammars, errors on TerminalPrefixItems; concrete production consTerminalPrefixItem @@ -127,7 +127,7 @@ top::TerminalPrefixItems ::= top.isAllMarking = true; } -nonterminal TerminalPrefixItem with config, env, grammarName, componentGrammarName, compiledGrammars, location, unparse, errors, prefixItemNames; +tracked nonterminal TerminalPrefixItem with config, env, grammarName, componentGrammarName, compiledGrammars, unparse, errors, prefixItemNames; propagate config, env, grammarName, componentGrammarName, compiledGrammars on TerminalPrefixItem; concrete production qNameTerminalPrefixItem @@ -137,7 +137,7 @@ top::TerminalPrefixItem ::= t::QName top.errors := t.lookupType.errors; top.prefixItemNames = [t.lookupType.fullName]; } action { - insert semantic token IdType_t at t.baseNameLoc; + insert semantic token IdType_t at t.nameLoc; } concrete production easyTerminalRefTerminalPrefixItem @@ -146,7 +146,7 @@ top::TerminalPrefixItem ::= t::EasyTerminalRef propagate env; forwards to qNameTerminalPrefixItem( - qName(top.location, head(t.dcls).fullName), + qName(head(t.dcls).fullName), location=top.location); } @@ -187,7 +187,7 @@ top::ParserComponent ::= 'prefer' t::QName 'over' ts::TermList ';' location=top.location, sourceGrammar=top.grammarName), tail(powerSet(ts.termList))); } action { - insert semantic token IdType_t at t.baseNameLoc; + insert semantic token IdType_t at t.nameLoc; } -- Prefix separator diff --git a/grammars/silver/compiler/modification/copper/ProductionStmt.sv b/grammars/silver/compiler/modification/copper/ProductionStmt.sv index da80493cd..83f589aca 100644 --- a/grammars/silver/compiler/modification/copper/ProductionStmt.sv +++ b/grammars/silver/compiler/modification/copper/ProductionStmt.sv @@ -12,11 +12,11 @@ disambiguate Insert_kwd, IdLower_t { pluck Insert_kwd; } concrete production namePrint top::Name ::= 'print' -{ forwards to name("print", top.location); } +{ forwards to name("print"); } concrete production namePluck top::Name ::= 'pluck' -{ forwards to name("pluck", top.location); } +{ forwards to name("pluck"); } concrete production pluckDef @@ -32,7 +32,7 @@ top::ProductionStmt ::= 'pluck' e::Expr ';' top.errors <- if !top.frame.permitPluck - then [err(top.location, "'pluck' allowed only in disambiguation-group parser actions.")] + then [errFromOrigin(top, "'pluck' allowed only in disambiguation-group parser actions.")] else []; e.originRules = []; @@ -42,7 +42,7 @@ top::ProductionStmt ::= 'pluck' e::Expr ';' tyCk.finalSubst = top.finalSubst; top.errors <- if tyCk.typeerror - then [err(top.location, "'pluck' expects one of the terminals it is disambiguating between. Instead it received "++tyCk.leftpp)] + then [errFromOrigin(top, "'pluck' expects one of the terminals it is disambiguating between. Instead it received "++tyCk.leftpp)] else []; thread downSubst, upSubst on top, e, tyCk, top; @@ -63,7 +63,7 @@ top::ProductionStmt ::= 'print' e::Expr ';' top.errors <- if !top.frame.permitActions - then [err(top.location, "'print' statement allowed only in parser action blocks. You may be looking for print(String,IO) :: IO.")] + then [errFromOrigin(top, "'print' statement allowed only in parser action blocks. You may be looking for print(String,IO) :: IO.")] else []; local attribute errCheck1 :: TypeCheck; errCheck1.finalSubst = top.finalSubst; @@ -76,7 +76,7 @@ top::ProductionStmt ::= 'print' e::Expr ';' errCheck1 = check(e.typerep, stringType()); top.errors <- if errCheck1.typeerror - then [err(e.location, "print expects a string, instead it recieved a " ++ errCheck1.leftpp)] + then [errFromOrigin(e, "print expects a string, instead it recieved a " ++ errCheck1.leftpp)] else []; } @@ -89,13 +89,13 @@ top::ProductionStmt ::= 'local' 'attribute' a::Name '::' te::TypeExpr ';' abstract production parserAttributeValueDef top::ProductionStmt ::= val::Decorated! QName e::Expr { - undecorates to valueEq(val, '=', e, ';', location=top.location); + undecorates to valueEq(val, '=', e, ';'); top.unparse = "\t" ++ val.unparse ++ " = " ++ e.unparse ++ ";"; propagate config, grammarName, compiledGrammars, env, frame, errors, finalSubst; top.errors <- if !top.frame.permitActions - then [err(top.location, "Assignment to parser attributes only permitted in parser action blocks")] + then [errFromOrigin(top, "Assignment to parser attributes only permitted in parser action blocks")] else []; top.translation = makeCopperName(val.lookupValue.fullName) ++ " = " ++ e.translation ++ ";\n"; @@ -110,7 +110,7 @@ top::ProductionStmt ::= val::Decorated! QName e::Expr errCheck1 = check(e.typerep, val.lookupValue.typeScheme.monoType); top.errors <- if errCheck1.typeerror - then [err(top.location, "Parser attribute " ++ val.name ++ " has type " ++ errCheck1.rightpp ++ " but the expression being assigned to it has type " ++ errCheck1.leftpp)] + then [errFromOrigin(top, "Parser attribute " ++ val.name ++ " has type " ++ errCheck1.rightpp ++ " but the expression being assigned to it has type " ++ errCheck1.leftpp)] else []; } @@ -122,7 +122,7 @@ top::ProductionStmt ::= 'pushToken' '(' val::QName ',' lexeme::Expr ')' ';' top.errors <- if !top.frame.permitActions - then [err(top.location, "Tokens may only be pushed in action blocks")] + then [errFromOrigin(top, "Tokens may only be pushed in action blocks")] else []; top.translation = "pushToken(Terminals." ++ makeCopperName(val.lookupType.fullName) ++ ", (" ++ lexeme.translation ++ ").toString()" ++ ");"; @@ -137,7 +137,7 @@ top::ProductionStmt ::= 'pushToken' '(' val::QName ',' lexeme::Expr ')' ';' errCheck1 = check(lexeme.typerep, stringType()); top.errors <- if errCheck1.typeerror - then [err(lexeme.location, "Lexeme parameter has type " ++ errCheck1.leftpp ++ " which is not a String")] + then [errFromOrigin(lexeme, "Lexeme parameter has type " ++ errCheck1.leftpp ++ " which is not a String")] else []; } @@ -149,7 +149,7 @@ top::ProductionStmt ::= 'insert' 'semantic' 'token' n::QNameType 'at' loc::Expr top.errors <- if !top.frame.permitActions - then [err(top.location, "Semantic tokens may only be inserted in action blocks")] + then [errFromOrigin(top, "Semantic tokens may only be inserted in action blocks")] else []; top.translation = s"""insertToken(new ${makeTerminalName(n.lookupType.fullName)}(new common.StringCatter(""), ${loc.translation}));"""; @@ -164,7 +164,7 @@ top::ProductionStmt ::= 'insert' 'semantic' 'token' n::QNameType 'at' loc::Expr errCheck1 = check(loc.typerep, nonterminalType("silver:core:Location", [], true, false)); top.errors <- if errCheck1.typeerror - then [err(loc.location, s"Semantic token position expected a ${errCheck1.rightpp}, but got ${errCheck1.leftpp}")] + then [errFromOrigin(loc, s"Semantic token position expected a ${errCheck1.rightpp}, but got ${errCheck1.leftpp}")] else []; } action { insert semantic token IdType_t at n.location; @@ -178,7 +178,7 @@ top::ProductionStmt ::= '{' stmts::ProductionStmts '}' top.errors <- if !top.frame.permitActions - then [err(top.location, "Block statement is only permitted in action blocks")] + then [errFromOrigin(top, "Block statement is only permitted in action blocks")] else []; top.translation = stmts.translation; @@ -197,7 +197,7 @@ top::ProductionStmt ::= 'if' '(' condition::Expr ')' th::ProductionStmt 'else' e top.errors <- if !top.frame.permitActions - then [err(top.location, "If statement is only permitted in action blocks")] + then [errFromOrigin(top, "If statement is only permitted in action blocks")] else []; top.translation = s"if(${condition.translation}) {${th.translation}} else {${el.translation}}"; @@ -222,7 +222,7 @@ top::ProductionStmt ::= 'if' '(' condition::Expr ')' th::ProductionStmt 'else' e errCheck1 = check(condition.typerep, boolType()); top.errors <- if errCheck1.typeerror - then [err(condition.location, "if condition has type " ++ errCheck1.leftpp ++ " which is not a Boolean")] + then [errFromOrigin(condition, "if condition has type " ++ errCheck1.leftpp ++ " which is not a Boolean")] else []; } @@ -230,14 +230,14 @@ concrete production ifStmt top::ProductionStmt ::= 'if' '(' condition::Expr ')' th::ProductionStmt { top.unparse = "\t" ++ "if (" ++ condition.unparse ++ ") " ++ th.unparse; - forwards to ifElseStmt($1, $2, condition, $4, th, 'else', blockStmt('{', productionStmtsNil(location=top.location), '}', location=top.location), location=top.location); + forwards to ifElseStmt($1, $2, condition, $4, th, 'else', blockStmt('{', productionStmtsNil(), '}')); } abstract production parserAttributeDefLHS top::DefLHS ::= q::Decorated! QName { - undecorates to concreteDefLHS(q, location=top.location); + undecorates to concreteDefLHS(q); top.name = q.name; top.unparse = q.unparse; top.found = false; @@ -246,8 +246,8 @@ top::DefLHS ::= q::Decorated! QName propagate errors; top.errors <- if !top.frame.permitActions - then [err(q.location, "Parser attributes can only be used in action blocks")] - else [err(q.location, "Parser action blocks are imperative, not declarative. You cannot modify the attributes of " ++ q.name ++ ". If you are trying to set inherited attributes, you should use 'decorate ... with { ... }' when you create it.")]; + then [errFromOrigin(q, "Parser attributes can only be used in action blocks")] + else [errFromOrigin(q, "Parser action blocks are imperative, not declarative. You cannot modify the attributes of " ++ q.name ++ ". If you are trying to set inherited attributes, you should use 'decorate ... with { ... }' when you create it.")]; top.translation = error("Internal compiler error: translation not defined in the presence of errors"); @@ -257,7 +257,7 @@ top::DefLHS ::= q::Decorated! QName abstract production termAttrValueValueDef top::ProductionStmt ::= val::Decorated! QName e::Expr { - undecorates to valueEq(val, '=', e, ';', location=top.location); + undecorates to valueEq(val, '=', e, ';'); top.unparse = "\t" ++ val.unparse ++ " = " ++ e.unparse ++ ";"; propagate config, grammarName, compiledGrammars, env, frame, errors, finalSubst; @@ -265,7 +265,7 @@ top::ProductionStmt ::= val::Decorated! QName e::Expr top.errors <- if val.name != "lexeme" then [] else - [err(val.location, "lexeme is not reassignable.")]; + [errFromOrigin(val, "lexeme is not reassignable.")]; local memberfunc :: String = if val.name == "filename" then "setFileName" else @@ -286,7 +286,7 @@ top::ProductionStmt ::= val::Decorated! QName e::Expr errCheck1 = check(e.typerep, val.lookupValue.typeScheme.monoType); top.errors <- if errCheck1.typeerror - then [err(top.location, "Terminal attribute " ++ val.name ++ " has type " ++ errCheck1.rightpp ++ " but the expression being assigned to it has type " ++ errCheck1.leftpp)] + then [errFromOrigin(top, "Terminal attribute " ++ val.name ++ " has type " ++ errCheck1.rightpp ++ " but the expression being assigned to it has type " ++ errCheck1.leftpp)] else []; } diff --git a/grammars/silver/compiler/modification/copper/TermList.sv b/grammars/silver/compiler/modification/copper/TermList.sv index 8220adcfa..5670f7cd9 100644 --- a/grammars/silver/compiler/modification/copper/TermList.sv +++ b/grammars/silver/compiler/modification/copper/TermList.sv @@ -5,7 +5,7 @@ grammar silver:compiler:modification:copper; -- specifically with refernce how abstract / concrete is deliniated. -- if TermPrecList has its structure refactored, so should TermList. -nonterminal TermList with config, grammarName, unparse, location, termList, defs, errors, env; +tracked nonterminal TermList with config, grammarName, unparse, termList, defs, errors, env; monoid attribute termList :: [String]; @@ -14,17 +14,17 @@ propagate config, grammarName, env, errors, termList on TermList; concrete production termListOne terms::TermList ::= t::QName { - forwards to termList(t,termListNull(location=t.location), location=t.location); + forwards to termList(t,termListNull()); } action { - insert semantic token IdType_t at t.baseNameLoc; + insert semantic token IdType_t at t.nameLoc; } concrete production termListCons terms::TermList ::= t::QName ',' terms_tail::TermList { - forwards to termList(t,terms_tail,location=terms.location); + forwards to termList(t,terms_tail); } action { - insert semantic token IdType_t at t.baseNameLoc; + insert semantic token IdType_t at t.nameLoc; } @@ -48,9 +48,9 @@ top::TermList ::= h::QName t::TermList -- Todo: Consider: should this report a different error if the element of the list -- exists but is not a terminal, i.e "Expected a terminal but got a _____"? top.errors <- if null(h.lookupType.dcls) - then [err(h.location, "Undeclared terminal '" ++ h.name ++ "'.")] + then [errFromOrigin(h, "Undeclared terminal '" ++ h.name ++ "'.")] else if length(h.lookupType.dcls) > 1 - then [err(h.location, "Ambiguous reference to terminal '" ++ h.name ++ "'. Possibilities are:\n" ++ printPossibilities(h.lookupType.dcls))] + then [errFromOrigin(h, "Ambiguous reference to terminal '" ++ h.name ++ "'. Possibilities are:\n" ++ printPossibilities(h.lookupType.dcls))] else []; } diff --git a/grammars/silver/compiler/modification/copper/TerminalDcl.sv b/grammars/silver/compiler/modification/copper/TerminalDcl.sv index 13c2e8fd7..eb5b38be9 100644 --- a/grammars/silver/compiler/modification/copper/TerminalDcl.sv +++ b/grammars/silver/compiler/modification/copper/TerminalDcl.sv @@ -56,21 +56,21 @@ top::TerminalModifier ::= 'action' acode::ActionCode_c monoid attribute precTermList :: [String]; -nonterminal TermPrecs with config, grammarName, unparse, location, precTermList, errors, env; +tracked nonterminal TermPrecs with config, grammarName, unparse, precTermList, errors, env; propagate config, grammarName, env, errors, precTermList on TermPrecs; concrete production termPrecsOne top::TermPrecs ::= t::QName { - forwards to termPrecs(termPrecList(t,termPrecListNull(location=t.location), location=t.location), location=top.location); + forwards to termPrecs(termPrecList(t,termPrecListNull())); } action { - insert semantic token IdType_t at t.baseNameLoc; + insert semantic token IdType_t at t.nameLoc; } concrete production termPrecsList top::TermPrecs ::= '{' terms::TermPrecList '}' { - forwards to termPrecs(terms,location=top.location); + forwards to termPrecs(terms); } abstract production termPrecs @@ -79,7 +79,7 @@ top::TermPrecs ::= terms::TermPrecList top.unparse = s"{${terms.unparse}}"; } -nonterminal TermPrecList with config, grammarName, unparse, location, precTermList, errors, env; +tracked nonterminal TermPrecList with config, grammarName, unparse, precTermList, errors, env; propagate config, grammarName, env, errors, precTermList on TermPrecList; abstract production termPrecList @@ -95,9 +95,9 @@ top::TermPrecList ::= h::QName t::TermPrecList -- Since we're looking it up in two ways, do the errors ourselves top.errors <- if null(h.lookupType.dcls) && null(h.lookupLexerClass.dcls) - then [err(h.location, "Undeclared terminal or lexer class '" ++ h.name ++ "'.")] + then [errFromOrigin(h, "Undeclared terminal or lexer class '" ++ h.name ++ "'.")] else if length(h.lookupType.dcls) + length(h.lookupLexerClass.dcls) > 1 - then [err(h.location, "Ambiguous reference to terminal or lexer class '" ++ h.name ++ "'. Possibilities are:\n" ++ + then [errFromOrigin(h, "Ambiguous reference to terminal or lexer class '" ++ h.name ++ "'. Possibilities are:\n" ++ printPossibilities(h.lookupType.dcls) ++ if !null(h.lookupLexerClass.dcls) then ", " ++ printPossibilities(h.lookupLexerClass.dcls) else "")] else []; } @@ -111,34 +111,34 @@ top::TermPrecList ::= concrete production termPrecListOne top::TermPrecList ::= t::QName { - forwards to termPrecList(t, termPrecListNull(location=top.location), location=top.location); + forwards to termPrecList(t, termPrecListNull()); } action { - insert semantic token IdType_t at t.baseNameLoc; + insert semantic token IdType_t at t.nameLoc; } concrete production termPrecListCons top::TermPrecList ::= t::QName ',' terms_tail::TermPrecList { - forwards to termPrecList(t, terms_tail,location=top.location); + forwards to termPrecList(t, terms_tail); } action { - insert semantic token IdType_t at t.baseNameLoc; + insert semantic token IdType_t at t.nameLoc; } -nonterminal LexerClasses with location, config, unparse, lexerClasses, errors, env; +tracked nonterminal LexerClasses with config, unparse, lexerClasses, errors, env; propagate config, env, errors, lexerClasses on LexerClasses; concrete production lexerClassesOne top::LexerClasses ::= n::QName { - forwards to lexerClasses(lexerClassListMain(n, lexerClassListNull(location=top.location), location=top.location), location=top.location); + forwards to lexerClasses(lexerClassListMain(n, lexerClassListNull())); } action { - insert semantic token IdLexerClassDcl_t at n.baseNameLoc; + insert semantic token IdLexerClassDcl_t at n.nameLoc; } concrete production lexerClassesList top::LexerClasses ::= '{' cls::LexerClassList '}' { - forwards to lexerClasses(cls,location=top.location); + forwards to lexerClasses(cls); } abstract production lexerClasses @@ -147,23 +147,23 @@ top::LexerClasses ::= cls::LexerClassList top.unparse = s"{${cls.unparse}}"; } -nonterminal LexerClassList with location, config, unparse, lexerClasses, errors, env; +tracked nonterminal LexerClassList with config, unparse, lexerClasses, errors, env; propagate config, env, errors, lexerClasses on LexerClassList; concrete production lexerClassListOne top::LexerClassList ::= n::QName { - forwards to lexerClassListMain(n,lexerClassListNull(location=n.location), location=n.location); + forwards to lexerClassListMain(n,lexerClassListNull()); } action { - insert semantic token IdLexerClassDcl_t at n.baseNameLoc; + insert semantic token IdLexerClassDcl_t at n.nameLoc; } concrete production lexerClassListCons top::LexerClassList ::= n::QName ',' cl_tail::LexerClassList { - forwards to lexerClassListMain(n,cl_tail,location=top.location); + forwards to lexerClassListMain(n,cl_tail); } action { - insert semantic token IdLexerClassDcl_t at n.baseNameLoc; + insert semantic token IdLexerClassDcl_t at n.nameLoc; } diff --git a/grammars/silver/compiler/modification/copper_mda/Analysis.sv b/grammars/silver/compiler/modification/copper_mda/Analysis.sv index 1269e1a06..8b612fd4d 100644 --- a/grammars/silver/compiler/modification/copper_mda/Analysis.sv +++ b/grammars/silver/compiler/modification/copper_mda/Analysis.sv @@ -27,7 +27,7 @@ top::AGDcl ::= 'copper_mda' testname::Name '(' orig::QName ')' '{' m::ParserComp head(searchEnvTree(orig.lookupValue.dcl.sourceGrammar, top.compiledGrammars)).parserSpecs); top.errors <- if !orig.lookupValue.found || !null(spec) then [] - else [err(orig.location, orig.name ++ " is not a parser.")]; + else [errFromOrigin(orig, orig.name ++ " is not a parser.")]; -- Ignoring prefixes and any SyntaxDcls generated by the ParserComponents for now... top.mdaSpecs = @@ -46,7 +46,7 @@ function findSpec else findSpec(n, tail(s)); } -nonterminal MdaSpec with location, sourceGrammar, fullName, compiledGrammars,cstAst; +tracked nonterminal MdaSpec with sourceGrammar, fullName, compiledGrammars,cstAst; abstract production mdaSpec top::MdaSpec ::= fn::String snt::String hostgrams::[String] extgrams::[String] customStartLayout::Maybe<[String]> diff --git a/grammars/silver/compiler/modification/defaultattr/DefaultAttr.sv b/grammars/silver/compiler/modification/defaultattr/DefaultAttr.sv index 781534923..c824bd80f 100644 --- a/grammars/silver/compiler/modification/defaultattr/DefaultAttr.sv +++ b/grammars/silver/compiler/modification/defaultattr/DefaultAttr.sv @@ -24,7 +24,7 @@ top::AGDcl ::= 'aspect' 'default' 'production' ns::AspectDefaultProductionSignat propagate config, grammarName, compiledGrammars, errors; - local sigDefs :: [Def] = addNewLexicalTyVars(top.grammarName, top.location, ns.lexicalTyVarKinds, ns.lexicalTypeVariables); + local sigDefs :: [Def] = addNewLexicalTyVars(top.grammarName, ns.lexicalTyVarKinds, ns.lexicalTypeVariables); -- oh no again! local myFlow :: EnvTree = head(searchEnvTree(top.grammarName, top.compiledGrammars)).grammarFlowTypes; @@ -47,7 +47,7 @@ top::AGDcl ::= 'aspect' 'default' 'production' ns::AspectDefaultProductionSignat sigNames = []; } -nonterminal AspectDefaultProductionSignature with config, grammarName, env, flowEnv, location, unparse, errors, defs, namedSignature, lexicalTypeVariables, lexicalTyVarKinds; +tracked nonterminal AspectDefaultProductionSignature with config, grammarName, env, flowEnv, unparse, errors, defs, namedSignature, lexicalTypeVariables, lexicalTyVarKinds; concrete production aspectDefaultProductionSignature top::AspectDefaultProductionSignature ::= lhs::Name '::' te::TypeExpr '::=' @@ -68,7 +68,7 @@ top::AspectDefaultProductionSignature ::= lhs::Name '::' te::TypeExpr '::=' top.errors <- if checkNT.typeerror - then [err(top.location, "Default production LHS type must be a nonterminal. Instead it is of type " ++ checkNT.leftpp)] + then [errFromOrigin(top, "Default production LHS type must be a nonterminal. Instead it is of type " ++ checkNT.leftpp)] else []; top.errors <- te.errorsKindStar; @@ -96,16 +96,16 @@ top::ValueDclInfo ::= fn::String ty::Type top.typeScheme = monoType(ty); - top.refDispatcher = lhsReference(_, location=_); - top.defDispatcher = errorValueDef(_, _, location=_); -- TODO: be smarter about the error message - top.defLHSDispatcher = defaultLhsDefLHS(_, location=_); - top.transDefLHSDispatcher = errorTransAttrDefLHS(_, _, location=_); + top.refDispatcher = lhsReference; + top.defDispatcher = errorValueDef; -- TODO: be smarter about the error message + top.defLHSDispatcher = defaultLhsDefLHS; + top.transDefLHSDispatcher = errorTransAttrDefLHS; } abstract production defaultLhsDefLHS top::DefLHS ::= q::Decorated! QName { - undecorates to concreteDefLHS(q, location=top.location); + undecorates to concreteDefLHS(q); top.name = q.name; top.unparse = q.unparse; top.found = !existingProblems && top.defLHSattr.attrDcl.isSynthesized; @@ -114,7 +114,7 @@ top::DefLHS ::= q::Decorated! QName top.errors := if existingProblems || top.found then [] - else [err(q.location, "Cannot define inherited attribute '" ++ top.defLHSattr.name ++ "' on the lhs '" ++ q.name ++ "'")]; + else [errFromOrigin(q, "Cannot define inherited attribute '" ++ top.defLHSattr.name ++ "' on the lhs '" ++ q.name ++ "'")]; top.typerep = q.lookupValue.typeScheme.monoType; diff --git a/grammars/silver/compiler/modification/ffi/FunctionDcl.sv b/grammars/silver/compiler/modification/ffi/FunctionDcl.sv index 903459ae2..8f2e84e25 100644 --- a/grammars/silver/compiler/modification/ffi/FunctionDcl.sv +++ b/grammars/silver/compiler/modification/ffi/FunctionDcl.sv @@ -2,8 +2,8 @@ grammar silver:compiler:modification:ffi; terminal FFI_kwd 'foreign' lexer classes {KEYWORD,RESERVED}; -nonterminal FFIDefs with config, location, grammarName, errors, env, unparse; -nonterminal FFIDef with config, location, grammarName, errors, env, unparse; +tracked nonterminal FFIDefs with config, grammarName, errors, env, unparse; +tracked nonterminal FFIDef with config, grammarName, errors, env, unparse; concrete production functionDclFFI top::AGDcl ::= 'function' id::Name ns::FunctionSignature body::ProductionBody 'foreign' '{' ffidefs::FFIDefs '}' @@ -18,9 +18,9 @@ top::AGDcl ::= 'function' id::Name ns::FunctionSignature body::ProductionBody 'f -- TODO this is a BS use of forwarding and should be eliminated. - forwards to functionDcl($1, @id, @ns, @body, location=top.location); + forwards to functionDcl($1, @id, @ns, @body); } action { - insert semantic token IdFnProdDcl_t at id.location; + insert semantic token IdFnProdDcl_t at id.nameLoc; sigNames = []; } diff --git a/grammars/silver/compiler/modification/ffi/TypeDcl.sv b/grammars/silver/compiler/modification/ffi/TypeDcl.sv index 808a80325..cacd564d8 100644 --- a/grammars/silver/compiler/modification/ffi/TypeDcl.sv +++ b/grammars/silver/compiler/modification/ffi/TypeDcl.sv @@ -11,10 +11,10 @@ concrete production ffiTypeDclLegacy top::AGDcl ::= 'type' id::Name tl::BracketedOptTypeExprs 'foreign' ';' { local obj :: String_t = terminal(String_t, "\"Object\""); - --forwards to ffiTypeDcl('foreign', 'type', id, tl, '=', obj, ';', location=top.location); - forwards to ffiTypeDclUgly('type', id, tl, 'foreign', '=', obj, ';', location=top.location); + --forwards to ffiTypeDcl('foreign', 'type', id, tl, '=', obj, ';'); + forwards to ffiTypeDclUgly('type', id, tl, 'foreign', '=', obj, ';'); } action { - insert semantic token IdTypeDcl_t at id.location; + insert semantic token IdTypeDcl_t at id.nameLoc; } @@ -41,7 +41,7 @@ top::AGDcl ::= 'type' id::Name tl::BracketedOptTypeExprs 'foreign' '=' trans::St -- Strip quotes local transType :: String = substring(1, length(trans.lexeme) - 1, trans.lexeme); - top.defs := [typeAliasDef(top.grammarName, id.location, fName, [], tl.freeVariables, foreignType(fName, transType, tl.types))]; + top.defs := [typeAliasDef(top.grammarName, id.nameLoc, fName, [], tl.freeVariables, foreignType(fName, transType, tl.types))]; propagate grammarName, errors, flowDefs, flowEnv; top.errors <- tl.errorsTyVars; @@ -53,14 +53,14 @@ top::AGDcl ::= 'type' id::Name tl::BracketedOptTypeExprs 'foreign' '=' trans::St -- Redefinition check of the name top.errors <- if length(getTypeDclAll(fName, top.env)) > 1 - then [err(id.location, "Type '" ++ fName ++ "' is already bound.")] + then [errFromOrigin(id, "Type '" ++ fName ++ "' is already bound.")] else []; top.errors <- if isLower(substring(0, 1, id.name)) - then [err(id.location, "Types must be capitalized. Invalid foreign type name " ++ id.name)] + then [errFromOrigin(id, "Types must be capitalized. Invalid foreign type name " ++ id.name)] else []; } action { - insert semantic token IdTypeDcl_t at id.location; + insert semantic token IdTypeDcl_t at id.nameLoc; } diff --git a/grammars/silver/compiler/modification/ffi/java/FunctionDcl.sv b/grammars/silver/compiler/modification/ffi/java/FunctionDcl.sv index 4cced97f3..5fffd0900 100644 --- a/grammars/silver/compiler/modification/ffi/java/FunctionDcl.sv +++ b/grammars/silver/compiler/modification/ffi/java/FunctionDcl.sv @@ -69,7 +69,7 @@ top::AGDcl ::= 'function' id::Name ns::FunctionSignature body::ProductionBody 'f )]; top.errors <- if length(ffidefs.ffiTranslationString) > 1 - then [err(ffidefs.location, "There is more than one Java translation in this FFI function")] + then [errFromOrigin(ffidefs, "There is more than one Java translation in this FFI function")] else []; } diff --git a/grammars/silver/compiler/modification/lambda_fn/DclInfo.sv b/grammars/silver/compiler/modification/lambda_fn/DclInfo.sv index 5539fa6d1..4f6dbfe5a 100644 --- a/grammars/silver/compiler/modification/lambda_fn/DclInfo.sv +++ b/grammars/silver/compiler/modification/lambda_fn/DclInfo.sv @@ -20,10 +20,10 @@ top::ValueDclInfo ::= fn::String ty::Type id::Integer paramIndex::Integer top.lambdaParamIndex = paramIndex; top.lambdaId = id; - top.refDispatcher = lambdaParamReference(_, location=_); - top.defDispatcher = errorValueDef(_, _, location=_); -- should be impossible (never in scope at production level?) - top.defLHSDispatcher = errorDefLHS(_, location=_); -- ditto - top.transDefLHSDispatcher = errorTransAttrDefLHS(_, _, location=_); + top.refDispatcher = lambdaParamReference; + top.defDispatcher = errorValueDef; -- should be impossible (never in scope at production level?) + top.defLHSDispatcher = errorDefLHS; -- ditto + top.transDefLHSDispatcher = errorTransAttrDefLHS; } function lambdaParamDef diff --git a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv index afb9bfdf6..c293967a7 100644 --- a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv +++ b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv @@ -14,7 +14,7 @@ top::Expr ::= '\' params::ProductionRHS '->' e::Expr { top.unparse = "\\ " ++ params.unparse ++ " -> " ++ e.unparse; - forwards to lambdap(params, e, location=top.location); + forwards to lambdap(params, e); } abstract production lambdap @@ -77,7 +77,7 @@ top::ProductionRHSElem ::= id::Name '::' t::TypeExpr abstract production lambdaParamReference top::Expr ::= q::Decorated! QName { - undecorates to baseExpr(q, location=top.location); + undecorates to baseExpr(q); top.unparse = q.unparse; propagate errors; top.freeVars := ts:fromList([q.name]); diff --git a/grammars/silver/compiler/modification/let_fix/DclInfo.sv b/grammars/silver/compiler/modification/let_fix/DclInfo.sv index 194ec8b10..9d9d02a8c 100644 --- a/grammars/silver/compiler/modification/let_fix/DclInfo.sv +++ b/grammars/silver/compiler/modification/let_fix/DclInfo.sv @@ -15,10 +15,10 @@ top::ValueDclInfo ::= fn::String ty::Type fi::Maybe fd::[FlowVertex] top.typeScheme = monoType(ty); - top.refDispatcher = lexicalLocalReference(_, fi, fd, rs, location=_); - top.defDispatcher = errorValueDef(_, _, location=_); -- should be impossible (never in scope at production level?) - top.defLHSDispatcher = errorDefLHS(_, location=_); -- ditto - top.transDefLHSDispatcher = errorTransAttrDefLHS(_, _, location=_); + top.refDispatcher = lexicalLocalReference(_, fi, fd, rs); + top.defDispatcher = errorValueDef; -- should be impossible (never in scope at production level?) + top.defLHSDispatcher = errorDefLHS; -- ditto + top.transDefLHSDispatcher = errorTransAttrDefLHS; } function lexicalLocalDef diff --git a/grammars/silver/compiler/modification/let_fix/Let.sv b/grammars/silver/compiler/modification/let_fix/Let.sv index ece715488..dc2175bb5 100644 --- a/grammars/silver/compiler/modification/let_fix/Let.sv +++ b/grammars/silver/compiler/modification/let_fix/Let.sv @@ -14,10 +14,10 @@ top::Expr ::= 'let' la::LetAssigns 'in' e::Expr 'end' { top.unparse = "let " ++ la.unparse ++ " in " ++ e.unparse ++ " end"; - forwards to letp(la.letAssignExprs, e, location=top.location); + forwards to letp(la.letAssignExprs, e); } -nonterminal LetAssigns with unparse, location, letAssignExprs; +tracked nonterminal LetAssigns with unparse, letAssignExprs; synthesized attribute letAssignExprs :: AssignExpr; @@ -25,7 +25,7 @@ concrete production assignsListCons top::LetAssigns ::= ae::AssignExpr ',' list::LetAssigns { top.unparse = ae.unparse ++ ", " ++ list.unparse; - top.letAssignExprs = appendAssignExpr(ae, list.letAssignExprs, location=top.location); + top.letAssignExprs = appendAssignExpr(ae, list.letAssignExprs); } concrete production assignListSingle top::LetAssigns ::= ae::AssignExpr @@ -59,7 +59,7 @@ top::Expr ::= la::AssignExpr e::Expr monoid attribute boundNames::[String]; -nonterminal AssignExpr with location, config, grammarName, env, compiledGrammars, +tracked nonterminal AssignExpr with config, grammarName, env, compiledGrammars, unparse, defs, errors, boundNames, freeVars, upSubst, downSubst, finalSubst, frame, originRules; @@ -95,13 +95,13 @@ top::AssignExpr ::= id::Name '::' t::TypeExpr '=' e::Expr -- auto-undecorate feature, so that's why we bother substituting. -- (er, except that we're starting with t, which is a Type... must be because we fake these -- in e.g. the pattern matching code, so type variables might appear there?) - top.defs <- [lexicalLocalDef(top.grammarName, id.location, fName, semiTy, e.flowVertexInfo, e.flowDeps, e.uniqueRefs)]; + top.defs <- [lexicalLocalDef(top.grammarName, id.nameLoc, fName, semiTy, e.flowVertexInfo, e.flowDeps, e.uniqueRefs)]; -- TODO: At present, this isn't working properly, because the local scope is -- whatever scope encloses the real local scope... hrmm! top.errors <- if length(getValueDclInScope(id.name, top.env)) > 1 - then [err(id.location, "Value '" ++ id.name ++ "' is already bound.")] + then [errFromOrigin(id, "Value '" ++ id.name ++ "' is already bound.")] else []; top.errors <- t.errorsKindStar; @@ -113,7 +113,7 @@ top::AssignExpr ::= id::Name '::' t::TypeExpr '=' e::Expr errCheck1 = check(e.typerep, t.typerep); top.errors <- if errCheck1.typeerror - then [err(id.location, "Value " ++ id.name ++ " declared with type " ++ errCheck1.rightpp ++ " but the expression being assigned to it has type " ++ errCheck1.leftpp)] + then [errFromOrigin(id, "Value " ++ id.name ++ " declared with type " ++ errCheck1.rightpp ++ " but the expression being assigned to it has type " ++ errCheck1.leftpp)] else []; e.isRoot = false; @@ -122,7 +122,7 @@ top::AssignExpr ::= id::Name '::' t::TypeExpr '=' e::Expr abstract production lexicalLocalReference top::Expr ::= q::Decorated! QName fi::Maybe fd::[FlowVertex] rs::[(String, UniqueRefSite)] { - undecorates to baseExpr(q, location=top.location); + undecorates to baseExpr(q); top.unparse = q.unparse; top.errors := []; top.freeVars := ts:fromList([q.name]); diff --git a/grammars/silver/compiler/modification/list/List.sv b/grammars/silver/compiler/modification/list/List.sv index f8584cb89..40e334090 100644 --- a/grammars/silver/compiler/modification/list/List.sv +++ b/grammars/silver/compiler/modification/list/List.sv @@ -16,14 +16,13 @@ top::TypeExpr ::= '[' te::TypeExpr ']' top.errorsKindStar := if top.typerep.kindrep != starKind() - then [err(top.location, s"${top.unparse} has kind ${prettyKind(top.typerep.kindrep)}, but kind * is expected here")] + then [errFromOrigin(top, s"${top.unparse} has kind ${prettyKind(top.typerep.kindrep)}, but kind * is expected here")] else []; forwards to appTypeExpr( - listCtrTypeExpr('[', ']', location=top.location), - bTypeList('<', typeListSingle(te, location=te.location), '>', location=top.location), - location=top.location); + listCtrTypeExpr('[', ']'), + bTypeList('<', typeListSingle(te), '>')); } concrete production listCtrTypeExpr @@ -35,10 +34,10 @@ top::TypeExpr ::= '[' ']' top.errorsKindStar := if top.typerep.kindrep != starKind() - then [err(top.location, s"${top.unparse} has kind ${prettyKind(top.typerep.kindrep)}, but kind * is expected here")] + then [errFromOrigin(top, s"${top.unparse} has kind ${prettyKind(top.typerep.kindrep)}, but kind * is expected here")] else []; - forwards to typerepTypeExpr(listCtrType(),location=top.location); + forwards to typerepTypeExpr(listCtrType()); } -- The expressions ------------------------------------------------------------- @@ -67,18 +66,15 @@ top::Expr ::= h::Expr '::' t::Expr forwards to application( baseExpr( - qName(top.location, "silver:core:cons"), - location=top.location), '(', + qName("silver:core:cons")), '(', snocAppExprs( snocAppExprs( - emptyAppExprs(location=top.location), ',', - presentAppExpr(@h, location=top.location), - location=top.location), ',', - presentAppExpr(@t, location=top.location), - location=top.location), + emptyAppExprs(), ',', + presentAppExpr(@h)), ',', + presentAppExpr(@t)), ',', - emptyAnnoAppExprs(location=top.location), - ')', location=top.location); + emptyAnnoAppExprs(), + ')'); } concrete production fullList @@ -94,17 +90,17 @@ synthesized attribute listtrans :: Expr occurs on Exprs; aspect production exprsEmpty top::Exprs ::= { - top.listtrans = emptyList('[',']', location=top.location); + top.listtrans = emptyList('[',']'); } aspect production exprsSingle top::Exprs ::= e::Expr { - top.listtrans = consListOp(e, '::', emptyList('[',']', location=top.location), location=top.location); + top.listtrans = consListOp(e, '::', emptyList('[',']')); } aspect production exprsCons top::Exprs ::= e1::Expr ',' e2::Exprs { - top.listtrans = consListOp(e1, '::', e2.listtrans, location=top.location); + top.listtrans = consListOp(e1, '::', e2.listtrans); } diff --git a/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv b/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv index 3f38fdd16..18de9cf5d 100644 --- a/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv +++ b/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv @@ -23,14 +23,14 @@ import silver:compiler:modification:list; -- Oh no, this is a hack! TODO terminal Match_kwd 'match' lexer classes {KEYWORD,RESERVED}; -- temporary!!! -nonterminal PrimPatterns with +tracked nonterminal PrimPatterns with config, grammarName, env, compiledGrammars, frame, - location, unparse, errors, freeVars, + unparse, errors, freeVars, downSubst, upSubst, finalSubst, scrutineeType, returnType, translation, initTransDecSites, originRules; -nonterminal PrimPattern with +tracked nonterminal PrimPattern with config, grammarName, env, compiledGrammars, frame, - location, unparse, errors, freeVars, + unparse, errors, freeVars, downSubst, upSubst, finalSubst, scrutineeType, returnType, translation, initTransDecSites, originRules; @@ -46,7 +46,7 @@ top::Expr ::= 'match' e::Expr 'return' t::TypeExpr 'with' pr::PrimPatterns 'else { top.unparse = "match " ++ e.unparse ++ " return " ++ t.unparse ++ " with " ++ pr.unparse ++ " else -> " ++ f.unparse ++ "end"; - forwards to matchPrimitive(e, t, pr, f, location=top.location); + forwards to matchPrimitive(e, t, pr, f); } abstract production matchPrimitive top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr @@ -62,9 +62,9 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr forwards to matchPrimitiveReal( if isDecorable(performSubstitution(e.typerep, e.upSubst), e.env) - then decorateExprWithEmpty('decorate', @e, 'with', '{', '}', location=e.location) + then decorateExprWithEmpty('decorate', @e, 'with', '{', '}') else @e, - t, pr, f, location=top.location); + t, pr, f); } {-- @@ -94,7 +94,7 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr errCheck2 = check(f.typerep, t.typerep); top.errors <- if errCheck2.typeerror - then [err(top.location, "pattern expression should have type " ++ errCheck2.rightpp ++ " instead it has type " ++ errCheck2.leftpp)] + then [errFromOrigin(top, "pattern expression should have type " ++ errCheck2.rightpp ++ " instead it has type " ++ errCheck2.leftpp)] else []; -- ordinary threading: e, pr, f, errCheck2 @@ -192,8 +192,8 @@ top::PrimPattern ::= qn::QName '(' ns::VarBinders ')' '->' e::Expr -- the code. After it works, perhaps these can be merged into one non-forwarding -- production, once the code is understood fully. forwards to if isGadt - then prodPatternGadt(qn, ns, e, location=top.location) - else prodPatternNormal(qn, ns, e, location=top.location); + then prodPatternGadt(qn, ns, e) + else prodPatternNormal(qn, ns, e); } abstract production prodPatternNormal top::PrimPattern ::= qn::Decorated QName ns::VarBinders e::Expr @@ -204,14 +204,14 @@ top::PrimPattern ::= qn::Decorated QName ns::VarBinders e::Expr local chk :: [Message] = if null(qn.lookupValue.dcls) || ns.varBinderCount == prod_type.arity then [] - else [err(qn.location, qn.name ++ " has " ++ toString(prod_type.arity) ++ " parameters but " ++ toString(ns.varBinderCount) ++ " patterns were provided")]; + else [errFromOrigin(qn, qn.name ++ " has " ++ toString(prod_type.arity) ++ " parameters but " ++ toString(ns.varBinderCount) ++ " patterns were provided")]; top.errors <- qn.lookupValue.errors; top.errors <- case qn.lookupValue.dcls of | prodDcl (_, _) :: _ -> [] | [] -> [] - | _ -> [err(qn.location, qn.name ++ " is not a production.")] + | _ -> [errFromOrigin(qn, qn.name ++ " is not a production.")] end; -- Turns the existential variables existential @@ -247,12 +247,12 @@ top::PrimPattern ::= qn::Decorated QName ns::VarBinders e::Expr errCheck1 = check(expectedScrutineeType, top.scrutineeType); top.errors <- if errCheck1.typeerror - then [err(top.location, qn.name ++ " has type " ++ errCheck1.leftpp ++ " but we're trying to match against " ++ errCheck1.rightpp)] + then [errFromOrigin(top, qn.name ++ " has type " ++ errCheck1.leftpp ++ " but we're trying to match against " ++ errCheck1.rightpp)] else []; errCheck2 = check(e.typerep, top.returnType); top.errors <- if errCheck2.typeerror - then [err(e.location, "pattern expression should have type " ++ errCheck2.rightpp ++ " instead it has type " ++ errCheck2.leftpp)] + then [errFromOrigin(e, "pattern expression should have type " ++ errCheck2.rightpp ++ " instead it has type " ++ errCheck2.leftpp)] else []; -- Thread NORMALLY! YAY! @@ -287,14 +287,14 @@ top::PrimPattern ::= qn::Decorated QName ns::VarBinders e::Expr local chk :: [Message] = if null(qn.lookupValue.dcls) || ns.varBinderCount == prod_type.arity then [] - else [err(qn.location, qn.name ++ " has " ++ toString(prod_type.arity) ++ " parameters but " ++ toString(ns.varBinderCount) ++ " patterns were provided")]; + else [errFromOrigin(qn, qn.name ++ " has " ++ toString(prod_type.arity) ++ " parameters but " ++ toString(ns.varBinderCount) ++ " patterns were provided")]; top.errors <- qn.lookupValue.errors; top.errors <- case qn.lookupValue.dcls of | prodDcl (_, _) :: _ -> [] | [] -> [] - | _ -> [err(qn.location, qn.name ++ " is not a production.")] + | _ -> [errFromOrigin(qn, qn.name ++ " is not a production.")] end; local prod_contexts_type :: Pair<[Context] Type> = fullySkolemizeProductionType(qn.lookupValue.typeScheme); -- that says FULLY. See the comments on that function. @@ -327,12 +327,12 @@ top::PrimPattern ::= qn::Decorated QName ns::VarBinders e::Expr errCheck1 = check(expectedScrutineeType, top.scrutineeType); top.errors <- if errCheck1.typeerror - then [err(top.location, qn.name ++ " has type " ++ errCheck1.leftpp ++ " but we're trying to match against " ++ errCheck1.rightpp)] + then [errFromOrigin(top, qn.name ++ " has type " ++ errCheck1.leftpp ++ " but we're trying to match against " ++ errCheck1.rightpp)] else []; errCheck2 = check(e.typerep, top.returnType); top.errors <- if errCheck2.typeerror - then [err(e.location, "pattern expression should have type " ++ errCheck2.rightpp ++ " instead it has type " ++ errCheck2.leftpp)] + then [errFromOrigin(e, "pattern expression should have type " ++ errCheck2.rightpp ++ " instead it has type " ++ errCheck2.leftpp)] else []; -- For GADTs, threading gets a bit weird. @@ -383,12 +383,12 @@ top::PrimPattern ::= i::Int_t '->' e::Expr errCheck1 = check(intType(), top.scrutineeType); top.errors <- if errCheck1.typeerror - then [err(top.location, i.lexeme ++ " is an " ++ errCheck1.leftpp ++ " but we're trying to match against " ++ errCheck1.rightpp)] + then [errFromOrigin(top, i.lexeme ++ " is an " ++ errCheck1.leftpp ++ " but we're trying to match against " ++ errCheck1.rightpp)] else []; errCheck2 = check(e.typerep, top.returnType); top.errors <- if errCheck2.typeerror - then [err(e.location, "pattern expression should have type " ++ errCheck2.rightpp ++ " instead it has type " ++ errCheck2.leftpp)] + then [errFromOrigin(e, "pattern expression should have type " ++ errCheck2.rightpp ++ " instead it has type " ++ errCheck2.leftpp)] else []; thread downSubst, upSubst on top, errCheck1, e, errCheck2, top; @@ -408,12 +408,12 @@ top::PrimPattern ::= f::Float_t '->' e::Expr errCheck1 = check(floatType(), top.scrutineeType); top.errors <- if errCheck1.typeerror - then [err(top.location, f.lexeme ++ " is a " ++ errCheck1.leftpp ++ " but we're trying to match against " ++ errCheck1.rightpp)] + then [errFromOrigin(top, f.lexeme ++ " is a " ++ errCheck1.leftpp ++ " but we're trying to match against " ++ errCheck1.rightpp)] else []; errCheck2 = check(e.typerep, top.returnType); top.errors <- if errCheck2.typeerror - then [err(e.location, "pattern expression should have type " ++ errCheck2.rightpp ++ " instead it has type " ++ errCheck2.leftpp)] + then [errFromOrigin(e, "pattern expression should have type " ++ errCheck2.rightpp ++ " instead it has type " ++ errCheck2.leftpp)] else []; thread downSubst, upSubst on top, errCheck1, e, errCheck2, top; @@ -433,12 +433,12 @@ top::PrimPattern ::= i::String_t '->' e::Expr errCheck1 = check(stringType(), top.scrutineeType); top.errors <- if errCheck1.typeerror - then [err(top.location, i.lexeme ++ " is a " ++ errCheck1.leftpp ++ " but we're trying to match against " ++ errCheck1.rightpp)] + then [errFromOrigin(top, i.lexeme ++ " is a " ++ errCheck1.leftpp ++ " but we're trying to match against " ++ errCheck1.rightpp)] else []; errCheck2 = check(e.typerep, top.returnType); top.errors <- if errCheck2.typeerror - then [err(e.location, "pattern expression should have type " ++ errCheck2.rightpp ++ " instead it has type " ++ errCheck2.leftpp)] + then [errFromOrigin(e, "pattern expression should have type " ++ errCheck2.rightpp ++ " instead it has type " ++ errCheck2.leftpp)] else []; thread downSubst, upSubst on top, errCheck1, e, errCheck2, top; @@ -458,12 +458,12 @@ top::PrimPattern ::= i::String '->' e::Expr errCheck1 = check(boolType(), top.scrutineeType); top.errors <- if errCheck1.typeerror - then [err(top.location, i ++ " is a " ++ errCheck1.leftpp ++ " but we're trying to match against " ++ errCheck1.rightpp)] + then [errFromOrigin(top, i ++ " is a " ++ errCheck1.leftpp ++ " but we're trying to match against " ++ errCheck1.rightpp)] else []; errCheck2 = check(e.typerep, top.returnType); top.errors <- if errCheck2.typeerror - then [err(e.location, "pattern expression should have type " ++ errCheck2.rightpp ++ " instead it has type " ++ errCheck2.leftpp)] + then [errFromOrigin(e, "pattern expression should have type " ++ errCheck2.rightpp ++ " instead it has type " ++ errCheck2.leftpp)] else []; thread downSubst, upSubst on top, errCheck1, e, errCheck2, top; @@ -483,12 +483,12 @@ top::PrimPattern ::= e::Expr errCheck1 = check(listType(freshType()), top.scrutineeType); top.errors <- if errCheck1.typeerror - then [err(top.location, "nil matches lists but we're trying to match against " ++ errCheck1.rightpp)] + then [errFromOrigin(top, "nil matches lists but we're trying to match against " ++ errCheck1.rightpp)] else []; errCheck2 = check(e.typerep, top.returnType); top.errors <- if errCheck2.typeerror - then [err(e.location, "pattern expression should have type " ++ errCheck2.rightpp ++ " instead it has type " ++ errCheck2.leftpp)] + then [errFromOrigin(e, "pattern expression should have type " ++ errCheck2.rightpp ++ " instead it has type " ++ errCheck2.leftpp)] else []; thread downSubst, upSubst on top, errCheck1, e, errCheck2, top; @@ -513,12 +513,12 @@ top::PrimPattern ::= h::Name t::Name e::Expr errCheck1 = check(listType(elemType), top.scrutineeType); top.errors <- if errCheck1.typeerror - then [err(top.location, "cons matches lists but we're trying to match against " ++ errCheck1.rightpp)] + then [errFromOrigin(top, "cons matches lists but we're trying to match against " ++ errCheck1.rightpp)] else []; errCheck2 = check(e.typerep, top.returnType); top.errors <- if errCheck2.typeerror - then [err(e.location, "pattern expression should have type " ++ errCheck2.rightpp ++ " instead it has type " ++ errCheck2.leftpp)] + then [errFromOrigin(e, "pattern expression should have type " ++ errCheck2.rightpp ++ " instead it has type " ++ errCheck2.leftpp)] else []; thread downSubst, upSubst on top, errCheck1, e, errCheck2, top; diff --git a/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv b/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv index c1873d4bf..74ded81cf 100644 --- a/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv +++ b/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv @@ -12,14 +12,14 @@ import silver:compiler:definition:flow:ast only just, PatternVarProjection, patt import silver:compiler:analysis:warnings:flow only receivedDeps; -- Used in computing flow errors -nonterminal VarBinders with +tracked nonterminal VarBinders with config, grammarName, env, compiledGrammars, frame, - location, unparse, errors, defs, boundNames, + unparse, errors, defs, boundNames, bindingTypes, bindingIndex, translation, varBinderCount, finalSubst, flowProjections, bindingNames, flowEnv, matchingAgainst; -nonterminal VarBinder with +tracked nonterminal VarBinder with config, grammarName, env, compiledGrammars, frame, - location, unparse, errors, defs, boundNames, + unparse, errors, defs, boundNames, bindingType, bindingIndex, translation, finalSubst, flowProjections, bindingName, flowEnv, matchingAgainst; @@ -182,14 +182,14 @@ top::VarBinder ::= n::Name -- (Types have to be upper case) top.errors <- if !isUpper(substring(0,1,n.name)) then [] - else [err(top.location, "Pattern variables must start with a lower case letter")]; + else [errFromOrigin(top, "Pattern variables must start with a lower case letter")]; -- We prevent this to avoid people possibly forgetting the parens, e.g. writing 'nothing' -- One thing we could do is specifically raise this error, only if it's the production would be the right type. -- this would allow us to match 'left' and 'right' on a Pair, for example, but error on Either top.errors <- case getValueDcl(n.name, top.env) of - | prodDcl(_,_) :: _ -> [err(top.location, "Pattern variables cannot have the same name as productions (to avoid confusion)")] + | prodDcl(_,_) :: _ -> [errFromOrigin(top, "Pattern variables cannot have the same name as productions (to avoid confusion)")] | _ -> [] end; } diff --git a/grammars/silver/compiler/translation/java/core/FunctionDcl.sv b/grammars/silver/compiler/translation/java/core/FunctionDcl.sv index d31d4f8be..ca086fa0a 100644 --- a/grammars/silver/compiler/translation/java/core/FunctionDcl.sv +++ b/grammars/silver/compiler/translation/java/core/FunctionDcl.sv @@ -47,7 +47,7 @@ s""" final common.DecoratedNode context = new P${id.name}(${argsAccess}).decor -- main function signature check TODO: this should probably be elsewhere! top.errors <- if id.name == "main" && typeIOValFailed && typeIOMonadFailed -- Neither legal main function type used - then [err(top.location, "main function must have type signature (IOVal ::= [String] IOToken) " ++ + then [errFromOrigin(top, "main function must have type signature (IOVal ::= [String] IOToken) " ++ "or (IO ::= [String]). Instead it has type " ++ prettyType(namedSig.typerep))] else []; } diff --git a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv index d80089f32..fa0929ac2 100644 --- a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv +++ b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv @@ -386,6 +386,6 @@ ${makeTyVarDecls(3, namedSig.typerep.freeVariables)} -- main function signature check TODO: this should probably be elsewhere! top.errors <- if id.name == "main" - then [err(top.location, "main should be a function!")] + then [errFromOrigin(top, "main should be a function!")] else []; } diff --git a/grammars/silver/core/Monoid.sv b/grammars/silver/core/Monoid.sv index c00b2f06b..ad4791a41 100644 --- a/grammars/silver/core/Monoid.sv +++ b/grammars/silver/core/Monoid.sv @@ -62,7 +62,7 @@ Monoid m => m ::= x::m n::Integer } @{- @hide -} -nonterminal MPowerHelper; +data nonterminal MPowerHelper; @{- @hide -} abstract production mPowerHelper diff --git a/grammars/silver/reflect/concretesyntax/ConcreteSyntax.sv b/grammars/silver/reflect/concretesyntax/ConcreteSyntax.sv index 77a5f9e3f..c9797a871 100644 --- a/grammars/silver/reflect/concretesyntax/ConcreteSyntax.sv +++ b/grammars/silver/reflect/concretesyntax/ConcreteSyntax.sv @@ -24,7 +24,7 @@ terminal String_t /[\"]([^\r\n\"\\]|[\\][\"]|[\\][\\]|[\\]b|[\\]n|[\\]r|[\\]f|[ ignore terminal WhiteSpace /[\r\n\t\ ]+/; -closed nonterminal AST_c with unparse, ast, errors, location; +closed tracked nonterminal AST_c with unparse, ast, errors; concrete productions top::AST_c | prodName::QName_t '(' children::ASTs_c ',' annotations::NamedASTs_c ')' @@ -63,7 +63,7 @@ concrete productions top::AST_c fromRight(locReifyRes, bogusLoc())); top.errors := case locReifyRes of - | left(msg) -> [err(location.location, msg)] + | left(msg) -> [errFromOrigin(location, msg)] | right(_) -> [] end; } @@ -110,7 +110,7 @@ concrete productions top::AST_c top.errors := []; } -nonterminal ASTs_c with unparse, ast<[AST]>, errors; +tracked nonterminal ASTs_c with unparse, ast<[AST]>, errors; concrete productions top::ASTs_c | t::ASTs_c ',' h::AST_c @@ -126,7 +126,7 @@ concrete productions top::ASTs_c top.errors := []; } -nonterminal NamedASTs_c with unparse, ast<[NamedAST]>, errors; +tracked nonterminal NamedASTs_c with unparse, ast<[NamedAST]>, errors; concrete productions top::NamedASTs_c | t::NamedASTs_c ',' h::NamedAST_c @@ -142,7 +142,7 @@ concrete productions top::NamedASTs_c top.errors := []; } -nonterminal NamedAST_c with unparse, ast, errors, location; +tracked nonterminal NamedAST_c with unparse, ast, errors; concrete productions top::NamedAST_c | n::QName_t '=' v::AST_c From c478c7db014a982d80e15ad1472ea6d70d7ed45a Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 22 Sep 2023 21:20:51 -0500 Subject: [PATCH 040/283] Fixing more errors from removing location --- .../compiler/definition/core/Annotation.sv | 2 +- .../compiler/definition/core/AspectDcl.sv | 8 +- .../compiler/definition/core/ClassDcl.sv | 6 +- .../silver/compiler/definition/core/Expr.sv | 2 +- .../compiler/definition/core/FunctionDcl.sv | 2 +- .../compiler/definition/core/GlobalDcl.sv | 2 +- .../compiler/definition/core/GrammarParts.sv | 6 +- .../compiler/definition/core/InstanceDcl.sv | 6 +- .../compiler/definition/core/ProductionDcl.sv | 2 +- .../definition/type/syntax/Constraint.sv | 78 +++++----- .../extension/astconstruction/Syntax.sv | 22 +-- .../compiler/extension/auto_ast/AutoAst.sv | 1 - .../compiler/extension/autoattr/DclInfo.sv | 20 +-- .../compiler/extension/autoattr/Destruct.sv | 8 +- .../compiler/extension/autoattr/Functor.sv | 18 +-- .../compiler/extension/autoattr/Monoid.sv | 8 +- .../compiler/extension/autoattr/Propagate.sv | 13 +- .../compiler/extension/autoattr/Threaded.sv | 14 +- .../autoattr/convenience/Convenience.sv | 26 ++-- .../extension/convenience/Convenience.sv | 24 +-- .../compiler/extension/convenience/Lists.sv | 11 +- .../extension/convenience/Productions.sv | 5 +- .../convenienceaspects/AbstractSyntax.sv | 147 +++++++----------- .../convenienceaspects/ConcreteSyntax.sv | 2 +- .../silver/compiler/extension/data/DataDcl.sv | 2 +- .../compiler/extension/deriving/Derive.sv | 28 ++-- .../compiler/extension/do_notation/Syntax.sv | 14 +- .../compiler/extension/doc/core/AGDcl.sv | 54 +++---- .../compiler/extension/doc/core/DataDcl.sv | 4 +- .../compiler/extension/doc/core/RootSpec.sv | 10 +- .../extension/doc/core/TypeClassDcls.sv | 4 +- .../extension/doc/core/doclang/DclComment.sv | 4 +- .../extension/strategyattr/Strategy.sv | 4 +- .../extension/templating/StringTemplating.sv | 4 +- .../compiler/extension/treegen/TestFor.sv | 4 +- .../compiler/metatranslation/Translation.sv | 39 ++--- 36 files changed, 267 insertions(+), 337 deletions(-) diff --git a/grammars/silver/compiler/definition/core/Annotation.sv b/grammars/silver/compiler/definition/core/Annotation.sv index 56c8055f3..b00663db4 100644 --- a/grammars/silver/compiler/definition/core/Annotation.sv +++ b/grammars/silver/compiler/definition/core/Annotation.sv @@ -11,7 +11,7 @@ top::AGDcl ::= 'annotation' a::QName tl::BracketedOptTypeExprs '::' te::TypeExpr production fName :: String = top.grammarName ++ ":" ++ a.name; - top.defs := [annoDef(top.grammarName, getParsedOriginLocationOrFallback(a), fName, tl.freeVariables, te.typerep)]; + top.defs := [annoDef(top.grammarName, a.nameLoc, fName, tl.freeVariables, te.typerep)]; tl.initialEnv = top.env; tl.env = tl.envBindingTyVars; diff --git a/grammars/silver/compiler/definition/core/AspectDcl.sv b/grammars/silver/compiler/definition/core/AspectDcl.sv index 218490f16..330aaf757 100644 --- a/grammars/silver/compiler/definition/core/AspectDcl.sv +++ b/grammars/silver/compiler/definition/core/AspectDcl.sv @@ -55,11 +55,11 @@ top::AGDcl ::= 'aspect' 'production' id::QName ns::AspectProductionSignature bod local contextSigDefs::[Def] = flatMap( - \ c::Context -> c.contextSigDefs(realSig, top.grammarName, top.location), + \ c::Context -> c.contextSigDefs(realSig, top.grammarName, id.nameLoc), realSig.contexts); local contextSigOccursDefs::[OccursDclInfo] = flatMap( - \ c::Context -> c.contextSigOccursDefs(realSig, top.grammarName, top.location), + \ c::Context -> c.contextSigOccursDefs(realSig, top.grammarName, id.nameLoc), realSig.contexts); local sourceGrammar::String = if id.lookupValue.found @@ -112,11 +112,11 @@ top::AGDcl ::= 'aspect' 'function' id::QName ns::AspectFunctionSignature body::P local contextSigDefs::[Def] = flatMap( - \ c::Context -> c.contextSigDefs(realSig, top.grammarName, top.location), + \ c::Context -> c.contextSigDefs(realSig, top.grammarName, id.nameLoc), realSig.contexts); local contextSigOccursDefs::[OccursDclInfo] = flatMap( - \ c::Context -> c.contextSigOccursDefs(realSig, top.grammarName, top.location), + \ c::Context -> c.contextSigOccursDefs(realSig, top.grammarName, id.nameLoc), realSig.contexts); local sourceGrammar::String = if id.lookupValue.found diff --git a/grammars/silver/compiler/definition/core/ClassDcl.sv b/grammars/silver/compiler/definition/core/ClassDcl.sv index a83f16f09..648e90968 100644 --- a/grammars/silver/compiler/definition/core/ClassDcl.sv +++ b/grammars/silver/compiler/definition/core/ClassDcl.sv @@ -49,7 +49,7 @@ top::AGDcl ::= 'class' cl::ConstraintList '=>' id::QNameType var::TypeExpr '{' b headDefs := cl.defs; headDefs <- [currentInstDef(top.grammarName, id.nameLoc, fName, var.typerep)]; - cl.constraintPos = classPos(fName, var.freeVariables); + cl.constraintPos = classPos(fName, var.freeVariables, sourceGrammar=top.grammarName); cl.env = newScopeEnv(headPreDefs, top.env); id.env = cl.env; @@ -120,7 +120,7 @@ top::ClassBodyItem ::= id::Name '::' cl::ConstraintList '=>' ty::TypeExpr ';' cl.constraintPos = case top.classHead of - | instContext(cls, _) -> classMemberPos(cls, boundVars) + | instContext(cls, _) -> classMemberPos(cls, boundVars, sourceGrammar=top.grammarName) | _ -> error("Class head is not an instContext") end; cl.env = top.constraintEnv; @@ -157,7 +157,7 @@ top::ClassBodyItem ::= id::Name '::' cl::ConstraintList '=>' ty::TypeExpr '=' e: cl.constraintPos = case top.classHead of - | instContext(cls, _) -> classMemberPos(cls, boundVars) + | instContext(cls, _) -> classMemberPos(cls, boundVars, sourceGrammar=top.grammarName) | _ -> error("Class head is not an instContext") end; cl.env = top.constraintEnv; diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index b128c5d0d..10cd2b520 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -920,7 +920,7 @@ top::Expr ::= 'terminal' '(' t::TypeExpr ',' e::Expr ')' --top.errors <- [wrnFromOrigin(t, "terminal(type,lexeme) is deprecated. Use terminal(type,lexeme,location) instead.")]; local bogus :: Expr = - mkStrFunctionInvocation($6.location, "silver:core:bogusLoc", []); + mkStrFunctionInvocation("silver:core:bogusLoc", []); forwards to terminalConstructor($1, $2, t, $4, e, ',', bogus, $6); } diff --git a/grammars/silver/compiler/definition/core/FunctionDcl.sv b/grammars/silver/compiler/definition/core/FunctionDcl.sv index 453444010..e84b4a66d 100644 --- a/grammars/silver/compiler/definition/core/FunctionDcl.sv +++ b/grammars/silver/compiler/definition/core/FunctionDcl.sv @@ -50,7 +50,7 @@ top::FunctionSignature ::= cl::ConstraintList '=>' lhs::FunctionLHS '::=' rhs::P { top.unparse = s"${cl.unparse} => ${lhs.unparse} ::= ${rhs.unparse}"; - cl.constraintPos = signaturePos(top.namedSignature); + cl.constraintPos = signaturePos(top.namedSignature, sourceGrammar=top.grammarName); cl.env = top.env; lhs.env = top.env; rhs.env = occursEnv(cl.occursDefs, top.env); diff --git a/grammars/silver/compiler/definition/core/GlobalDcl.sv b/grammars/silver/compiler/definition/core/GlobalDcl.sv index 317586dc7..fb26a6a74 100644 --- a/grammars/silver/compiler/definition/core/GlobalDcl.sv +++ b/grammars/silver/compiler/definition/core/GlobalDcl.sv @@ -36,7 +36,7 @@ top::AGDcl ::= 'global' id::Name '::' cl::ConstraintList '=>' t::TypeExpr '=' e: e.originRules = []; e.isRoot = true; - cl.constraintPos = globalPos(boundVars); + cl.constraintPos = globalPos(boundVars, sourceGrammar=top.grammarName); -- oh no again! local myFlow :: EnvTree = head(searchEnvTree(top.grammarName, top.compiledGrammars)).grammarFlowTypes; diff --git a/grammars/silver/compiler/definition/core/GrammarParts.sv b/grammars/silver/compiler/definition/core/GrammarParts.sv index a52bf1e3f..c47cf8997 100644 --- a/grammars/silver/compiler/definition/core/GrammarParts.sv +++ b/grammars/silver/compiler/definition/core/GrammarParts.sv @@ -61,7 +61,9 @@ top::Grammar ::= h::Root t::Grammar production attribute rootErrors::[Message] with ++; rootErrors := h.errors; - top.allFileErrors = (getParsedOriginLocationOrFallback(h).filename, rootErrors) :: t.allFileErrors; + top.allFileErrors = (getParsedOriginLocation(h).fromJust.filename, rootErrors) :: t.allFileErrors; - rootErrors <- warnIfMultJarName(h.jarName, t.jarName, h.location); + rootErrors <- attachNote logicalLocationFromOrigin(h) on + warnIfMultJarName(h.jarName, t.jarName) + end; } diff --git a/grammars/silver/compiler/definition/core/InstanceDcl.sv b/grammars/silver/compiler/definition/core/InstanceDcl.sv index c098a4fb9..ae23bc56c 100644 --- a/grammars/silver/compiler/definition/core/InstanceDcl.sv +++ b/grammars/silver/compiler/definition/core/InstanceDcl.sv @@ -51,7 +51,7 @@ top::AGDcl ::= 'instance' cl::ConstraintList '=>' id::QNameType ty::TypeExpr '{' | _ -> [] end; - cl.constraintPos = instancePos(instContext(fName, ty.typerep), boundVars); + cl.constraintPos = instancePos(instContext(fName, ty.typerep), boundVars, sourceGrammar=top.grammarName); production attribute headPreDefs :: [Def] with ++; headPreDefs := []; @@ -156,11 +156,11 @@ top::InstanceBodyItem ::= id::QName '=' e::Expr ';' local cmDefs::[Def] = flatMap( - \ c::Context -> c.contextMemberDefs(boundVars, top.grammarName, top.location), + \ c::Context -> c.contextMemberDefs(boundVars, top.grammarName, id.nameLoc), memberContexts); local cmOccursDefs::[OccursDclInfo] = flatMap( - \ c::Context -> c.contextMemberOccursDefs(boundVars, top.grammarName, top.location), + \ c::Context -> c.contextMemberOccursDefs(boundVars, top.grammarName, id.nameLoc), memberContexts); e.env = newScopeEnv( diff --git a/grammars/silver/compiler/definition/core/ProductionDcl.sv b/grammars/silver/compiler/definition/core/ProductionDcl.sv index f9f375ec0..f6d64ea2e 100644 --- a/grammars/silver/compiler/definition/core/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/core/ProductionDcl.sv @@ -100,7 +100,7 @@ top::ProductionSignature ::= cl::ConstraintList '=>' lhs::ProductionLHS '::=' rh top.unparse = s"${cl.unparse} => ${lhs.unparse} ::= ${rhs.unparse}"; cl.env = top.env; - cl.constraintPos = signaturePos(top.namedSignature); + cl.constraintPos = signaturePos(top.namedSignature, sourceGrammar=top.grammarName); lhs.env = top.env; rhs.env = occursEnv(cl.occursDefs, top.env); diff --git a/grammars/silver/compiler/definition/type/syntax/Constraint.sv b/grammars/silver/compiler/definition/type/syntax/Constraint.sv index 342cd1eeb..d9a82d2f8 100644 --- a/grammars/silver/compiler/definition/type/syntax/Constraint.sv +++ b/grammars/silver/compiler/definition/type/syntax/Constraint.sv @@ -72,7 +72,7 @@ top::Constraint ::= c::QNameType t::TypeExpr end; top.errors <- undecidableInstanceErrors; - local instDcl::InstDclInfo = top.constraintPos.classInstDcl(fName, t.typerep, top.grammarName, top.location); + local instDcl::InstDclInfo = top.constraintPos.classInstDcl(fName, t.typerep); top.defs <- [tcInstDef(instDcl)]; top.defs <- transitiveSuperDefs(top.env, t.typerep, [], instDcl); top.occursDefs <- transitiveSuperOccursDefs(top.env, t.typerep, [], instDcl); @@ -127,7 +127,7 @@ top::Constraint ::= 'attribute' at::QName attl::BracketedOptTypeExprs 'occurs' ' local rewrite :: Substitution = zipVarsAndTypesIntoSubstitution(atTypeScheme.boundVars, attl.types); production attrTy::Type = performRenaming(atTypeScheme.typerep, rewrite); - local instDcl::OccursDclInfo = top.constraintPos.occursInstDcl(fName, t.typerep, attrTy, top.grammarName, top.location); + local instDcl::OccursDclInfo = top.constraintPos.occursInstDcl(fName, t.typerep, attrTy); top.occursDefs <- [instDcl]; } @@ -174,7 +174,7 @@ top::Constraint ::= 'attribute' at::QName attl::BracketedOptTypeExprs i::TypeExp local rewrite :: Substitution = zipVarsAndTypesIntoSubstitution(atTypeScheme.boundVars, attl.types); production attrTy::Type = performRenaming(atTypeScheme.typerep, rewrite); - local instDcl::OccursDclInfo = top.constraintPos.occursInstDcl(fName, t.typerep, attrTy, top.grammarName, top.location); + local instDcl::OccursDclInfo = top.constraintPos.occursInstDcl(fName, t.typerep, attrTy); top.occursDefs <- [instDcl]; top.lexicalTyVarKinds <- @@ -222,7 +222,7 @@ top::Constraint ::= 'annotation' at::QName attl::BracketedOptTypeExprs 'occurs' local rewrite :: Substitution = zipVarsAndTypesIntoSubstitution(atTypeScheme.boundVars, attl.types); production attrTy::Type = performRenaming(atTypeScheme.typerep, rewrite); - local instDcl::OccursDclInfo = top.constraintPos.occursInstDcl(fName, t.typerep, attrTy, top.grammarName, top.location); + local instDcl::OccursDclInfo = top.constraintPos.occursInstDcl(fName, t.typerep, attrTy); top.occursDefs <- [instDcl]; } @@ -235,7 +235,7 @@ top::Constraint ::= 'runtimeTypeable' t::TypeExpr top.errors <- t.errorsTyVars; top.errors <- t.errorsKindStar; - local instDcl::InstDclInfo = top.constraintPos.typeableInstDcl(t.typerep, top.grammarName, top.location); + local instDcl::InstDclInfo = top.constraintPos.typeableInstDcl(t.typerep); top.defs <- [tcInstDef(instDcl)]; } @@ -254,7 +254,7 @@ top::Constraint ::= i1::TypeExpr 'subset' i2::TypeExpr then [errFromOrigin(top, s"${top.unparse} has kind ${prettyKind(i2.typerep.kindrep)}, but kind InhSet is expected here")] else []; - local instDcl::InstDclInfo = top.constraintPos.inhSubsetInstDcl(i1.typerep, i2.typerep, top.grammarName, top.location); + local instDcl::InstDclInfo = top.constraintPos.inhSubsetInstDcl(i1.typerep, i2.typerep); top.defs <- case top.constraintPos of | classPos(_, _) -> [] @@ -291,13 +291,14 @@ top::Constraint ::= 'typeError' msg::String_t end; } -synthesized attribute classInstDcl::(InstDclInfo ::= String Type String Location); -synthesized attribute occursInstDcl::(OccursDclInfo ::= String Type Type String Location); -synthesized attribute typeableInstDcl::(InstDclInfo ::= Type String Location); -synthesized attribute inhSubsetInstDcl::(InstDclInfo ::= Type Type String Location); +synthesized attribute classInstDcl::(InstDclInfo ::= String Type); +synthesized attribute occursInstDcl::(OccursDclInfo ::= String Type Type); +synthesized attribute typeableInstDcl::(InstDclInfo ::= Type); +synthesized attribute inhSubsetInstDcl::(InstDclInfo ::= Type Type); synthesized attribute classDefName::Maybe; synthesized attribute instanceHead::Maybe; -tracked nonterminal ConstraintPosition with classInstDcl, occursInstDcl, typeableInstDcl, inhSubsetInstDcl, classDefName, instanceHead; +tracked data nonterminal ConstraintPosition + with sourceGrammar, classInstDcl, occursInstDcl, typeableInstDcl, inhSubsetInstDcl, classDefName, instanceHead; aspect default production top::ConstraintPosition ::= @@ -308,37 +309,40 @@ top::ConstraintPosition ::= abstract production instancePos top::ConstraintPosition ::= instHead::Context tvs::[TyVar] { - top.classInstDcl = instConstraintDcl(_, _, tvs, sourceGrammar=_, sourceLocation=_); - top.occursInstDcl = occursInstConstraintDcl(_, _, _, tvs, sourceGrammar=_, sourceLocation=_); - top.typeableInstDcl = typeableInstConstraintDcl(_, tvs, sourceGrammar=_, sourceLocation=_); - top.inhSubsetInstDcl = inhSubsetInstConstraintDcl(_, _, tvs, sourceGrammar=_, sourceLocation=_); + local loc::Location = getParsedOriginLocationOrFallback(top); + top.classInstDcl = instConstraintDcl(_, _, tvs, sourceGrammar=top.sourceGrammar, sourceLocation=loc); + top.occursInstDcl = occursInstConstraintDcl(_, _, _, tvs, sourceGrammar=top.sourceGrammar, sourceLocation=loc); + top.typeableInstDcl = typeableInstConstraintDcl(_, tvs, sourceGrammar=top.sourceGrammar, sourceLocation=loc); + top.inhSubsetInstDcl = inhSubsetInstConstraintDcl(_, _, tvs, sourceGrammar=top.sourceGrammar, sourceLocation=loc); top.instanceHead = just(instHead); } abstract production classPos top::ConstraintPosition ::= className::String tvs::[TyVar] { - top.classInstDcl = \ fName::String t::Type g::String l::Location -> + local loc::Location = getParsedOriginLocationOrFallback(top); + top.classInstDcl = \ fName::String t::Type -> instSuperDcl(fName, - currentInstDcl(className, t, sourceGrammar=g, sourceLocation=l), - sourceGrammar=g, sourceLocation=l); - top.occursInstDcl = \ fName::String ntty::Type atty::Type g::String l::Location -> + currentInstDcl(className, t, sourceGrammar=top.sourceGrammar, sourceLocation=loc), + sourceGrammar=top.sourceGrammar, sourceLocation=loc); + top.occursInstDcl = \ fName::String ntty::Type atty::Type -> occursSuperDcl(fName, atty, - currentInstDcl(className, ntty, sourceGrammar=g, sourceLocation=l), - sourceGrammar=g, sourceLocation=l); - top.typeableInstDcl = \ t::Type g::String l::Location -> + currentInstDcl(className, ntty, sourceGrammar=top.sourceGrammar, sourceLocation=loc), + sourceGrammar=top.sourceGrammar, sourceLocation=loc); + top.typeableInstDcl = \ t::Type -> typeableSuperDcl( - currentInstDcl(className, t, sourceGrammar=g, sourceLocation=l), - sourceGrammar=g, sourceLocation=l); + currentInstDcl(className, t, sourceGrammar=top.sourceGrammar, sourceLocation=loc), + sourceGrammar=top.sourceGrammar, sourceLocation=loc); top.inhSubsetInstDcl = error("subset constraint not permitted as superclass"); top.classDefName = just(className); } abstract production classMemberPos top::ConstraintPosition ::= className::String tvs::[TyVar] { - top.classInstDcl = instConstraintDcl(_, _, tvs, sourceGrammar=_, sourceLocation=_); - top.occursInstDcl = occursInstConstraintDcl(_, _, _, tvs, sourceGrammar=_, sourceLocation=_); - top.typeableInstDcl = typeableInstConstraintDcl(_, tvs, sourceGrammar=_, sourceLocation=_); - top.inhSubsetInstDcl = inhSubsetInstConstraintDcl(_, _, tvs, sourceGrammar=_, sourceLocation=_); + local loc::Location = getParsedOriginLocationOrFallback(top); + top.classInstDcl = instConstraintDcl(_, _, tvs, sourceGrammar=top.sourceGrammar, sourceLocation=loc); + top.occursInstDcl = occursInstConstraintDcl(_, _, _, tvs, sourceGrammar=top.sourceGrammar, sourceLocation=loc); + top.typeableInstDcl = typeableInstConstraintDcl(_, tvs, sourceGrammar=top.sourceGrammar, sourceLocation=loc); + top.inhSubsetInstDcl = inhSubsetInstConstraintDcl(_, _, tvs, sourceGrammar=top.sourceGrammar, sourceLocation=loc); top.classDefName = just(className); -- A bit strange, but class member constraints are sort of like instance constraints. -- However we don't know what the instance type actually is, and want to skip the @@ -348,19 +352,21 @@ top::ConstraintPosition ::= className::String tvs::[TyVar] abstract production signaturePos top::ConstraintPosition ::= sig::NamedSignature { - top.classInstDcl = sigConstraintDcl(_, _, sig, sourceGrammar=_, sourceLocation=_); - top.occursInstDcl = occursSigConstraintDcl(_, _, _, sig, sourceGrammar=_, sourceLocation=_); - top.typeableInstDcl = typeableSigConstraintDcl(_, sig, sourceGrammar=_, sourceLocation=_); - top.inhSubsetInstDcl = inhSubsetSigConstraintDcl(_, _, sig, sourceGrammar=_, sourceLocation=_); + local loc::Location = getParsedOriginLocationOrFallback(top); + top.classInstDcl = sigConstraintDcl(_, _, sig, sourceGrammar=top.sourceGrammar, sourceLocation=loc); + top.occursInstDcl = occursSigConstraintDcl(_, _, _, sig, sourceGrammar=top.sourceGrammar, sourceLocation=loc); + top.typeableInstDcl = typeableSigConstraintDcl(_, sig, sourceGrammar=top.sourceGrammar, sourceLocation=loc); + top.inhSubsetInstDcl = inhSubsetSigConstraintDcl(_, _, sig, sourceGrammar=top.sourceGrammar, sourceLocation=loc); } abstract production globalPos top::ConstraintPosition ::= tvs::[TyVar] { + local loc::Location = getParsedOriginLocationOrFallback(top); -- These are translated the same as instance constraints. - top.classInstDcl = instConstraintDcl(_, _, tvs, sourceGrammar=_, sourceLocation=_); - top.occursInstDcl = occursInstConstraintDcl(_, _, _, tvs, sourceGrammar=_, sourceLocation=_); - top.typeableInstDcl = typeableInstConstraintDcl(_, tvs, sourceGrammar=_, sourceLocation=_); - top.inhSubsetInstDcl = inhSubsetInstConstraintDcl(_, _, tvs, sourceGrammar=_, sourceLocation=_); + top.classInstDcl = instConstraintDcl(_, _, tvs, sourceGrammar=top.sourceGrammar, sourceLocation=loc); + top.occursInstDcl = occursInstConstraintDcl(_, _, _, tvs, sourceGrammar=top.sourceGrammar, sourceLocation=loc); + top.typeableInstDcl = typeableInstConstraintDcl(_, tvs, sourceGrammar=top.sourceGrammar, sourceLocation=loc); + top.inhSubsetInstDcl = inhSubsetInstConstraintDcl(_, _, tvs, sourceGrammar=top.sourceGrammar, sourceLocation=loc); } function transitiveSuperContexts diff --git a/grammars/silver/compiler/extension/astconstruction/Syntax.sv b/grammars/silver/compiler/extension/astconstruction/Syntax.sv index 03f1c8b69..24b24786b 100644 --- a/grammars/silver/compiler/extension/astconstruction/Syntax.sv +++ b/grammars/silver/compiler/extension/astconstruction/Syntax.sv @@ -15,7 +15,7 @@ top::Expr ::= 'AST' '{' ast::AST_c '}' layout {silver:reflect:concretesyntax:WhiteSpace} { top.unparse = s"AST {${ast.unparse}}"; - forwards to translate(top.location, reflect(ast.ast)); + forwards to translate(reflect(ast.ast)); } concrete production quoteASTPattern @@ -23,7 +23,7 @@ top::Pattern ::= 'AST' '{' ast::AST_c '}' layout {silver:reflect:concretesyntax:WhiteSpace} { top.unparse = s"AST {${ast.unparse}}"; - forwards to translatePattern(top.location, reflect(ast.ast)); + forwards to translatePattern(reflect(ast.ast)); } concrete production antiquoteAST_c @@ -39,7 +39,7 @@ concrete production varAST_c top::AST_c ::= n::QName_t { top.unparse = n.lexeme; - top.ast = antiquotePatternAST(varPattern(name(n.lexeme, n.location))); + top.ast = antiquotePatternAST(varPattern(name(n.lexeme))); top.errors := if indexOf(":", n.lexeme) != -1 then [errFromOrigin(n, "Pattern variable name must be unqualified")] @@ -58,13 +58,9 @@ abstract production antiquoteAST top::AST ::= e::Expr { top.translation = - errorExpr( - [err(top.givenLocation, "${} should only occur inside AST { } expression")], - location=top.givenLocation); + errorExpr([err(top.givenLocation, "${} should only occur inside AST { } expression")]); top.patternTranslation = - errorPattern( - [err(top.givenLocation, "${} should only occur inside AST { } expression")], - location=top.givenLocation); + errorPattern([err(top.givenLocation, "${} should only occur inside AST { } expression")]); forwards to error("forward shouldn't be needed here"); } @@ -72,12 +68,8 @@ abstract production antiquotePatternAST top::AST ::= p::Pattern { top.translation = - errorExpr( - [err(top.givenLocation, "Variable and wildcard patterns should only occur inside AST { } pattern")], - location=top.givenLocation); + errorExpr([err(top.givenLocation, "Variable and wildcard patterns should only occur inside AST { } pattern")]); top.patternTranslation = - errorPattern( - [err(top.givenLocation, "Variable and wildcard patterns should only occur inside AST { } pattern")], - location=top.givenLocation); + errorPattern([err(top.givenLocation, "Variable and wildcard patterns should only occur inside AST { } pattern")]); forwards to error("forward shouldn't be needed here"); } diff --git a/grammars/silver/compiler/extension/auto_ast/AutoAst.sv b/grammars/silver/compiler/extension/auto_ast/AutoAst.sv index ad6c88a9e..d4a8c1520 100644 --- a/grammars/silver/compiler/extension/auto_ast/AutoAst.sv +++ b/grammars/silver/compiler/extension/auto_ast/AutoAst.sv @@ -60,7 +60,6 @@ top::ProductionStmt ::= 'abstract' v::QName ';' astQName, '=', mkFullFunctionInvocation( - top.location, baseExpr(v), map(accessAst(_, top.location), elems), if hasLoc then diff --git a/grammars/silver/compiler/extension/autoattr/DclInfo.sv b/grammars/silver/compiler/extension/autoattr/DclInfo.sv index 54c237844..95e1c0e7f 100644 --- a/grammars/silver/compiler/extension/autoattr/DclInfo.sv +++ b/grammars/silver/compiler/extension/autoattr/DclInfo.sv @@ -28,7 +28,7 @@ top::AttributeDclInfo ::= fn::String top.isSynthesized = true; top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations top.attributionDispatcher = functorAttributionDcl; @@ -53,11 +53,11 @@ top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type empty::Expr append: top.operation = append; top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = - \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr l::Location -> - errorAttributeDef([err(l, attr.name ++ " is a monoid collection attribute, and you must use ':=' or '<-', not '='.")], dl, attr, e); + \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr -> + errorAttributeDef([errFromOrigin(ambientOrigin(), attr.name ++ " is a monoid collection attribute, and you must use ':=' or '<-', not '='.")], dl, attr, e); top.attrBaseDefDispatcher = synBaseColAttributeDef; top.attrAppendDefDispatcher = synAppendColAttributeDef; top.attributionDispatcher = defaultAttributionDcl; @@ -93,7 +93,7 @@ top::AttributeDclInfo ::= inh::String syn::String top.isSynthesized = true; top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations top.attributionDispatcher = defaultAttributionDcl; @@ -110,7 +110,7 @@ top::AttributeDclInfo ::= syn::String top.isSynthesized = true; top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations top.attributionDispatcher = defaultAttributionDcl; @@ -127,7 +127,7 @@ top::AttributeDclInfo ::= inh::String keySyn::String syn::String top.isSynthesized = true; top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations top.attributionDispatcher = defaultAttributionDcl; @@ -144,7 +144,7 @@ top::AttributeDclInfo ::= inh::String synPartial::String syn::String top.isSynthesized = true; top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations top.attributionDispatcher = defaultAttributionDcl; @@ -161,7 +161,7 @@ top::AttributeDclInfo ::= inh::String synPartial::String syn::String top.isSynthesized = true; top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations top.attributionDispatcher = defaultAttributionDcl; @@ -222,7 +222,7 @@ top::AttributeDclInfo ::= inh::String syn::String bound::[TyVar] ty::Type o::May top.operation = o.fromJust; top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = if o.isJust diff --git a/grammars/silver/compiler/extension/autoattr/Destruct.sv b/grammars/silver/compiler/extension/autoattr/Destruct.sv index 6dbeb52e4..e331ad489 100644 --- a/grammars/silver/compiler/extension/autoattr/Destruct.sv +++ b/grammars/silver/compiler/extension/autoattr/Destruct.sv @@ -16,7 +16,7 @@ top::AGDcl ::= 'destruct' 'attribute' inh::Name ';' forwards to defsAGDcl( - [attrDef(defaultEnvItem(destructDcl(inhFName, sourceGrammar=top.grammarName, sourceLocation=inh.location)))]); + [attrDef(defaultEnvItem(destructDcl(inhFName, sourceGrammar=top.grammarName, sourceLocation=inh.nameLoc)))]); } abstract production destructAttributionDcl @@ -100,9 +100,9 @@ top::ProductionStmt ::= attr::Decorated! QName ')')} -> a | a -> error( - "Destruct attribute " ++ $Expr{stringConst(terminal(String_t, s"\"${attr.name}\"", top.location))} ++ - " demanded on child " ++ $Expr{stringConst(terminal(String_t, s"\"${ie.snd.elementName}\"", top.location))} ++ - " of production " ++ $Expr{stringConst(terminal(String_t, s"\"${top.frame.signature.fullName}\"", top.location))} ++ + "Destruct attribute " ++ $Expr{stringConst(terminal(String_t, s"\"${attr.name}\"", attr.nameLoc))} ++ + " demanded on child " ++ $Expr{stringConst(terminal(String_t, s"\"${ie.snd.elementName}\"", attr.nameLoc))} ++ + " of production " ++ $Expr{stringConst(terminal(String_t, s"\"${top.frame.signature.fullName}\"", attr.nameLoc))} ++ " when given value " ++ silver:core:hackUnparse(a) ++ " does not match.") -- TODO: Shouldn't really be using hackUnparse here. end; }, diff --git a/grammars/silver/compiler/extension/autoattr/Functor.sv b/grammars/silver/compiler/extension/autoattr/Functor.sv index 999637dad..20f647976 100644 --- a/grammars/silver/compiler/extension/autoattr/Functor.sv +++ b/grammars/silver/compiler/extension/autoattr/Functor.sv @@ -16,7 +16,7 @@ top::AGDcl ::= 'functor' 'attribute' a::Name ';' forwards to defsAGDcl( - [attrDef(defaultEnvItem(functorDcl(fName, sourceGrammar=top.grammarName, sourceLocation=a.location)))]); + [attrDef(defaultEnvItem(functorDcl(fName, sourceGrammar=top.grammarName, sourceLocation=a.nameLoc)))]); } abstract production functorAttributionDcl @@ -64,10 +64,10 @@ top::ProductionStmt ::= attr::Decorated! QName -- Generate the arguments for the constructor local inputs :: [Expr] = - map(makeArg(top.location, top.env, attr, _), top.frame.signature.inputElements); + map(makeArg(top.env, attr, _), top.frame.signature.inputElements); local annotations :: [Pair] = map( - makeAnnoArg(top.location, top.frame.signature.outputElement.elementName, _), + makeAnnoArg(top.frame.signature.outputElement.elementName, _), top.frame.signature.namedInputElements); -- Construct an attribute def and call with the generated arguments @@ -77,24 +77,19 @@ top::ProductionStmt ::= attr::Decorated! QName '.', qNameAttrOccur(new(attr)), '=', - mkFullFunctionInvocation( - top.location, - baseExpr(qName(top.frame.fullName)), - inputs, - annotations), + mkFullFunctionInvocation(baseExpr(qName(top.frame.fullName)), inputs, annotations), ';'); } {-- - Generates the expression we should use for an argument - - @param loc The parent location to use in construction - @param env The environment - @param attrName The name of the attribute being propagated - @param input The NamedSignatureElement being propagated - @return Either this the child, or accessing `attrName` on the child -} function makeArg -Expr ::= loc::Location env::Env attrName::Decorated QName input::NamedSignatureElement +Expr ::= env::Env attrName::Decorated QName input::NamedSignatureElement { local at::QName = qName(input.elementName); at.env = env; @@ -115,13 +110,12 @@ Expr ::= loc::Location env::Env attrName::Decorated QName input::NamedSignatureE {-- - Generates the list of AnnoExprs used in calling the constructor - - @param loc The parent location to use in construction - @param baseName The name of the parent from the signature - @param input The NamedSignatureElement for an annotation - @return A list of AnnoExprs to be used to build the named arguments -} function makeAnnoArg -Pair ::= loc::Location baseName::String input::NamedSignatureElement +Pair ::= baseName::String input::NamedSignatureElement { -- TODO: This is a hacky way of getting the base name, not sure if correct -- trouble is the annotations are listed as fullnames, but have to be supplied as shortnames. weird. diff --git a/grammars/silver/compiler/extension/autoattr/Monoid.sv b/grammars/silver/compiler/extension/autoattr/Monoid.sv index 67b9e3ddb..346ea49ad 100644 --- a/grammars/silver/compiler/extension/autoattr/Monoid.sv +++ b/grammars/silver/compiler/extension/autoattr/Monoid.sv @@ -23,7 +23,7 @@ top::AGDcl ::= 'monoid' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te::T -- TODO: We want to define our own defs here but can't forward to defsAGDcl because collections define different translation. -- Not sure about the best way to refactor this. top.defs := - [attrDef(defaultEnvItem(monoidDcl(fName, tl.freeVariables, te.typerep, e, q.operation, sourceGrammar=top.grammarName, sourceLocation=a.location)))]; + [attrDef(defaultEnvItem(monoidDcl(fName, tl.freeVariables, te.typerep, e, q.operation, sourceGrammar=top.grammarName, sourceLocation=a.nameLoc)))]; top.errors <- e.errors; @@ -73,12 +73,12 @@ top::AGDcl ::= 'monoid' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te::T exprOperator(baseExpr(qName("silver:core:append"))), $7); } -synthesized attribute appendProd :: (Expr ::= Expr Expr Location) occurs on Operation; +synthesized attribute appendProd :: (Expr ::= Expr Expr) occurs on Operation; aspect production functionOperation top::Operation ::= e::Expr _ _ { - top.appendProd = \ e1::Expr e2::Expr l::Location -> mkFunctionInvocation(l, e, [e1, e2]); + top.appendProd = \ e1::Expr e2::Expr -> mkFunctionInvocation(e, [e1, e2]); } aspect production plusPlusOperationString top::Operation ::= @@ -136,7 +136,7 @@ top::ProductionStmt ::= attr::Decorated! QName then attr.lookupAttribute.dcl.emptyVal else foldr1( - attr.lookupAttribute.dcl.operation.appendProd(_, _, top.location), + attr.lookupAttribute.dcl.operation.appendProd, map( \ i::NamedSignatureElement -> access( diff --git a/grammars/silver/compiler/extension/autoattr/Propagate.sv b/grammars/silver/compiler/extension/autoattr/Propagate.sv index 86daf3f64..c21b1d9b7 100644 --- a/grammars/silver/compiler/extension/autoattr/Propagate.sv +++ b/grammars/silver/compiler/extension/autoattr/Propagate.sv @@ -57,7 +57,7 @@ top::AGDcl ::= attrs::NameList nt::QName ps::ProdNameList getKnownProds(nt.lookupType.fullName, top.env)); local dcl::AGDcl = foldr( - appendAGDcl(_, _), emptyAGDcl(), + appendAGDcl, emptyAGDcl(), map(propagateAspectDcl(_, attrs), includedProds)); forwards to @@ -72,14 +72,17 @@ top::AGDcl ::= d::ValueDclInfo attrs::NameList top.errors := if null(forward.errors) then [] - else [nested(top.location, s"In propagate of ${attrs.unparse} for production ${d.fullName}:", forward.errors)]; + else [nested( + getParsedOriginLocationOrFallback(top), + s"In propagate of ${attrs.unparse} for production ${d.fullName}:", + forward.errors)]; forwards to aspectProductionDcl( 'aspect', 'production', qName(d.fullName), aspectProductionSignature( aspectProductionLHSFull( - name(d.namedSignature.outputElement.elementName, top.location), + name(d.namedSignature.outputElement.elementName), d.namedSignature.outputElement.typerep), '::=', foldr( @@ -88,7 +91,7 @@ top::AGDcl ::= d::ValueDclInfo attrs::NameList map( \ ie::NamedSignatureElement -> aspectRHSElemFull( - name(ie.elementName, top.location), + name(ie.elementName), freshenType(ie.typerep, ie.typerep.freeVariables)), d.namedSignature.inputElements))), productionBody( @@ -136,7 +139,7 @@ top::ProductionStmt ::= attr::QName forwards to if !null(attr.lookupAttribute.errors) then errorProductionStmt(attr.lookupAttribute.errors) - else attr.lookupAttribute.dcl.propagateDispatcher(attr, top.location); + else attr.lookupAttribute.dcl.propagateDispatcher(attr); } abstract production propagateError diff --git a/grammars/silver/compiler/extension/autoattr/Threaded.sv b/grammars/silver/compiler/extension/autoattr/Threaded.sv index be2d30f6d..c613f3434 100644 --- a/grammars/silver/compiler/extension/autoattr/Threaded.sv +++ b/grammars/silver/compiler/extension/autoattr/Threaded.sv @@ -30,8 +30,8 @@ top::AGDcl ::= 'threaded' 'attribute' inh::Name ',' syn::Name tl::BracketedOptTy forwards to defsAGDcl( - [attrDef(defaultEnvItem(threadedInhDcl(inhFName, synFName, tl.freeVariables, te.typerep, nothing(), d.reversed, sourceGrammar=top.grammarName, sourceLocation=inh.location))), - attrDef(defaultEnvItem(threadedSynDcl(inhFName, synFName, tl.freeVariables, te.typerep, nothing(), d.reversed, sourceGrammar=top.grammarName, sourceLocation=syn.location)))]); + [attrDef(defaultEnvItem(threadedInhDcl(inhFName, synFName, tl.freeVariables, te.typerep, nothing(), d.reversed, sourceGrammar=top.grammarName, sourceLocation=inh.nameLoc))), + attrDef(defaultEnvItem(threadedSynDcl(inhFName, synFName, tl.freeVariables, te.typerep, nothing(), d.reversed, sourceGrammar=top.grammarName, sourceLocation=syn.nameLoc)))]); } concrete production collectionThreadedAttributeDcl @@ -67,8 +67,8 @@ top::AGDcl ::= 'threaded' 'attribute' inh::Name ',' syn::Name tl::BracketedOptTy -- The non-interfering way of doing this would be to split up the collection attr decl prodictions -- into a prod providing the defs, and a prod providing the translation... top.defs := - [attrDef(defaultEnvItem(threadedInhDcl(inhFName, synFName, tl.freeVariables, te.typerep, just(q.operation), d.reversed, sourceGrammar=top.grammarName, sourceLocation=inh.location))), - attrDef(defaultEnvItem(threadedSynDcl(inhFName, synFName, tl.freeVariables, te.typerep, just(q.operation), d.reversed, sourceGrammar=top.grammarName, sourceLocation=syn.location)))]; + [attrDef(defaultEnvItem(threadedInhDcl(inhFName, synFName, tl.freeVariables, te.typerep, just(q.operation), d.reversed, sourceGrammar=top.grammarName, sourceLocation=inh.nameLoc))), + attrDef(defaultEnvItem(threadedSynDcl(inhFName, synFName, tl.freeVariables, te.typerep, just(q.operation), d.reversed, sourceGrammar=top.grammarName, sourceLocation=syn.nameLoc)))]; forwards to appendAGDcl( @@ -122,8 +122,7 @@ top::ProductionStmt ::= isCol::Boolean rev::Boolean inh::Decorated! QName syn::S forwards to threadInhDcl( isCol, inh.name, syn, - map( - name(_, top.location), + map(name, lhsName :: (if rev then reverse(occursChildren) else occursChildren) ++ if null(getOccursDcl(syn, top.frame.lhsNtName, top.env)) && !null(top.frame.signature.inputElements) @@ -157,8 +156,7 @@ top::ProductionStmt ::= isCol::Boolean rev::Boolean inh::String syn::Decorated! forwards to threadSynDcl( isCol, inh, syn.name, - map( - name(_, top.location), + map(name, lhsName :: (if rev then reverse(occursChildren) else occursChildren) ++ [if !null(getValueDcl("forward", top.env)) then "forward" else lhsName])); diff --git a/grammars/silver/compiler/extension/autoattr/convenience/Convenience.sv b/grammars/silver/compiler/extension/autoattr/convenience/Convenience.sv index 9ae3e2a90..a91b2b0a1 100644 --- a/grammars/silver/compiler/extension/autoattr/convenience/Convenience.sv +++ b/grammars/silver/compiler/extension/autoattr/convenience/Convenience.sv @@ -16,7 +16,7 @@ top::AGDcl ::= 'functor' 'attribute' a::Name 'occurs' 'on' qs::QNames ';' forwards to appendAGDcl( functorAttributeDcl($1, $2, a, $7), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(a), botlNone()), qs.qnames)); + makeOccursDclsHelp(qNameWithTL(qNameId(a), botlNone()), qs.qnames)); } concrete production monoidAttributeDclMultiple @@ -26,7 +26,7 @@ top::AGDcl ::= 'monoid' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te::T forwards to appendAGDcl( monoidAttributeDcl($1, $2, a, tl, $5, te, $7, e, $9, q, $14), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(a), botlNone()), qs.qnames)); + makeOccursDclsHelp(qNameWithTL(qNameId(a), botlNone()), qs.qnames)); } concrete production tcMonoidAttributeDclMultiple @@ -36,7 +36,7 @@ top::AGDcl ::= 'monoid' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te::T forwards to appendAGDcl( tcMonoidAttributeDcl($1, $2, a, tl, $5, te, $10), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(a), botlNone()), qs.qnames)); + makeOccursDclsHelp(qNameWithTL(qNameId(a), botlNone()), qs.qnames)); } concrete production destructAttributeDclMultiple @@ -46,7 +46,7 @@ top::AGDcl ::= 'destruct' 'attribute' a::Name 'occurs' 'on' qs::QNames ';' forwards to appendAGDcl( destructAttributeDcl($1, $2, a, ';'), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(a), botlNone()), qs.qnames)); + makeOccursDclsHelp(qNameWithTL(qNameId(a), botlNone()), qs.qnames)); } concrete production equalityAttributeDclMultiple @@ -56,7 +56,7 @@ top::AGDcl ::= 'equality' 'attribute' syn::Name 'with' inh::QName 'occurs' 'on' forwards to appendAGDcl( equalityAttributeDcl($1, $2, syn, $4, inh, $9), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(syn), botlNone()), qs.qnames)); + makeOccursDclsHelp(qNameWithTL(qNameId(syn), botlNone()), qs.qnames)); } concrete production orderingAttributeDclMultiple @@ -67,8 +67,8 @@ top::AGDcl ::= 'ordering' 'attribute' keySyn::Name ',' syn::Name 'with' inh::QNa appendAGDcl( orderingAttributeDcl($1, $2, keySyn, $4, syn, $6, inh, $11), appendAGDcl( - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(keySyn), botlNone()), qs.qnames), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(syn), botlNone()), qs.qnames))); + makeOccursDclsHelp(qNameWithTL(qNameId(keySyn), botlNone()), qs.qnames), + makeOccursDclsHelp(qNameWithTL(qNameId(syn), botlNone()), qs.qnames))); } -- Deprecate? Eric suggested keeping this: https://github.com/melt-umn/silver/issues/431#issuecomment-760552226 @@ -117,8 +117,8 @@ top::AGDcl ::= 'biequality' 'attribute' synPartial::Name ',' syn::Name 'with' in appendAGDcl( biequalityAttributeDcl($1, $2, synPartial, ',', syn, 'with', inh, ';'), appendAGDcl( - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(synPartial), botlNone()), qs.qnames), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(syn), botlNone()), qs.qnames))); + makeOccursDclsHelp(qNameWithTL(qNameId(synPartial), botlNone()), qs.qnames), + makeOccursDclsHelp(qNameWithTL(qNameId(syn), botlNone()), qs.qnames))); } concrete production threadedAttributeDclMultiple @@ -129,8 +129,8 @@ top::AGDcl ::= 'threaded' 'attribute' inh::Name ',' syn::Name tl::BracketedOptTy appendAGDcl( threadedAttributeDcl($1, $2, inh, $4, syn, tl, $7, te, d, ';'), appendAGDcl( - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(inh), botlNone()), qs.qnames), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(syn), botlNone()), qs.qnames))); + makeOccursDclsHelp(qNameWithTL(qNameId(inh), botlNone()), qs.qnames), + makeOccursDclsHelp(qNameWithTL(qNameId(syn), botlNone()), qs.qnames))); } concrete production collectionThreadedAttributeDclMultiple @@ -141,6 +141,6 @@ top::AGDcl ::= 'threaded' 'attribute' inh::Name ',' syn::Name tl::BracketedOptTy appendAGDcl( collectionThreadedAttributeDcl($1, $2, inh, $4, syn, tl, $7, te, 'with', q, d, ';'), appendAGDcl( - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(inh), botlNone()), qs.qnames), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(syn), botlNone()), qs.qnames))); + makeOccursDclsHelp(qNameWithTL(qNameId(inh), botlNone()), qs.qnames), + makeOccursDclsHelp(qNameWithTL(qNameId(syn), botlNone()), qs.qnames))); } diff --git a/grammars/silver/compiler/extension/convenience/Convenience.sv b/grammars/silver/compiler/extension/convenience/Convenience.sv index 58b73bbbe..bb0587ad3 100644 --- a/grammars/silver/compiler/extension/convenience/Convenience.sv +++ b/grammars/silver/compiler/extension/convenience/Convenience.sv @@ -12,19 +12,19 @@ concrete production multipleAttributionDclsManyMany top::AGDcl ::= 'attribute' a::QNames2 'occurs' 'on' nts::QNames2 ';' { top.unparse = "attribute " ++ a.unparse ++ " occurs on " ++ nts.unparse ++ " ;" ; - forwards to makeOccursDcls(top.location, a.qnames, nts.qnames); + forwards to makeOccursDcls(a.qnames, nts.qnames); } concrete production multipleAttributionDclsSingleMany top::AGDcl ::= 'attribute' a::QName tl::BracketedOptTypeExprs 'occurs' 'on' nts::QNames2 ';' { top.unparse = "attribute " ++ a.unparse ++ " occurs on " ++ nts.unparse ++ " ;" ; - forwards to makeOccursDcls(top.location, [qNameWithTL(a, tl)], nts.qnames); + forwards to makeOccursDcls([qNameWithTL(a, tl)], nts.qnames); } concrete production multipleAttributionDclsManySingle top::AGDcl ::= 'attribute' a::QNames2 'occurs' 'on' nts::QNameWithTL ';' { top.unparse = "attribute " ++ a.unparse ++ " occurs on " ++ nts.unparse ++ " ;" ; - forwards to makeOccursDcls(top.location, a.qnames, [nts]); + forwards to makeOccursDcls(a.qnames, [nts]); } -- Multiple annotation occurs on statements @@ -32,19 +32,19 @@ concrete production multipleAnnotationDclsManyMany top::AGDcl ::= 'annotation' a::QNames2 'occurs' 'on' nts::QNames2 ';' { top.unparse = "annotation " ++ a.unparse ++ " occurs on " ++ nts.unparse ++ " ;" ; - forwards to makeOccursDcls(top.location, a.qnames, nts.qnames); + forwards to makeOccursDcls(a.qnames, nts.qnames); } concrete production multipleAnnotationDclsSingleMany top::AGDcl ::= 'annotation' a::QName tl::BracketedOptTypeExprs 'occurs' 'on' nts::QNames2 ';' { top.unparse = "annotation " ++ a.unparse ++ " occurs on " ++ nts.unparse ++ " ;" ; - forwards to makeOccursDcls(top.location, [qNameWithTL(a, tl)], nts.qnames); + forwards to makeOccursDcls([qNameWithTL(a, tl)], nts.qnames); } concrete production multipleAnnotationDclsManySingle top::AGDcl ::= 'annotation' a::QNames2 'occurs' 'on' nts::QNameWithTL ';' { top.unparse = "annotation " ++ a.unparse ++ " occurs on " ++ nts.unparse ++ " ;" ; - forwards to makeOccursDcls(top.location, a.qnames, [nts]); + forwards to makeOccursDcls(a.qnames, [nts]); } @@ -54,7 +54,7 @@ top::AGDcl ::= quals::NTDeclQualifiers 'nonterminal' id::Name tl::BracketedOptTy top.unparse = "nonterminal " ++ id.unparse ++ tl.unparse ++ " " ++ nm.unparse ++ " with " ++ attrs.unparse ++ " ;"; forwards to appendAGDcl( nonterminalDcl(quals, $2, id, tl, nm, $8), - makeOccursDcls(top.location, attrs.qnames, [qNameWithTL(qNameId(id), tl)])); + makeOccursDcls(attrs.qnames, [qNameWithTL(qNameId(id), tl)])); } action { insert semantic token IdTypeDcl_t at id.nameLoc; } @@ -66,7 +66,7 @@ top::AGDcl ::= 'inherited' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te top.unparse = "inherited attribute " ++ a.name ++ tl.unparse ++ " :: " ++ te.unparse ++ " occurs on " ++ qs.unparse ++ ";" ; forwards to appendAGDcl( attributeDclInh($1, $2, a, tl, $5, te, $10), - makeOccursDclsHelp(top.location, qNameWithTL(qNameId(a), tl), qs.qnames)); + makeOccursDclsHelp(qNameWithTL(qNameId(a), tl), qs.qnames)); } concrete production attributeDclSynMultiple @@ -75,7 +75,7 @@ top::AGDcl ::= 'synthesized' 'attribute' a::Name tl::BracketedOptTypeExprs '::' top.unparse = "synthesized attribute " ++ a.name ++ tl.unparse ++ " :: " ++ te.unparse ++ " occurs on " ++ qs.unparse ++ ";" ; forwards to appendAGDcl( attributeDclSyn($1, $2, a, tl, $5, te, $10), - makeOccursDclsHelp(top.location, qNameWithTL(qNameId(a), tl), qs.qnames)); + makeOccursDclsHelp(qNameWithTL(qNameId(a), tl), qs.qnames)); } concrete production attributeDclTransMultiple @@ -84,7 +84,7 @@ top::AGDcl ::= 'translation' 'attribute' a::Name tl::BracketedOptTypeExprs '::' top.unparse = "translation attribute " ++ a.name ++ tl.unparse ++ " :: " ++ te.unparse ++ " occurs on " ++ qs.unparse ++ ";" ; forwards to appendAGDcl( attributeDclTrans($1, $2, a, tl, $5, te, $10), - makeOccursDclsHelp(top.location, qNameWithTL(qNameId(a), tl), qs.qnames)); + makeOccursDclsHelp(qNameWithTL(qNameId(a), tl), qs.qnames)); } concrete production collectionAttributeDclInhMultiple @@ -93,7 +93,7 @@ top::AGDcl ::= 'inherited' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te top.unparse = "inherited attribute " ++ a.name ++ tl.unparse ++ " :: " ++ te.unparse ++ " with " ++ q.unparse ++ " ;" ; forwards to appendAGDcl( collectionAttributeDclInh($1, $2, a, tl, $5, te, $7, q, $12), - makeOccursDclsHelp(top.location, qNameWithTL(qNameId(a), tl), qs.qnames)); + makeOccursDclsHelp(qNameWithTL(qNameId(a), tl), qs.qnames)); } concrete production collectionAttributeDclSynMultiple @@ -102,7 +102,7 @@ top::AGDcl ::= 'synthesized' 'attribute' a::Name tl::BracketedOptTypeExprs '::' top.unparse = "synthesized attribute " ++ a.name ++ tl.unparse ++ " :: " ++ te.unparse ++ " with " ++ q.unparse ++ " ;" ; forwards to appendAGDcl( collectionAttributeDclSyn($1, $2, a, tl, $5, te, $7, q, $12), - makeOccursDclsHelp(top.location, qNameWithTL(qNameId(a), tl), qs.qnames)); + makeOccursDclsHelp(qNameWithTL(qNameId(a), tl), qs.qnames)); } diff --git a/grammars/silver/compiler/extension/convenience/Lists.sv b/grammars/silver/compiler/extension/convenience/Lists.sv index 4130d6468..9c3d3c3c4 100644 --- a/grammars/silver/compiler/extension/convenience/Lists.sv +++ b/grammars/silver/compiler/extension/convenience/Lists.sv @@ -54,21 +54,20 @@ top::QNames ::= id1::QNameWithTL ',' id2::QNames -------------------------------------------------------------------------------- function makeOccursDcls -AGDcl ::= l::Location ats::[QNameWithTL] nts::[QNameWithTL] +AGDcl ::= ats::[QNameWithTL] nts::[QNameWithTL] { return if null(ats) then emptyAGDcl() - else appendAGDcl(makeOccursDclsHelp(l, head(ats), nts), makeOccursDcls(l, tail(ats), nts)); + else appendAGDcl(makeOccursDclsHelp(head(ats), nts), makeOccursDcls(tail(ats), nts)); } function makeOccursDclsHelp -AGDcl ::= l::Location at::QNameWithTL nts::[QNameWithTL] +AGDcl ::= at::QNameWithTL nts::[QNameWithTL] { return if null(nts) then emptyAGDcl() - else appendAGDcl( - attributionDcl('attribute', at.qnwtQN, at.qnwtTL, 'occurs', 'on', head(nts).qnwtQN, head(nts).qnwtTL, ';'), - makeOccursDclsHelp(l, at, tail(nts))); + else appendAGDcl(attributionDcl('attribute', at.qnwtQN, at.qnwtTL, 'occurs', 'on', head(nts).qnwtQN, head(nts).qnwtTL, ';'), + makeOccursDclsHelp(at, tail(nts))); } diff --git a/grammars/silver/compiler/extension/convenience/Productions.sv b/grammars/silver/compiler/extension/convenience/Productions.sv index c9780c570..c4090fc18 100644 --- a/grammars/silver/compiler/extension/convenience/Productions.sv +++ b/grammars/silver/compiler/extension/convenience/Productions.sv @@ -59,9 +59,8 @@ top::ProductionDclStmt ::= optn::OptionalName v::ProdVBar name( "p_" ++ substitute(":", "_", top.grammarName) - ++ "_" ++ substitute(".", "_", top.location.filename) - ++ "_" ++ toString(v.line) ++ "_" ++ toString(v.column), - v.location) + ++ "_" ++ substitute(".", "_", v.location.filename) + ++ "_" ++ toString(v.line) ++ "_" ++ toString(v.column)) | anOptionalName(_, n, _) -> n end; diff --git a/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv b/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv index 9ab8d2a78..ebae714d5 100644 --- a/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv +++ b/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv @@ -5,11 +5,10 @@ import silver:compiler:modification:let_fix; @{- - From a list of Patterns, makes a PatternList with the right list-shaped productions. - @param l the list of patterns to modify - - @param defaultLoc the location to provide for the patternListNil construct (which needs a location). - @return A patternList List-Like Nonterminal instance. -} function makePatternListFromListofPatterns -PatternList ::= l::[Pattern] defaultLoc::Location +PatternList ::= l::[Pattern] { return foldr( @@ -57,19 +56,17 @@ PatternList ::= pl::PatternList | prodAppPattern(_,_,ps,_) -> collectPatternsFromPatternList(ps,[]) | _ -> [] end, - collectPatternsFromPatternList(pl,[])))), - pl.location); + collectPatternsFromPatternList(pl,[]))))); } @{- - Takes in a regular list of Expr, turns them into an instance of the Exprs production. - @param l A list of Expr's. - - @param defaultLoc The default location to provide for the ExprsEmpty production (nil-like construct). - @return A combined Exprs List-like construct made from the Expr's in the input list. -} function makeExprsFromExprList -Exprs ::= l::[Expr] defaultLoc::Location +Exprs ::= l::[Expr] { return if null(l) then exprsEmpty() @@ -115,11 +112,10 @@ function collectMatchRulesfromMRuleList - This function goes into a production pattern (if it is one), extracts out the sub pattern for that production, and generates names for each element of that sub pattern. - e.g Given `silver_matchRule {foo(bar(3,x),y) -> y+1 }` where `foo`,`bar` are productions, it returns `[_gen1,_gen2]` (where the numbers are generated from genInt) - @param mr An instance of MatchRule - - @param loc A default location to provide for when we use the patternList_nil production. - @return A list of names where each name corresponds to an argument to the production subpattern. -} function makeGeneratedNamesFromMatchRule -[Name] ::= mr::MatchRule loc::Location +[Name] ::= mr::MatchRule { local patList::PatternList = case mr of @@ -131,7 +127,7 @@ function makeGeneratedNamesFromMatchRule return map(\pat::Pattern -> - name("__generated_" ++ toString(genInt()), loc), + name("__generated_" ++ toString(genInt())), collectPatternsFromPatternList(patList,[])); } @@ -141,11 +137,10 @@ function makeGeneratedNamesFromMatchRule - This function goes into a production pattern (if it is one), extracts out the sub pattern for that production, and generates wildcard patterns for each param, giving back a production pattern with the appropriate number of wildcards. - @param mr An instance of MatchRule - - @param loc A default location to provide for when we use the patternList_nil production. - @return A wildcard matchRule with the same number of params as the production pattern. -} function makeWildcardsFromMatchRule -PatternList ::= mr::MatchRule loc::Location +PatternList ::= mr::MatchRule { local patList::PatternList = case mr of @@ -158,19 +153,17 @@ PatternList ::= mr::MatchRule loc::Location return makePatternListFromListofPatterns( map(\pat::Pattern -> wildcPattern('_'), - collectPatternsFromPatternList(patList,[])), - loc); + collectPatternsFromPatternList(patList,[]))); } @{- - - This function takes in a name and location and returns a concrete definition LHS element that is the result of applying the concrete definition production to them. + - This function takes in a name and returns a concrete definition LHS element that is the result of applying the concrete definition production to them. - @param name The name being defined. - - @param loc the location of the definition. - - @return a concrete definition LHS element that uses the name and location provided. + - @return a concrete definition LHS element that uses the name provided. -} function makeDefinitionLHSFromName -DefLHS ::= name::Name loc::Location +DefLHS ::= name::Name { return concreteDefLHS(qNameId(name)); } @@ -182,11 +175,10 @@ DefLHS ::= name::Name loc::Location - @param newName The name being defined. - @param aspectLHS a convenience aspect LHS expression that contains the name and type of the term that our generated aspect production returns. - @param e The expression that uses the name we're defining and will be surrounded by let. - - @param loc the location of the definition. - @return A Let expr that binds the name we provide to the "top" term in our aspect production with let, and surrounds the expression we gave. -} function makeLetExprForTopRenaming -Expr ::= newName::Name aspectLHS::Decorated ConvAspectLHS e::Expr loc::Location +Expr ::= newName::Name aspectLHS::Decorated ConvAspectLHS e::Expr { return letp( assignExpr( @@ -204,17 +196,16 @@ Expr ::= newName::Name aspectLHS::Decorated ConvAspectLHS e::Expr loc::Location - @param patList A list of matchrules that represents a grouping of match rules with similar patterns. - @param aspectLHS a convenience aspect LHS expression that contains the name and type of the term that our generated aspect production returns. - @param e The Expr on the other side of the arrow of the match rule - - @param loc The location where the aspect pattern is defined - @return An expression from the wildcard matchrule we can use in making convenience aspects. -} function makeWildcardExprFromPatternList -Expr ::= patList::PatternList aspectLHS::Decorated ConvAspectLHS e::Expr loc::Location +Expr ::= patList::PatternList aspectLHS::Decorated ConvAspectLHS e::Expr { return case patList of | patternList_one(wildcPattern(_)) -> e | patternList_more(wildcPattern(_),_,_) -> e - | patternList_one(varPattern(name)) -> makeLetExprForTopRenaming(name, aspectLHS, e, loc) - | patternList_more(varPattern(name),_,_) -> makeLetExprForTopRenaming(name, aspectLHS, e, loc) + | patternList_one(varPattern(name)) -> makeLetExprForTopRenaming(name, aspectLHS, e) + | patternList_more(varPattern(name),_,_) -> makeLetExprForTopRenaming(name, aspectLHS, e) | _ -> errorExpr([]) end; } @@ -224,13 +215,13 @@ Expr ::= patList::PatternList aspectLHS::Decorated ConvAspectLHS e::Expr loc::Lo - @param aspectLHS a convenience aspect LHS expression that contains the name and type of the term that our generated aspect production returns. - @param aspectAttr The aspect attribute we're generating productions for - @param eqKind The operator that assigns or binds to the attribute - - @param location The location where the aspect pattern is defined - @param env A Environment for looking up production types. - @return A pair of a single AgDcl that defines the aspect production we're generating, and a list of warnings or errors that came from generating the AgDcl. -} function extractAspectAgDclFromRuleList -Pair ::= rules::[MatchRule] aspectLHS::Decorated ConvAspectLHS aspectAttr::QNameAttrOccur eqKind::ConvenienceAspectEquationKind location::Location env::Env +Pair ::= rules::[MatchRule] aspectLHS::Decorated ConvAspectLHS aspectAttr::QNameAttrOccur eqKind::ConvenienceAspectEquationKind env::Env { + attachNote if null(rules) then logicalLocationFromOrigin(aspectLHS) else logicalLocationFromOrigin(head(rules)); local lookupProdInputTypes::([Type] ::= String) = \prodName::String -> case (getValueDcl(prodName,env)) of @@ -259,24 +250,15 @@ Pair ::= rules::[MatchRule] aspectLHS::Decorated ConvAspectLHS map((\mRule::MatchRule -> case mRule of | matchRule_c(pl,arrow,e) -> matchRule_c( extractSubPatternListsFromProdPatterns(pl), - arrow, - eation) + arrow, e) | matchRuleWhen_c(pl,whenKWD,cond,arrow,e) -> matchRuleWhen_c( extractSubPatternListsFromProdPatterns(pl), - whenKWD, - cond, - arrow, - eation) + whenKWD, cond, arrow, e) | matchRuleWhenMatches_c(pl,whenKWD,cond,matches,p,arrow,e) -> matchRuleWhenMatches_c( extractSubPatternListsFromProdPatterns(pl), - whenKWD, - cond, - matches, - p, - arrow, - eation) + whenKWD, cond, matches, p, arrow, e) end), _); @@ -288,7 +270,7 @@ Pair ::= rules::[MatchRule] aspectLHS::Decorated ConvAspectLHS \paramsCaseSubExpr::[Expr] mRules::[MatchRule] -> caseExpr_c( 'case', - makeExprsFromExprList(paramsCaseSubExpr,location), + makeExprsFromExprList(paramsCaseSubExpr), 'of', terminal(Opt_Vbar_t, "|"), makeMRuleListFromListMatchRules(transformPatternMatchRule(mRules)), @@ -303,21 +285,17 @@ Pair ::= rules::[MatchRule] aspectLHS::Decorated ConvAspectLHS $Name{aspectLHS.aspectName}::$TypeExpr{aspectLHS.aspectType} ::= $AspectRHS{prodParams} { $ProductionStmt{ eqKind.makeAspectEquation( - makeDefinitionLHSFromName( - aspectLHS.aspectName, - head(rules).location), + makeDefinitionLHSFromName(aspectLHS.aspectName), aspectAttr, - paramsCaseExpr, - paramsCaseExpr.location)}} + paramsCaseExpr)}} }; - return case rules of | matchRule_c(patternList_one(prodAppPattern(name,_,_,_)),_,e) :: _ -> -- Handling for production patterns - let paramNames :: [Name] = makeGeneratedNamesFromMatchRule(head(rules),location) + let paramNames :: [Name] = makeGeneratedNamesFromMatchRule(head(rules)) in ( makeAspectProduction( @@ -333,7 +311,7 @@ Pair ::= rules::[MatchRule] aspectLHS::Decorated ConvAspectLHS end | matchRule_c(patternList_more(prodAppPattern(name,_,_,_),_,_),_,e) :: _ -> - let paramNames :: [Name] = makeGeneratedNamesFromMatchRule(head(rules),location) + let paramNames :: [Name] = makeGeneratedNamesFromMatchRule(head(rules)) in ( makeAspectProduction( @@ -354,12 +332,9 @@ Pair ::= rules::[MatchRule] aspectLHS::Decorated ConvAspectLHS aspect default production $Name{aspectLHS.aspectName}::$TypeExpr{aspectLHS.aspectType} ::= { $ProductionStmt{eqKind.makeAspectEquation( - makeDefinitionLHSFromName( - aspectLHS.aspectName, - head(rules).location), + makeDefinitionLHSFromName(aspectLHS.aspectName), aspectAttr, - e, - head(rules).location)}} + e)}} }, []) | matchRule_c(patternList_more(wildcPattern(_),_,_),_,e) :: _ -> @@ -368,12 +343,9 @@ Pair ::= rules::[MatchRule] aspectLHS::Decorated ConvAspectLHS aspect default production $Name{aspectLHS.aspectName}::$TypeExpr{aspectLHS.aspectType} ::= { $ProductionStmt{eqKind.makeAspectEquation( - makeDefinitionLHSFromName( - aspectLHS.aspectName, - head(rules).location), + makeDefinitionLHSFromName(aspectLHS.aspectName), aspectAttr, - e, - head(rules).location)}} + e)}} }, []) -- Handling for varpatterns @@ -383,12 +355,9 @@ Pair ::= rules::[MatchRule] aspectLHS::Decorated ConvAspectLHS aspect default production $Name{aspectLHS.aspectName}::$TypeExpr{aspectLHS.aspectType} ::= { $ProductionStmt{eqKind.makeAspectEquation( - makeDefinitionLHSFromName( - aspectLHS.aspectName, - head(rules).location), + makeDefinitionLHSFromName(spectLHS.aspectName), aspectAttr, - makeLetExprForTopRenaming(name, aspectLHS, e, head(rules).location), - head(rules).location)}} + makeLetExprForTopRenaming(name, aspectLHS, e))}} }, []) | matchRule_c(patternList_more(varPattern(name),_,_),_,e) :: _ -> @@ -398,17 +367,15 @@ Pair ::= rules::[MatchRule] aspectLHS::Decorated ConvAspectLHS $Name{aspectLHS.aspectName}::$TypeExpr{aspectLHS.aspectType} ::= { $ProductionStmt{eqKind.makeAspectEquation( makeDefinitionLHSFromName( - aspectLHS.aspectName, - head(rules).location), + aspectLHS.aspectName), aspectAttr, - makeLetExprForTopRenaming(name, aspectLHS, e, head(rules).location), - head(rules).location)}} + makeLetExprForTopRenaming(name, aspectLHS, e))}} }, []) | _ -> ( emptyAGDcl(), - [err(location,"Patterns in aspect convenience syntax should be productions,wildcards, or varpatterns only")]) + [errFromOrigin(ambientOrigin(),"Patterns in aspect convenience syntax should be productions,wildcards, or varpatterns only")]) end; } @@ -552,37 +519,27 @@ top::AGDcl ::= attr::QNameAttrOccur aspectLHS::Decorated ConvAspectLHS eqKind::C local groupedMRulesWithExtraWildcards::[[MatchRule]] = case mListWildcardAndAfter of | [] -> groupedMRules - | matchRule_c(patList,_,e) :: _ -> map( - \mList::[MatchRule] -> - case mList of - | matchRule_c(patternList_one(prodAppPattern(name,leftparen,patternList,rightparen)),arrow,_) :: _ -> - let wildcardPatternList :: PatternList = makeWildcardsFromMatchRule(head(mList),(head(mListWildcardAndAfter)).location) - in - let expr :: Expr = makeWildcardExprFromPatternList(patList, aspectLHS, e, (head(mListWildcardAndAfter)).location) + | firstRule :: _ when firstRule matches matchRule_c(patList,_,e) -> map( + \mList::[MatchRule] -> attachNote logicalLocationFromOrigin(firstRule) on + case mList of + | matchRule_c(patternList_one(prodAppPattern(name,leftparen,patternList,rightparen)),arrow,_) :: _ -> + let wildcardPatternList :: PatternList = makeWildcardsFromMatchRule(head(mList)) in - mList ++ [matchRule_c(patternList_one(prodAppPattern(name,leftparen,wildcardPatternList,rightparen, location=(head(mListWildcardAndAfter)).location),location=(head(mListWildcardAndAfter)).location),arrow,expr,location=(head(mListWildcardAndAfter)).location)] + let expr :: Expr = makeWildcardExprFromPatternList(patList, aspectLHS, e) + in + mList ++ [matchRule_c(patternList_one(prodAppPattern(name,leftparen,wildcardPatternList,rightparen)),arrow,expr)] + end end - end - | matchRule_c(patternList_more(prodAppPattern(name,_,wildcardPatternList,_),_,_),arrow,_) :: _ -> - let wildcardPatternList :: PatternList = makeWildcardsFromMatchRule(head(mList),(head(mListWildcardAndAfter)).location) - in - let expr :: Expr = makeWildcardExprFromPatternList(patList, aspectLHS, e, (head(mListWildcardAndAfter)).location) + | matchRule_c(patternList_more(prodAppPattern(name,_,wildcardPatternList,_),_,_),arrow,_) :: _ -> + let wildcardPatternList :: PatternList = makeWildcardsFromMatchRule(head(mList)) in - mList ++ [matchRule_c( - patternList_one( - prodAppPattern( - name, - '(', - wildcardPatternList, - ')', - location=(head(mListWildcardAndAfter)).location), - location=(head(mListWildcardAndAfter)).location), - arrow, - expr, - location=(head(mListWildcardAndAfter)).location)] + let expr :: Expr = makeWildcardExprFromPatternList(patList, aspectLHS, e) + in + mList ++ [matchRule_c(patternList_one(prodAppPattern(name, '(', wildcardPatternList, ')')), arrow, expr)] + end end + | otherwise -> otherwise end - | otherwise -> otherwise end, groupedMRules) | firstRule::rest -> groupedMRules @@ -590,7 +547,7 @@ top::AGDcl ::= attr::QNameAttrOccur aspectLHS::Decorated ConvAspectLHS eqKind::C local groupExtractResults::[Pair] = map( - extractAspectAgDclFromRuleList(_,aspectLHS,attr,eqKind,top.location, top.env), + extractAspectAgDclFromRuleList(_,aspectLHS,attr,eqKind,top.env), groupedMRulesWithExtraWildcards); local groupExtractErrors::[Message] = foldr(append, [], (map(snd(_), groupExtractResults))); @@ -609,7 +566,7 @@ top::AGDcl ::= attr::QNameAttrOccur aspectLHS::Decorated ConvAspectLHS eqKind::C -- This means that nothing is past the wildcard pattern, which is good. then groupExtractErrors -- Something _is_ past the wildcard pattern - else [wrn(((head(mListAfterWildcard)).location),"This pattern and the ones that follow are being ignored.")] + else [wrnFromOrigin(head(mListAfterWildcard),"This pattern and the ones that follow are being ignored.")] ++ groupExtractErrors; -- Errors are filtered out here in a move we call in the business "an infelicity" @@ -622,7 +579,7 @@ top::AGDcl ::= attr::QNameAttrOccur aspectLHS::Decorated ConvAspectLHS eqKind::C \message::Message -> -- Note: If you see this error unexpectedly that might mean the string for this error has changed. case message of - | err(l, "Pattern has overlapping cases!") when l == top.location -> false + | err(l, "Pattern has overlapping cases!") when l == getParsedOriginLocationOrFallback(top) -> false | _ -> true end, forward.errors); diff --git a/grammars/silver/compiler/extension/convenienceaspects/ConcreteSyntax.sv b/grammars/silver/compiler/extension/convenienceaspects/ConcreteSyntax.sv index bd12bd1c8..160592451 100644 --- a/grammars/silver/compiler/extension/convenienceaspects/ConcreteSyntax.sv +++ b/grammars/silver/compiler/extension/convenienceaspects/ConcreteSyntax.sv @@ -4,7 +4,7 @@ import silver:compiler:modification:collection; import silver:compiler:extension:constructparser; @{- @hide -} -synthesized attribute makeAspectEquation::(ProductionStmt ::= DefLHS QNameAttrOccur Expr Location); +synthesized attribute makeAspectEquation::(ProductionStmt ::= DefLHS QNameAttrOccur Expr); @{- - A nonterminal describing what binding to use on the attribute in the generated aspects. diff --git a/grammars/silver/compiler/extension/data/DataDcl.sv b/grammars/silver/compiler/extension/data/DataDcl.sv index 3962f4ba8..d0b482c80 100644 --- a/grammars/silver/compiler/extension/data/DataDcl.sv +++ b/grammars/silver/compiler/extension/data/DataDcl.sv @@ -65,7 +65,7 @@ top::DataConstructor ::= id::Name rhs::ProductionRHS top.unparse = s"${id.unparse} ${rhs.unparse}"; local ntBaseType::TypeExpr = nominalTypeExpr( - qNameTypeId(terminal(IdUpper_t, top.ntName, top.location))); + qNameTypeId(terminal(IdUpper_t, top.ntName, id.nameLoc))); local ntType::TypeExpr = case top.ntTypeArgs of | botlNone() -> ntBaseType diff --git a/grammars/silver/compiler/extension/deriving/Derive.sv b/grammars/silver/compiler/extension/deriving/Derive.sv index 46d04343b..7c9803ff8 100644 --- a/grammars/silver/compiler/extension/deriving/Derive.sv +++ b/grammars/silver/compiler/extension/deriving/Derive.sv @@ -114,7 +114,7 @@ top::AGDcl ::= nt::Decorated! QName consVarBinder(_, ',', _), nilVarBinder(), map(\ i::Integer -> - varVarBinder(name(s"a${toString(i)}", top.location)), + varVarBinder(name(s"a${toString(i)}")), range(0, length(prod.namedSignature.inputElements)))), ')', '->', matchPrimitive( Silver_Expr {y}, @@ -125,7 +125,7 @@ top::AGDcl ::= nt::Decorated! QName consVarBinder(_, ',', _), nilVarBinder(), map(\ i::Integer -> - varVarBinder(name(s"b${toString(i)}", top.location)), + varVarBinder(name(s"b${toString(i)}")), range(0, length(prod.namedSignature.inputElements)))), ')', '->', foldr( and(_, '&&', _), @@ -134,8 +134,7 @@ top::AGDcl ::= nt::Decorated! QName \ i::Integer -> Silver_Expr { $name{s"a${toString(i)}"} == $name{s"b${toString(i)}"} }, range(0, length(prod.namedSignature.inputElements)))))), Silver_Expr {false})), - includedProds), - top.location), + includedProds)), Silver_Expr {silver:core:error("Unexpected production in derived Eq instance!")}), map( \ anno::NamedSignatureElement -> @@ -156,7 +155,7 @@ top::AGDcl ::= nt::Decorated! QName consVarBinder(_, ',', _), nilVarBinder(), map(\ i::Integer -> - varVarBinder(name(s"a${toString(i)}", top.location)), + varVarBinder(name(s"a${toString(i)}")), range(0, length(prod.namedSignature.inputElements)))), ')', '->', matchPrimitive( Silver_Expr {y}, @@ -167,7 +166,7 @@ top::AGDcl ::= nt::Decorated! QName consVarBinder(_, ',', _), nilVarBinder(), map(\ i::Integer -> - varVarBinder(name(s"b${toString(i)}", top.location)), + varVarBinder(name(s"b${toString(i)}")), range(0, length(prod.namedSignature.inputElements)))), ')', '->', foldr( or(_, '||', _), @@ -176,8 +175,7 @@ top::AGDcl ::= nt::Decorated! QName \ i::Integer -> Silver_Expr { $name{s"a${toString(i)}"} != $name{s"b${toString(i)}"} }, range(0, length(prod.namedSignature.inputElements)))))), Silver_Expr {true})), - includedProds), - top.location), + includedProds)), Silver_Expr {silver:core:error("Unexpected production in derived Eq instance!")}), map( \ anno::NamedSignatureElement -> @@ -232,7 +230,7 @@ top::AGDcl ::= nt::Decorated! QName consVarBinder(_, ',', _), nilVarBinder(), map(\ i::Integer -> - varVarBinder(name(s"a${toString(i)}", top.location)), + varVarBinder(name(s"a${toString(i)}")), range(0, length(prod.namedSignature.inputElements)))), ')', '->', matchPrimitive( Silver_Expr {y}, @@ -248,7 +246,7 @@ top::AGDcl ::= nt::Decorated! QName map( \ i::Integer -> if prod.fullName == prod2.fullName - then varVarBinder(name(s"b${toString(i)}", top.location)) + then varVarBinder(name(s"b${toString(i)}")) else ignoreVarBinder('_'), range(0, length(prod2.namedSignature.inputElements)))), ')', '->', if prod.fullName < prod2.fullName @@ -263,11 +261,9 @@ top::AGDcl ::= nt::Decorated! QName map( \ i::Integer -> Silver_Expr { silver:core:compare($name{s"a${toString(i)}"}, $name{s"b${toString(i)}"}) }, range(0, length(prod2.namedSignature.inputElements))))), - includedProds), - top.location), + includedProds)), Silver_Expr {silver:core:error("Unexpected production in derived Ord instance!")})), - includedProds), - top.location), + includedProds)), Silver_Expr {silver:core:error("Unexpected production in derived Ord instance!")}), map( \ anno::NamedSignatureElement -> @@ -278,12 +274,12 @@ top::AGDcl ::= nt::Decorated! QName } function foldPrimPatterns -PrimPatterns ::= ps::[PrimPattern] loc::Location +PrimPatterns ::= ps::[PrimPattern] { return case ps of | [h] -> onePattern(h) - | h :: t -> consPattern(h, '|', foldPrimPatterns(t, loc)) + | h :: t -> consPattern(h, '|', foldPrimPatterns(t)) | [] -> error("empty patterns") end; } diff --git a/grammars/silver/compiler/extension/do_notation/Syntax.sv b/grammars/silver/compiler/extension/do_notation/Syntax.sv index 2b24e9a7b..0e51c0a98 100644 --- a/grammars/silver/compiler/extension/do_notation/Syntax.sv +++ b/grammars/silver/compiler/extension/do_notation/Syntax.sv @@ -121,8 +121,8 @@ top::DoBody ::= b::DoBinding rest::DoBody if top.isApplicative then foldl( - \ trans::Expr e::Expr -> mkStrFunctionInvocation(top.location, "silver:core:ap", [trans, e]), - mkStrFunctionInvocation(top.location, "silver:core:map", [ + \ trans::Expr e::Expr -> mkStrFunctionInvocation("silver:core:ap", [trans, e]), + mkStrFunctionInvocation("silver:core:map", [ foldr( \ el::ProductionRHSElem trans::Expr -> lambdap( @@ -172,7 +172,7 @@ top::DoBody ::= b::DoBinding rest::DoBody zipWith( \ i::Integer item::(String, TypeExpr) -> letDoBinding( - 'let', name(item.1, top.location), '::', item.2, '=', + 'let', name(item.1), '::', item.2, '=', select(Silver_Expr { $name{recVarName} }, 1, i + 1, length(top.recBindings)), ';'), range(0, length(top.recBindings)), top.recBindings)); @@ -182,7 +182,7 @@ top::DoBody ::= b::DoBinding rest::DoBody else if !ts:isEmpty(newRecVars) then consDoBody( bindDoBinding( - name(recVarName, top.location), '::', recVarType, '<-', + name(recVarName), '::', recVarType, '<-', Silver_Expr { mfix( \ $name{recVarName}::$TypeExpr{recVarType} -> @@ -218,7 +218,7 @@ top::DoBody ::= 'return' e::Expr ';' top.appBindings = []; top.appExprs = []; top.appResult = e; - top.transform = mkStrFunctionInvocation(top.location, "silver:core:pure", [e]); + top.transform = mkStrFunctionInvocation("silver:core:pure", [e]); top.recBindings = []; top.recBody = top.recRes; top.mdoTransform = top; @@ -239,7 +239,7 @@ top::DoBinding ::= n::Name DoDoubleColon_t t::TypeExpr '<-' e::Expr ';' productionRHSElem(n, terminal(ColonColon_t, "::"), t), productionRHSNil()), top.transformIn); - top.transform = mkStrFunctionInvocation(top.location, "silver:core:bind", [e, cont]); + top.transform = mkStrFunctionInvocation("silver:core:bind", [e, cont]); top.recBindings = [(n.name, t)]; } @@ -252,7 +252,7 @@ top::DoBinding ::= e::Expr ';' top.appBindings = [productionRHSElemType(typerepTypeExpr(freshType()))]; top.appExprs = [e]; - top.transform = mkStrFunctionInvocation(top.location, "silver:core:applySecond", [e, top.transformIn]); + top.transform = mkStrFunctionInvocation("silver:core:applySecond", [e, top.transformIn]); top.recBindings = []; } diff --git a/grammars/silver/compiler/extension/doc/core/AGDcl.sv b/grammars/silver/compiler/extension/doc/core/AGDcl.sv index af9ed6a97..8d1a58a4b 100644 --- a/grammars/silver/compiler/extension/doc/core/AGDcl.sv +++ b/grammars/silver/compiler/extension/doc/core/AGDcl.sv @@ -19,7 +19,7 @@ top::AGDcl ::= 'function' id::Name ns::FunctionSignature body::ProductionBody { top.docForName = id.name; top.docUnparse = "`function " ++ id.name ++ "`   (`" ++ ns.unparse ++ "`)"; - top.docDcls := [(id.name, docDclInfo(id.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(id.name, docDclInfo(id.name, sourceLocation=id.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -37,7 +37,7 @@ top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::Pr { top.docForName = id.name; top.docUnparse = "`abstract production " ++ id.name ++ "`   (`" ++ ns.unparse ++ "`)"; - top.docDcls := [(id.name, docDclInfo(id.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(id.name, docDclInfo(id.name, sourceLocation=id.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -46,7 +46,7 @@ top::AGDcl ::= 'concrete' 'production' id::Name ns::ProductionSignature pm::Prod { top.docForName = id.name; top.docUnparse = "`concrete production " ++ id.name ++ "`   (`" ++ ns.unparse ++ "`)"; - top.docDcls := [(id.name, docDclInfo(id.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(id.name, docDclInfo(id.name, sourceLocation=id.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -55,7 +55,7 @@ top::AGDcl ::= 'synthesized' 'attribute' a::Name tl::BracketedOptTypeExprs '::' { top.docForName = a.name; top.docUnparse = s"`synthesized attribute ${a.name}${tl.unparse} :: ${te.unparse}`"; - top.docDcls := [(a.name, docDclInfo(a.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(a.name, docDclInfo(a.name, sourceLocation=a.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -64,7 +64,7 @@ top::AGDcl ::= 'inherited' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te { top.docForName = a.name; top.docUnparse = s"`inherited attribute ${a.name}${tl.unparse} :: ${te.unparse}`"; - top.docDcls := [(a.name, docDclInfo(a.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(a.name, docDclInfo(a.name, sourceLocation=a.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -73,7 +73,7 @@ top::AGDcl ::= 'translation' 'attribute' a::Name tl::BracketedOptTypeExprs '::' { top.docForName = a.name; top.docUnparse = s"`translation attribute ${a.name}${tl.unparse} :: ${te.unparse}`"; - top.docDcls := [(a.name, docDclInfo(a.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(a.name, docDclInfo(a.name, sourceLocation=a.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -82,7 +82,7 @@ top::AGDcl ::= quals::NTDeclQualifiers 'nonterminal' id::Name tl::BracketedOptTy { top.docForName = id.name; top.docUnparse = s"`${quals.docUnparse}nonterminal ${id.name}${tl.unparse}`"; - top.docDcls := [(id.name, docDclInfo(id.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(id.name, docDclInfo(id.name, sourceLocation=id.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -100,7 +100,7 @@ top::AGDcl ::= t::TerminalKeywordModifier id::Name r::RegExpr tm::TerminalModifi { top.docForName = id.name; top.docUnparse = s"`terminal ${id.unparse}`"; - top.docDcls := [(id.name, docDclInfo(id.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(id.name, docDclInfo(id.name, sourceLocation=id.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -109,7 +109,7 @@ top::AGDcl ::= 'lexer' 'class' id::Name modifiers::LexerClassModifiers ';' { top.docForName = id.name; top.docUnparse = s"`lexer class ${id.unparse} ${modifiers.unparse}`"; - top.docDcls := [(id.name, docDclInfo(id.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(id.name, docDclInfo(id.name, sourceLocation=id.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -118,7 +118,7 @@ top::AGDcl ::= 'parser' n::Name '::' t::TypeExpr '{' m::ParserComponents '}' { top.docForName = n.name; top.docUnparse = s"`parser ${n.unparse} :: ${t.unparse}`"; - top.docDcls := [(n.name, docDclInfo(n.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(n.name, docDclInfo(n.name, sourceLocation=n.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -127,7 +127,7 @@ top::AGDcl ::= 'annotation' a::QName tl::BracketedOptTypeExprs '::' te::TypeExpr { top.docForName = a.name; top.docUnparse = s"`annotation ${a.unparse}${tl.unparse} :: ${te.unparse}`"; - top.docDcls := [(a.name, docDclInfo(a.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(a.name, docDclInfo(a.name, sourceLocation=a.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -136,7 +136,7 @@ top::AGDcl ::= 'equality' 'attribute' syn::Name 'with' inh::QName ';' { top.docForName = syn.name; top.docUnparse = s"`equality attribute ${syn.name} with ${inh.name}`"; - top.docDcls := [(syn.name, docDclInfo(syn.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(syn.name, docDclInfo(syn.name, sourceLocation=syn.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -145,8 +145,8 @@ top::AGDcl ::= 'ordering' 'attribute' keySyn::Name ',' syn::Name 'with' inh::QNa { top.docForName = keySyn.name++" and "++syn.name++" (ordering pair)"; top.docUnparse = s"`ordering attribute ${keySyn.name}, ${syn.name} with ${inh.name}`"; - top.docDcls := [(keySyn.name, docDclInfo(keySyn.name, sourceLocation=top.location, sourceGrammar=top.grammarName)), - (syn.name, docDclInfo(syn.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(keySyn.name, docDclInfo(keySyn.name, sourceLocation=keySyn.nameLoc, sourceGrammar=top.grammarName)), + (syn.name, docDclInfo(syn.name, sourceLocation=syn.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -155,7 +155,7 @@ top::AGDcl ::= 'monoid' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te::T { top.docForName = a.name; top.docUnparse = s"`monoid attribute ${a.unparse}${tl.unparse} :: ${te.unparse}`"; - top.docDcls := [(a.name, docDclInfo(a.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(a.name, docDclInfo(a.name, sourceLocation=a.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -164,8 +164,8 @@ top::AGDcl ::= 'threaded' 'attribute' inh::Name ',' syn::Name tl::BracketedOptTy { top.docForName = inh.name++" and "++syn.name++" (threaded pair)"; top.docUnparse = s"`threaded attribute ${inh.name}, ${syn.name}${tl.unparse} :: ${te.unparse} direction=${if d.reversed then "right to left" else "left to right"}`"; - top.docDcls := [(inh.name, docDclInfo(inh.name, sourceLocation=top.location, sourceGrammar=top.grammarName)), - (syn.name, docDclInfo(syn.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(inh.name, docDclInfo(inh.name, sourceLocation=inh.nameLoc, sourceGrammar=top.grammarName)), + (syn.name, docDclInfo(syn.name, sourceLocation=syn.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -174,7 +174,7 @@ top::AGDcl ::= 'functor' 'attribute' a::Name ';' { top.docForName = a.name; top.docUnparse = s"`monoid attribute ${a.unparse}`"; - top.docDcls := [(a.name, docDclInfo(a.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(a.name, docDclInfo(a.name, sourceLocation=a.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -184,9 +184,9 @@ top::AGDcl ::= 'functor' 'attribute' a::Name ';' -- { -- top.docForName = inh.name++" and "++synPartial.name++" and "++syn.name++" (unification set)"; -- top.docUnparse = s"`unification attribute ${inh.name}, ${syn.name}, ${syn.name}`"; --- top.docDcls := [(inh.name, docDclInfo(inh.name, sourceLocation=top.location, sourceGrammar=top.grammarName)), --- (syn.name, docDclInfo(syn.name, sourceLocation=top.location, sourceGrammar=top.grammarName)), --- (synPartial.name, docDclInfo(synPartial.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; +-- top.docDcls := [(inh.name, docDclInfo(inh.name, sourceLocation=inh.nameLoc, sourceGrammar=top.grammarName)), +-- (syn.name, docDclInfo(syn.name, sourceLocation=syn.nameLoc, sourceGrammar=top.grammarName)), +-- (synPartial.name, docDclInfo(synPartial.name, sourceLocation=inh.nameLoc, sourceGrammar=top.grammarName))]; -- top.docs := [mkUndocumentedItem(top.docForName, top)]; -- } @@ -204,7 +204,7 @@ top::AGDcl ::= 'type' id::Name tl::BracketedOptTypeExprs 'foreign' '=' trans::St { top.docForName = id.name; top.docUnparse = s"`ffi type ${id.unparse}`"; - top.docDcls := [(id.name, docDclInfo(id.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(id.name, docDclInfo(id.name, sourceLocation=id.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -255,7 +255,7 @@ top::AGDcl ::= 'parser' 'attribute' a::Name '::' te::TypeExpr 'action' acode::Ac { top.docForName = a.name; top.docUnparse = s"`parser attribute ${a.unparse}`"; - top.docDcls := [(a.name, docDclInfo(a.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(a.name, docDclInfo(a.name, sourceLocation=a.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -313,7 +313,7 @@ top::AGDcl ::= 'global' id::Name '::' cl::ConstraintList '=>' t::TypeExpr '=' e: { top.docForName = id.name; top.docUnparse = s"`global ${id.unparse}`"; - top.docDcls := [(id.name, docDclInfo(id.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(id.name, docDclInfo(id.name, sourceLocation=id.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -322,7 +322,7 @@ top::AGDcl ::= 'type' id::Name tl::BracketedOptTypeExprs '=' te::TypeExpr ';' { top.docForName = id.name; top.docUnparse = s"`type ${id.unparse}`"; - top.docDcls := [(id.name, docDclInfo(id.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(id.name, docDclInfo(id.name, sourceLocation=id.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -331,7 +331,7 @@ top::AGDcl ::= 'synthesized' 'attribute' a::Name tl::BracketedOptTypeExprs '::' { top.docForName = a.name; top.docUnparse = s"`synthesized attribute ${a.unparse} (collection)`"; - top.docDcls := [(a.name, docDclInfo(a.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(a.name, docDclInfo(a.name, sourceLocation=a.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } @@ -340,7 +340,7 @@ top::AGDcl ::= 'inherited' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te { top.docForName = a.name; top.docUnparse = s"`synthesized attribute ${a.unparse} (collection)`"; - top.docDcls := [(a.name, docDclInfo(a.name, sourceLocation=top.location, sourceGrammar=top.grammarName))]; + top.docDcls := [(a.name, docDclInfo(a.name, sourceLocation=a.nameLoc, sourceGrammar=top.grammarName))]; top.docs := [mkUndocumentedItem(top.docForName, top)]; } diff --git a/grammars/silver/compiler/extension/doc/core/DataDcl.sv b/grammars/silver/compiler/extension/doc/core/DataDcl.sv index 9330b5d72..35ba0b5fc 100644 --- a/grammars/silver/compiler/extension/doc/core/DataDcl.sv +++ b/grammars/silver/compiler/extension/doc/core/DataDcl.sv @@ -12,7 +12,7 @@ top::AGDcl ::= 'data' id::Name tl::BracketedOptTypeExprs '=' ctors::DataConstruc propagate grammarName, config, docEnv; top.docForName = id.name; top.docUnparse = s"`data nonterminal ${id.unparse}`"; - top.docDcls := (id.name, docDclInfo(id.name, sourceLocation=top.location, sourceGrammar=top.grammarName)) :: ctors.docDcls; + top.docDcls := (id.name, docDclInfo(id.name, sourceLocation=id.nameLoc, sourceGrammar=top.grammarName)) :: ctors.docDcls; top.docs := mkUndocumentedItem(top.docForName, top) :: ctors.docs; ctors.downDocConfig = top.downDocConfig; } @@ -23,7 +23,7 @@ top::AGDcl ::= 'data' id::Name tl::BracketedOptTypeExprs '=' ctors::DataConstruc propagate grammarName, config, docEnv; top.docForName = id.name; top.docUnparse = s"`data nonterminal ${id.unparse}`"; - top.docDcls := (id.name, docDclInfo(id.name, sourceLocation=top.location, sourceGrammar=top.grammarName)) :: ctors.docDcls; + top.docDcls := (id.name, docDclInfo(id.name, sourceLocation=id.nameLoc, sourceGrammar=top.grammarName)) :: ctors.docDcls; top.docs := mkUndocumentedItem(top.docForName, top) :: ctors.docs; ctors.downDocConfig = top.downDocConfig; } diff --git a/grammars/silver/compiler/extension/doc/core/RootSpec.sv b/grammars/silver/compiler/extension/doc/core/RootSpec.sv index fe28883a6..6a2b94e76 100644 --- a/grammars/silver/compiler/extension/doc/core/RootSpec.sv +++ b/grammars/silver/compiler/extension/doc/core/RootSpec.sv @@ -47,12 +47,14 @@ function toSplitFiles { return case g of | consGrammar(this, rest) -> - if getSplit(this.localDocConfig) then toSplitFiles(rest, grammarConf, forIndex, formatFile( - silverToMdFilename(this.location.filename), - getFileTitle(this.localDocConfig, silverToMdFilename(this.location.filename)), + let filename::String = getParsedOriginLocation(this).fromJust.filename + in if getSplit(this.localDocConfig) then toSplitFiles(rest, grammarConf, forIndex, formatFile( + silverToMdFilename(filename), + getFileTitle(this.localDocConfig, silverToMdFilename(filename)), getFileWeight(this.localDocConfig), true, - s"In grammar `${g.grammarName}` file `${this.location.filename}`: "++(if getToc(this.localDocConfig) then "{{< toc >}}" else ""), + s"In grammar `${g.grammarName}` file `${filename}`: "++(if getToc(this.localDocConfig) then "{{< toc >}}" else ""), this.docs) ++ soFar) else toSplitFiles(rest, grammarConf, forIndex ++ this.docs, soFar) + end | nilGrammar() -> let skel::Boolean = (length(soFar) == 0 && length(grammarConf) == 0 && length(forIndex) == 0) in formatFile("_index.md", getGrammarTitle(grammarConf, "["++g.grammarName++"]"++(if skel then " (skel)" else "")), diff --git a/grammars/silver/compiler/extension/doc/core/TypeClassDcls.sv b/grammars/silver/compiler/extension/doc/core/TypeClassDcls.sv index 8a2a92de0..309890ace 100644 --- a/grammars/silver/compiler/extension/doc/core/TypeClassDcls.sv +++ b/grammars/silver/compiler/extension/doc/core/TypeClassDcls.sv @@ -12,7 +12,7 @@ top::AGDcl ::= 'class' cl::ConstraintList '=>' id::QNameType var::TypeExpr '{' b { top.docForName = "class " ++ id.name; top.docUnparse = s"`class ${id.unparse}`"; - top.docDcls := [(id.name, docDclInfo(top.docForName, sourceLocation=top.location, sourceGrammar=top.grammarName))] ++ body.docDcls; + top.docDcls := [(id.name, docDclInfo(top.docForName, sourceLocation=id.nameLoc, sourceGrammar=top.grammarName))] ++ body.docDcls; top.docs := [mkUndocumentedItem(top.docForName, top)] ++ body.docs; body.scopeName = top.docForName; body.downDocConfig = top.downDocConfig; @@ -24,7 +24,7 @@ top::AGDcl ::= 'instance' cl::ConstraintList '=>' id::QNameType ty::TypeExpr '{' { top.docForName = "instance "++id.name++" "++ty.unparse; top.docUnparse = s"`instance ${id.unparse} ${ty.unparse}`"; - top.docDcls := [(id.name, docDclInfo(top.docForName, sourceLocation=top.location, sourceGrammar=top.grammarName))] ++ body.docDcls; + top.docDcls := [(id.name, docDclInfo(top.docForName, sourceLocation=id.nameLoc, sourceGrammar=top.grammarName))] ++ body.docDcls; top.docs := [mkUndocumentedItem(top.docForName, top)] ++ body.docs; body.scopeName = top.docForName; body.downDocConfig = top.downDocConfig; diff --git a/grammars/silver/compiler/extension/doc/core/doclang/DclComment.sv b/grammars/silver/compiler/extension/doc/core/doclang/DclComment.sv index 0159a660c..faabb5e81 100644 --- a/grammars/silver/compiler/extension/doc/core/doclang/DclComment.sv +++ b/grammars/silver/compiler/extension/doc/core/doclang/DclComment.sv @@ -74,7 +74,7 @@ top::DclComment ::= EmptyDclComment_t top.doEmit = false; } -global theEmptyDclComment :: DclComment = emptyDclComment(terminal(EmptyDclComment_t, ""), location=txtLoc("")); +global theEmptyDclComment :: DclComment = emptyDclComment(terminal(EmptyDclComment_t, "")); concrete production normalDclComment top::DclComment ::= InitialIgnore_t blocks::DclCommentBlocks FinalIgnore_t @@ -406,7 +406,7 @@ top::DclCommentPart ::= '@link' '[' id::Id_t ']' end; top.errors <- case res of | [_] -> [] - | _ -> [wrn(childParserLoc(top.offsetLocation, top.location, 0, 0, 0, 0), + | _ -> [wrn(childParserLoc(top.offsetLocation, getParsedOriginLocation(top).fromJust, 0, 0, 0, 0), "Broken doc link to `"++id.lexeme++"`")] end; } diff --git a/grammars/silver/compiler/extension/strategyattr/Strategy.sv b/grammars/silver/compiler/extension/strategyattr/Strategy.sv index b2a31c468..3bdd02f46 100644 --- a/grammars/silver/compiler/extension/strategyattr/Strategy.sv +++ b/grammars/silver/compiler/extension/strategyattr/Strategy.sv @@ -35,7 +35,7 @@ top::AGDcl ::= isTotal::Boolean a::Name recVarNameEnv::[Pair] rec local fwrd::AGDcl = foldr( - appendAGDcl(_, _), + appendAGDcl, defsAGDcl( [attrDef( defaultEnvItem( @@ -105,7 +105,7 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: appendAGDcl( @atOccursDcl, foldr1( - appendAGDcl(_, _), + appendAGDcl, map( \ n::String -> attributionDcl( diff --git a/grammars/silver/compiler/extension/templating/StringTemplating.sv b/grammars/silver/compiler/extension/templating/StringTemplating.sv index e9fdc5c86..ab3382bfa 100644 --- a/grammars/silver/compiler/extension/templating/StringTemplating.sv +++ b/grammars/silver/compiler/extension/templating/StringTemplating.sv @@ -65,14 +65,14 @@ concrete production pptemplateExpr top::Expr ::= PPTemplate_kwd t::TemplateString layout {} { - forwards to translate(top.location, reflect(t.ppTemplate)); + forwards to translate(reflect(t.ppTemplate)); } concrete production singleLinepptemplateExpr top::Expr ::= SLPPTemplate_kwd t::SingleLineTemplateString layout {} { - forwards to translate(top.location, reflect(t.ppTemplate)); + forwards to translate(reflect(t.ppTemplate)); } -- Antiquote production used in translating nonwater Exprs that should get directly embedded in the result. diff --git a/grammars/silver/compiler/extension/treegen/TestFor.sv b/grammars/silver/compiler/extension/treegen/TestFor.sv index 910ce5640..e33c4b613 100644 --- a/grammars/silver/compiler/extension/treegen/TestFor.sv +++ b/grammars/silver/compiler/extension/treegen/TestFor.sv @@ -53,7 +53,7 @@ top::AGDcl ::= 'testFor' testSuite::Name ':' n::Name '::' id::QName ',' e::Expr -- emit function taking a ID tree GENERATING FUNCTION and check e on it forwards to foldr( - appendAGDcl(_, _), + appendAGDcl, emptyAGDcl(), fundcl :: map( @@ -88,7 +88,7 @@ AGDcl ::= d::ValueDclInfo testfunname::String l::Location testSuite::Name -- emit test case calling 'repeatTestTimes(testArbitraryProduction_ID, 100)' return foldr( - appendAGDcl(_, _), + appendAGDcl, emptyAGDcl(), [ functionDcl( diff --git a/grammars/silver/compiler/metatranslation/Translation.sv b/grammars/silver/compiler/metatranslation/Translation.sv index c3f10bb6c..153cfe654 100644 --- a/grammars/silver/compiler/metatranslation/Translation.sv +++ b/grammars/silver/compiler/metatranslation/Translation.sv @@ -11,16 +11,16 @@ imports silver:compiler:modification:list; imports silver:compiler:extension:patternmatching; function translate -Expr ::= loc::Location ast::AST +Expr ::= ast::AST { - ast.givenLocation = loc; + ast.givenLocation = getParsedOriginLocationOrFallback(ambientOrigin()); return ast.translation; } function translatePattern -Pattern ::= loc::Location ast::AST +Pattern ::= ast::AST { - ast.givenLocation = loc; + ast.givenLocation = getParsedOriginLocationOrFallback(ambientOrigin()); return ast.patternTranslation; } @@ -104,9 +104,7 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs -- The next item in the list is the nil production, no need to insert an append. | nonterminalAST(p, _, _) when p == trans.3 -> antiquoteExpr -- There are more items that need to be appended to the antiquoted expression. - | _ -> - mkStrFunctionInvocation( - givenLocation, trans.4, [antiquoteExpr, antiquote.3.translation]) + | _ -> mkStrFunctionInvocation(trans.4, [antiquoteExpr, antiquote.3.translation]) end; }; antiquoteTranslation <- @@ -126,7 +124,6 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs top.translation = fromMaybe( mkFullFunctionInvocation( - givenLocation, baseExpr(qName(prodName)), children.translation, filter(\ a::(String, Expr) -> a.1 != "location", annotations.translation)), @@ -171,12 +168,7 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs -- Note that we intentionally ignore annotations here top.patternTranslation = fromMaybe( - prodAppPattern( - qName(prodName), - '(', - children.patternTranslation, - ')', - location=givenLocation), + prodAppPattern(qName(prodName), '(', children.patternTranslation, ')'), patternAntiquoteTranslation); children.givenLocation = givenLocation; @@ -192,13 +184,9 @@ top::AST ::= terminalName::String lexeme::String location::Location top.translation = terminalConstructor( 'terminal', '(', - nominalTypeExpr( - makeQNameType(terminalName, top.givenLocation), - location=top.givenLocation), + nominalTypeExpr(makeQNameType(terminalName, top.givenLocation)), ',', - stringConst( - terminal(String_t, s"\"${escapeString(lexeme)}\"", top.givenLocation), - location=top.givenLocation), + stringConst(terminal(String_t, s"\"${escapeString(lexeme)}\"", top.givenLocation)), ',', locationAST.translation, ')'); @@ -218,8 +206,7 @@ top::AST ::= vals::ASTs exprsCons(_, ',', _), exprsEmpty(), vals.translation), - ']', - location=top.givenLocation); + ']'); top.patternTranslation = listPattern('[', vals.patternTranslation, ']'); } @@ -228,13 +215,9 @@ aspect production stringAST top::AST ::= s::String { top.translation = - stringConst( - terminal(String_t, s"\"${escapeString(s)}\"", top.givenLocation), - location=top.givenLocation); + stringConst(terminal(String_t, s"\"${escapeString(s)}\"", top.givenLocation)); top.patternTranslation = - strPattern( - terminal(String_t, s"\"${escapeString(s)}\"", top.givenLocation), - location=top.givenLocation); + strPattern(terminal(String_t, s"\"${escapeString(s)}\"", top.givenLocation)); } aspect production integerAST From fed400bc7d0e7aa5bbb25fccc54f2808c470db9e Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 28 Sep 2023 14:31:20 -0500 Subject: [PATCH 041/283] More updating to remote locations --- .../silver/compiler/definition/core/Expr.sv | 11 +- .../compiler/extension/auto_ast/AutoAst.sv | 7 +- .../extension/doc/core/CommentItem.sv | 19 +- .../compiler/extension/doc/core/DataDcl.sv | 6 +- .../extension/doc/core/DocumentedAGDcl.sv | 4 +- .../compiler/extension/doc/core/Root.sv | 2 +- .../extension/doc/core/TypeClassDcls.sv | 18 +- .../implicit_monads/AttributeDefs.sv | 8 +- .../extension/implicit_monads/Case.sv | 64 +-- .../extension/implicit_monads/DclInfo.sv | 4 +- .../extension/implicit_monads/Expr.sv | 366 +++++++++--------- .../compiler/extension/implicit_monads/Let.sv | 8 +- .../implicit_monads/PrimitiveMatch.sv | 43 +- .../implicit_monads/ProductionBody.sv | 30 +- .../extension/implicit_monads/Util.sv | 43 +- .../extension/patternmatching/Case.sv | 132 ++++--- .../compiler/extension/rewriting/Expr.sv | 54 +-- .../compiler/extension/rewriting/Rewriting.sv | 22 +- .../extension/silverconstruction/Syntax.sv | 12 +- .../silverconstruction/Translation.sv | 2 - .../extension/strategyattr/ConcreteSyntax.sv | 4 +- .../extension/strategyattr/DclInfo.sv | 2 +- .../extension/strategyattr/Strategy.sv | 4 +- .../extension/strategyattr/StrategyExpr.sv | 17 +- .../strategyattr/construction/Construction.sv | 2 +- .../strategyattr/convenience/Convenience.sv | 4 +- .../extension/templating/StringTemplating.sv | 14 +- .../extension/testing/EqualityTest.sv | 10 +- .../compiler/extension/testing/Helper.sv | 6 +- .../extension/testing/MainTestSuite.sv | 20 +- .../compiler/extension/treegen/Arbitrary.sv | 38 +- .../primitivepattern/VarBinders.sv | 2 +- 32 files changed, 475 insertions(+), 503 deletions(-) diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index 10cd2b520..cb15bb5e8 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -914,15 +914,10 @@ top::Expr ::= 'terminal' '(' t::TypeExpr ',' es::Expr ',' el::Expr ')' concrete production terminalFunction top::Expr ::= 'terminal' '(' t::TypeExpr ',' e::Expr ')' { - -- So, *maybe* this is deprecated? But let's not complain for now, because - -- it's too widely used. + local locExpr :: Expr = + Silver_Expr { getParsedOriginLocationOrFallback(ambientOrigin()) }; - --top.errors <- [wrnFromOrigin(t, "terminal(type,lexeme) is deprecated. Use terminal(type,lexeme,location) instead.")]; - - local bogus :: Expr = - mkStrFunctionInvocation("silver:core:bogusLoc", []); - - forwards to terminalConstructor($1, $2, t, $4, e, ',', bogus, $6); + forwards to terminalConstructor($1, $2, t, $4, e, ',', locExpr, $6); } -- These sorta seem obsolete, but there are some important differences from AppExprs. diff --git a/grammars/silver/compiler/extension/auto_ast/AutoAst.sv b/grammars/silver/compiler/extension/auto_ast/AutoAst.sv index d4a8c1520..6e93fd2d7 100644 --- a/grammars/silver/compiler/extension/auto_ast/AutoAst.sv +++ b/grammars/silver/compiler/extension/auto_ast/AutoAst.sv @@ -61,7 +61,7 @@ top::ProductionStmt ::= 'abstract' v::QName ';' '=', mkFullFunctionInvocation( baseExpr(v), - map(accessAst(_, top.location), elems), + map(accessAst, elems), if hasLoc then [("location", access( @@ -91,14 +91,13 @@ Type ::= ns::NamedSignatureElement env::Env } function accessAst -Expr ::= ns::NamedSignatureElement l::Location +Expr ::= ns::NamedSignatureElement { return access( baseExpr(qName(ns.elementName)), '.', - qNameAttrOccur(qName("silver:langutil:ast")), - location=l); + qNameAttrOccur(qName("silver:langutil:ast"))); } diff --git a/grammars/silver/compiler/extension/doc/core/CommentItem.sv b/grammars/silver/compiler/extension/doc/core/CommentItem.sv index bcecc6b61..4921a3137 100644 --- a/grammars/silver/compiler/extension/doc/core/CommentItem.sv +++ b/grammars/silver/compiler/extension/doc/core/CommentItem.sv @@ -1,11 +1,10 @@ grammar silver:compiler:extension:doc:core; synthesized attribute body :: String; -synthesized attribute loc :: Location; synthesized attribute stub :: Boolean; synthesized attribute docNames :: [String]; synthesized attribute undocNames :: [String]; -tracked nonterminal CommentItem with body, loc, doEmit, stub, docNames, undocNames; +tracked nonterminal CommentItem with body, doEmit, stub, docNames, undocNames; {- Used by other productions to construct @@ -22,19 +21,19 @@ String ::= n::String } function makeStub -String ::= forName::String docUnparse::String grammarName::String loc::Location +String ::= forName::String docUnparse::String grammarName::String { + local loc::Location = getParsedOriginLocation(ambientOrigin()).fromJust; return s"""## ${docUnparse} {#${sanitizeAnchor(forName)}} Contained in grammar `[${grammarName}]`. Defined at [${substitute(":", "/", grammarName)}/${loc.filename} line ${toString(loc.line)}](https://github.com/melt-umn/silver/blob/develop/grammars/${substitute(":", "/", grammarName)}/${loc.filename}#L${toString(loc.line)})."""; } abstract production dclCommentItem -top::CommentItem ::= forName::String docUnparse::String grammarName::String location::Location body::Decorated DclComment +top::CommentItem ::= forName::String docUnparse::String grammarName::String body::Decorated DclComment { top.body = body.indentBy ++ substitute("\n", "\n"++body.indentBy, - makeStub(forName, docUnparse, grammarName, location) ++ "\n\n" ++ body.body); - top.loc = location; + makeStub(forName, docUnparse, grammarName) ++ "\n\n" ++ body.body); top.doEmit = body.doEmit; top.stub = false; top.docNames = [forName]; @@ -45,7 +44,6 @@ abstract production standaloneDclCommentItem top::CommentItem ::= body::Decorated DclComment { top.body = substitute("\n", "\n"++body.indentBy, body.body); - top.loc = body.location; top.doEmit = body.doEmit; top.stub = false; top.docNames = []; @@ -53,10 +51,9 @@ top::CommentItem ::= body::Decorated DclComment } abstract production undocumentedItem -top::CommentItem ::= forName::String docUnparse::String grammarName::String location::Location +top::CommentItem ::= forName::String docUnparse::String grammarName::String { - top.body = makeStub(forName, docUnparse, grammarName, location) ++ "\n\n (Undocumented.)"; - top.loc = location; + top.body = makeStub(forName, docUnparse, grammarName) ++ "\n\n (Undocumented.)"; top.doEmit = true; top.stub = true; top.docNames = []; @@ -66,5 +63,5 @@ top::CommentItem ::= forName::String docUnparse::String grammarName::String loca function mkUndocumentedItem CommentItem ::= f::String t::Decorated AGDcl { - return undocumentedItem(f, t.docUnparse, t.grammarName, t.location); + return undocumentedItem(f, t.docUnparse, t.grammarName); } diff --git a/grammars/silver/compiler/extension/doc/core/DataDcl.sv b/grammars/silver/compiler/extension/doc/core/DataDcl.sv index 35ba0b5fc..9fd79e500 100644 --- a/grammars/silver/compiler/extension/doc/core/DataDcl.sv +++ b/grammars/silver/compiler/extension/doc/core/DataDcl.sv @@ -64,7 +64,9 @@ top::DataConstructor ::= comment::DocComment_t item::DataConstructor local isDoubleComment::Boolean = length(realDclDocs) != 0; top.docs := if isDoubleComment then [standaloneDclCommentItem(parsed)] ++ realDclDocs - else [dclCommentItem(top.docForName, forward.docUnparse, forward.grammarName, item.location, parsed)]; + else [attachNote logicalLocationFromOrigin(item) on + dclCommentItem(top.docForName, forward.docUnparse, forward.grammarName, parsed) + end]; top.docErrors <- if isDoubleComment then [wrnFromOrigin(parsed, "Doc comment not immediately preceding constructor, so association is ambiguous. Treating as standalone comment. Mark with @@{- instead of @{- to silence this warning.")] @@ -79,6 +81,6 @@ top::DataConstructor ::= id::Name rhs::ProductionRHS top.docForName = id.name; top.docUnparse = "`abstract production " ++ id.name ++ "`   (`" ++ top.ntName ++ top.ntTypeArgs.unparse ++ " ::= " ++ rhs.unparse ++ "`)"; top.docDcls := []; - top.docs := [undocumentedItem(top.docForName, top.docUnparse, top.grammarName, top.location)]; + top.docs := [undocumentedItem(top.docForName, top.docUnparse, top.grammarName)]; top.upDocConfig := []; } \ No newline at end of file diff --git a/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv b/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv index e72419405..e6bb9a099 100644 --- a/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv +++ b/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv @@ -77,7 +77,9 @@ top::AGDcl ::= comment::DocComment_t dcl::AGDcl local isDoubleComment::Boolean = case forward of documentedAGDcl(_, _) -> true | _ -> false end; top.docs := if isDoubleComment then [standaloneDclCommentItem(parsed)] ++ forward.docs - else [dclCommentItem(forward.docForName, forward.docUnparse, forward.grammarName, dcl.location, parsed)] + else [attachNote logicalLocationFromOrigin(dcl) on + dclCommentItem(forward.docForName, forward.docUnparse, forward.grammarName, parsed) + end] ++ if length(forward.docs) > 1 then tail(forward.docs) else []; top.errors <- if isDoubleComment then [wrnFromOrigin(parsed, "Doc comment not immediately preceding AGDcl, so association is ambiguous. Treating as standalone comment. Mark with @@{- instead of @{- to silence this warning.")] diff --git a/grammars/silver/compiler/extension/doc/core/Root.sv b/grammars/silver/compiler/extension/doc/core/Root.sv index d72828293..dd7fc105b 100644 --- a/grammars/silver/compiler/extension/doc/core/Root.sv +++ b/grammars/silver/compiler/extension/doc/core/Root.sv @@ -124,7 +124,7 @@ top::Grammar ::= c1::Root c2::Grammar top.docDcls := c1.docDcls ++ c2.docDcls; top.undocumentedNamed = c1.undocumentedNamed ++ c2.undocumentedNamed; top.documentedNamed = c1.documentedNamed ++ c2.documentedNamed; - top.allFileDocErrors = (c1.location.filename, c1.docErrors) :: c2.allFileDocErrors; + top.allFileDocErrors = (getParsedOriginLocation(c1).fromJust.filename, c1.docErrors) :: c2.allFileDocErrors; } -- consGrammar(FILE1, consGrammar(FILE2, nilGrammar())) diff --git a/grammars/silver/compiler/extension/doc/core/TypeClassDcls.sv b/grammars/silver/compiler/extension/doc/core/TypeClassDcls.sv index 309890ace..d6f3add91 100644 --- a/grammars/silver/compiler/extension/doc/core/TypeClassDcls.sv +++ b/grammars/silver/compiler/extension/doc/core/TypeClassDcls.sv @@ -55,7 +55,7 @@ top::ClassBodyItem ::= top.docForName = ""; top.upDocConfig := []; top.docDcls := []; - top.docs := [undocumentedItem(top.scopeName ++ "." ++ top.docForName, "`" ++ top.scopeName ++ "`." ++ top.docUnparse, top.grammarName, top.location)]; + top.docs := [undocumentedItem(top.scopeName ++ "." ++ top.docForName, "`" ++ top.scopeName ++ "`." ++ top.docUnparse, top.grammarName)]; top.docUnparse = ""; } @@ -78,7 +78,9 @@ top::ClassBodyItem ::= comment::DocComment_t item::ClassBodyItem local isDoubleComment::Boolean = length(realDclDocs) != 0; top.docs := if isDoubleComment then [standaloneDclCommentItem(parsed)] ++ realDclDocs - else [dclCommentItem(top.scopeName ++ "." ++ forward.docForName, forward.docUnparse, forward.grammarName, item.location, parsed)]; + else [attachNote logicalLocationFromOrigin(item) on + dclCommentItem(top.scopeName ++ "." ++ forward.docForName, forward.docUnparse, forward.grammarName, parsed) + end]; top.docErrors <- if isDoubleComment then [wrnFromOrigin(parsed, "Doc comment not immediately preceding ClassBodyItem, so association is ambiguous. Treating as standalone comment. Mark with @@{- instead of @{- to silence this warning.")] @@ -92,7 +94,7 @@ top::ClassBodyItem ::= id::Name '::' cl::ConstraintList '=>' ty::TypeExpr ';' { top.docForName = id.name; top.docUnparse = "`" ++ id.unparse ++ " :: " ++ cl.unparse ++ " => " ++ ty.unparse ++ "`"; - top.docs := [undocumentedItem(top.scopeName ++ "." ++ top.docForName, "`" ++ top.scopeName ++ "`." ++ top.docUnparse, top.grammarName, top.location)]; + top.docs := [undocumentedItem(top.scopeName ++ "." ++ top.docForName, "`" ++ top.scopeName ++ "`." ++ top.docUnparse, top.grammarName)]; } aspect production defaultConstraintClassBodyItem @@ -100,7 +102,7 @@ top::ClassBodyItem ::= id::Name '::' cl::ConstraintList '=>' ty::TypeExpr '=' e: { top.docForName = id.name; top.docUnparse = "`" ++ id.unparse ++ " :: " ++ cl.unparse ++ " => " ++ ty.unparse ++ "` (has default)"; - top.docs := [undocumentedItem(top.scopeName ++ "." ++ top.docForName, "`" ++ top.scopeName ++ "`." ++ top.docUnparse, top.grammarName, top.location)]; + top.docs := [undocumentedItem(top.scopeName ++ "." ++ top.docForName, "`" ++ top.scopeName ++ "`." ++ top.docUnparse, top.grammarName)]; } @@ -132,7 +134,7 @@ top::InstanceBodyItem ::= top.docForName = ""; top.upDocConfig := []; top.docDcls := []; - top.docs := [undocumentedItem(top.scopeName ++ "." ++ top.docForName, "`" ++ top.scopeName ++ "`." ++ top.docUnparse, top.grammarName, top.location)]; + top.docs := [undocumentedItem(top.scopeName ++ "." ++ top.docForName, "`" ++ top.scopeName ++ "`." ++ top.docUnparse, top.grammarName)]; top.docUnparse = ""; } @@ -155,7 +157,9 @@ top::InstanceBodyItem ::= comment::DocComment_t item::InstanceBodyItem local isDoubleComment::Boolean = length(realDclDocs) != 0; top.docs := if isDoubleComment then [standaloneDclCommentItem(parsed)] ++ realDclDocs - else [dclCommentItem(top.scopeName ++ "." ++ forward.docForName, forward.docUnparse, forward.grammarName, item.location, parsed)]; + else [attachNote logicalLocationFromOrigin(item) on + dclCommentItem(top.scopeName ++ "." ++ forward.docForName, forward.docUnparse, forward.grammarName, parsed) + end]; top.docErrors <- if isDoubleComment then [wrnFromOrigin(parsed, "Doc comment not immediately preceding InstanceBodyItem, so association is ambiguous. Treating as standalone comment. Mark with @@{- instead of @{- to silence this warning.")] @@ -169,5 +173,5 @@ top::InstanceBodyItem ::= id::QName '=' e::Expr ';' { top.docForName = id.name; top.docUnparse = "`" ++ id.unparse ++ "`"; - top.docs := [undocumentedItem(top.scopeName ++ "." ++ top.docForName, "`" ++ top.scopeName ++ "`." ++ top.docUnparse, top.grammarName, top.location)]; + top.docs := [undocumentedItem(top.scopeName ++ "." ++ top.docForName, "`" ++ top.scopeName ++ "`." ++ top.docUnparse, top.grammarName)]; } diff --git a/grammars/silver/compiler/extension/implicit_monads/AttributeDefs.sv b/grammars/silver/compiler/extension/implicit_monads/AttributeDefs.sv index 9c3695154..9ecd88bdf 100644 --- a/grammars/silver/compiler/extension/implicit_monads/AttributeDefs.sv +++ b/grammars/silver/compiler/extension/implicit_monads/AttributeDefs.sv @@ -25,7 +25,7 @@ top::AGDcl ::= 'restricted' 'inherited' 'attribute' a::Name tl::BracketedOptType production attribute fName :: String; fName = top.grammarName ++ ":" ++ a.name; - local fwd::AGDcl = defsAGDcl([restrictedInhDef(top.grammarName, a.location, fName, tl.freeVariables, te.typerep)]); + local fwd::AGDcl = defsAGDcl([restrictedInhDef(top.grammarName, a.nameLoc, fName, tl.freeVariables, te.typerep)]); forwards to fwd; } @@ -55,7 +55,7 @@ top::AGDcl ::= 'restricted' 'synthesized' 'attribute' a::Name tl::BracketedOptTy production attribute fName :: String; fName = top.grammarName ++ ":" ++ a.name; - local fwd::AGDcl = defsAGDcl([restrictedSynDef(top.grammarName, a.location, fName, tl.freeVariables, te.typerep)]); + local fwd::AGDcl = defsAGDcl([restrictedSynDef(top.grammarName, a.nameLoc, fName, tl.freeVariables, te.typerep)]); forwards to fwd; } @@ -89,7 +89,7 @@ top::AGDcl ::= 'implicit' 'inherited' 'attribute' a::Name tl::BracketedOptTypeEx production attribute fName :: String; fName = top.grammarName ++ ":" ++ a.name; - local fwd::AGDcl = defsAGDcl([implicitInhDef(top.grammarName, a.location, fName, tl.freeVariables, te.typerep)]); + local fwd::AGDcl = defsAGDcl([implicitInhDef(top.grammarName, a.nameLoc, fName, tl.freeVariables, te.typerep)]); forwards to fwd; } @@ -121,7 +121,7 @@ top::AGDcl ::= 'implicit' 'synthesized' 'attribute' a::Name tl::BracketedOptType production attribute fName :: String; fName = top.grammarName ++ ":" ++ a.name; - local fwd::AGDcl = defsAGDcl([implicitSynDef(top.grammarName, a.location, fName, tl.freeVariables, te.typerep)]); + local fwd::AGDcl = defsAGDcl([implicitSynDef(top.grammarName, a.nameLoc, fName, tl.freeVariables, te.typerep)]); forwards to fwd; } diff --git a/grammars/silver/compiler/extension/implicit_monads/Case.sv b/grammars/silver/compiler/extension/implicit_monads/Case.sv index 50ad6dd40..33661cc13 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Case.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Case.sv @@ -35,10 +35,11 @@ top::Expr ::= 'case' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' false, ml.matchRuleList); - local basicFailure::Expr = mkStrFunctionInvocation(top.location, "silver:core:error", + local loc::Location = getParsedOriginLocationOrFallback(ambientOrigin()); + local basicFailure::Expr = mkStrFunctionInvocation("silver:core:error", [stringConst(terminal(String_t, "\"Error: pattern match failed at " ++ top.grammarName ++ - " " ++ top.location.unparse ++ "\\n\""))]); + " " ++ loc.unparse ++ "\\n\""))]); {- Inserting fails breaks down if the current monad's fail is expecting something other than a string, integer, float, or list, @@ -47,7 +48,7 @@ top::Expr ::= 'case' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' -} local failure::Expr = if isMonadFail(top.expectedMonad, top.env) - then monadFail(top.location) + then monadFail() else basicFailure; {- This sets up the actual output type. If there's a monad, the @@ -65,7 +66,7 @@ top::Expr ::= 'case' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' --read the comment on the function below if you want to know what it is local attribute monadStuff::([(Type, Expr, String)], [Expr]); monadStuff = monadicMatchTypesNames(redeces.monadDecExprs, ml.patternTypeList, [], top.env, - ml.mUpSubst, top.expectedMonad, top.location, 1); + ml.mUpSubst, top.expectedMonad, 1); local attribute redeces::Exprs = es; redeces.mDownSubst = ml.mUpSubst; redeces.downSubst = ml.mUpSubst; @@ -88,7 +89,7 @@ top::Expr ::= 'case' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' -} local monadLocal::Expr = foldr(\ p::(Type, Expr, String) rest::Expr -> - makeLet(top.location, p.3, monadInnerType(p.1, top.location), p.2, rest), + makeLet(p.3, monadInnerType(p.1), p.2, rest), caseExpr(monadStuff.snd, ml.matchRuleList, !isMonadFail(top.expectedMonad, top.env), failure, outty), @@ -157,11 +158,11 @@ function monadicMatchTypesNames ([(Type, (Expr, String))], [Expr]) ::= elst::[Decorated Expr with MonadInhs] tylst::[Type] names::[String] env::Env sub::Substitution em::Type - loc::Location index::Integer + index::Integer { local attribute subcall::([(Type, Expr, String)], [Expr]); subcall = case elst, tylst of - | _::etl, _::ttl -> monadicMatchTypesNames(etl, ttl, ntail, env, sub, em, loc, index + 1) + | _::etl, _::ttl -> monadicMatchTypesNames(etl, ttl, ntail, env, sub, em, index + 1) | [], [] -> error("Should not access subcall in monadicMatchTypesNames with empty lists") | _, _ -> error("Both lists in monadicMatchTypesNames must be the same length") end; @@ -190,7 +191,7 @@ function monadicMatchTypesNames fails.-} aspect production caseExpr top::Expr ::= es::[Expr] ml::[AbstractMatchRule] complete::Boolean failExpr::Expr retType::Type { - forward monadLocal = monadCompileCaseExpr(es, ml, failExpr, retType, top.location, top.env); + forward monadLocal = monadCompileCaseExpr(es, ml, failExpr, retType, top.env); top.monadRewritten = monadLocal.monadRewritten; @@ -217,14 +218,14 @@ top::Expr ::= es::[Expr] ml::[AbstractMatchRule] complete::Boolean failExpr::Exp copying the function format from the patternmatching extension. -} function monadCompileCaseExpr -Expr ::= es::[Expr] ml::[AbstractMatchRule] failExpr::Expr retType::Type loc::Location env::Env +Expr ::= es::[Expr] ml::[AbstractMatchRule] failExpr::Expr retType::Type env::Env { --Split rules into segments of non-forwarding constructors, all same -- forwarding constructor, and variables based on first pattern local groups::[[AbstractMatchRule]] = splitPatternGroups(ml, env); local compiledGroups::Expr = - monadCompilePatternGroups(es, groups, failExpr, retType, loc, env); + monadCompilePatternGroups(es, groups, failExpr, retType, env); --Check if there is any match rule with empty patterns local anyEmptyRules::Boolean = @@ -270,11 +271,11 @@ Expr ::= es::[Expr] ml::[AbstractMatchRule] failExpr::Expr retType::Type loc::Lo -- but without using lets which would end up being problematic in our implicit use function monadCompilePatternGroups Expr ::= matchEs::[Expr] ruleGroups::[[AbstractMatchRule]] finalFail::Expr - retType::Type loc::Location env::Env + retType::Type env::Env { local compileRest::Expr = monadCompilePatternGroups(matchEs, tail(ruleGroups), finalFail, - retType, loc, env); + retType, env); local firstGroup::[AbstractMatchRule] = case ruleGroups of @@ -311,7 +312,7 @@ Expr ::= matchEs::[Expr] ruleGroups::[[AbstractMatchRule]] finalFail::Expr map(bindHeadPattern(firstMatchExpr, freshType(), _), firstGroup); local currentVarCase::Expr = monadCompileCaseExpr(tail(matchEs), boundVarRules, - compileRest, retType, loc, env); + compileRest, retType, env); return case ruleGroups of @@ -336,7 +337,7 @@ PrimPattern ::= currExpr::Expr restExprs::[Expr] failCase::Expr retType::Type monadCompileCaseExpr( map(exprFromName, names) ++ annoAccesses ++ restExprs, map(\ mr::AbstractMatchRule -> mr.expandHeadPattern(annos), mrs), - failCase, retType, head(mrs).location, env); + failCase, retType, env); local annos :: [String] = nub(map(fst, flatMap((.patternNamedSubPatternList), map((.headPattern), mrs)))); @@ -344,12 +345,12 @@ PrimPattern ::= currExpr::Expr restExprs::[Expr] failCase::Expr retType::Type map(\ n::String -> access(currExpr, '.', qNameAttrOccur(qName(n))), annos); -- Maybe this one is more reasonable? We need to test examples and see what happens... - local l :: Location = head(mrs).headPattern.location; + local l :: Location = getParsedOriginLocationOrFallback(head(mrs).headPattern); return case head(mrs).headPattern of | prodAppPattern_named(qn,_,_,_,_,_) -> - prodPattern(qn, '(', convStringsToVarBinders(names, l), ')', terminal(Arrow_kwd, "->", l), subcase) + prodPattern(qn, '(', convStringsToVarBinders(names), ')', terminal(Arrow_kwd, "->", l), subcase) | intPattern(it) -> integerPattern(it, terminal(Arrow_kwd, "->", l), subcase) | fltPattern(it) -> floatPattern(it, terminal(Arrow_kwd, "->", l), subcase) | strPattern(it) -> stringPattern(it, terminal(Arrow_kwd, "->", l), subcase) @@ -377,8 +378,8 @@ top::Expr ::= 'case_any' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' top.grammarName, top.compiledGrammars, top.config, top.flowEnv, top.expectedMonad, false, top.originRules); - local mplus::Expr = monadPlus(top.location); - local mzero::Expr = monadZero(top.location); + local mplus::Expr = monadPlus(); + local mzero::Expr = monadZero(); local isMonadPlus_instance::Boolean = isMonadPlus(top.expectedMonad, top.env); local notMonadPlus::String = @@ -399,7 +400,7 @@ top::Expr ::= 'case_any' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' --Rewrite the case expressions, wrapped in lambdas to provide the names local rewrittenCaseExprs::[Expr] = map(\ x::Expr -> - decorate buildMultiLambda(params, x, top.location) with + decorate buildMultiLambda(params, x) with {mDownSubst = top.mDownSubst; frame = top.frame; grammarName = top.grammarName; @@ -417,7 +418,7 @@ top::Expr ::= 'case_any' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' caseExprs); --Take the rewritten functions and apply them to the names to get expressions of a monad type local appliedCaseExprs::[Expr] = - map(\ x::Expr -> buildApplication(x, nameExprs, top.location), + map(\ x::Expr -> buildApplication(x, nameExprs), rewrittenCaseExprs); --In some cases, they might not return monadic types, so we need to check and add return local typecheckedCaseExprs::[Expr] = @@ -431,7 +432,7 @@ top::Expr ::= 'case_any' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' in if isMonad(ty, top.env) && monadsMatch(ty, top.expectedMonad, top.mDownSubst).fst then x - else buildApplication(monadReturn(top.location), [x], top.location) + else buildApplication(monadReturn(), [x]) end, appliedCaseExprs); --Mplus the rewritten-and-applied case expressions together @@ -442,7 +443,7 @@ top::Expr ::= 'case_any' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' head(typecheckedCaseExprs), tail(typecheckedCaseExprs)); --Use bind and lambdas to change the names of everything being matched on to only evaluate it once local applied::Expr = - mcaseBindsApps(es.rawExprs, newNames, top.location, mplused, + mcaseBindsApps(es.rawExprs, newNames, mplused, top.env, ml.mUpSubst, top.frame, top.grammarName, top.compiledGrammars, top.config, top.flowEnv, top.expectedMonad, top.isRoot, top.originRules); @@ -463,13 +464,13 @@ top::Expr ::= 'case_any' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' a lambda to change the name. -} function mcaseBindsApps -Expr ::= exprs::[Expr] names::[String] loc::Location base::Expr +Expr ::= exprs::[Expr] names::[String] base::Expr env::Env sub::Substitution f::BlockContext gn::String cg::EnvTree c::Decorated CmdArgs fe::FlowEnv em::Type iR::Boolean oR::[Decorated Expr] { local subcall::Expr = - mcaseBindsApps(tail(exprs), tail(names), loc, base, + mcaseBindsApps(tail(exprs), tail(names), base, env, sub, f, gn, cg, c, fe, em, iR, oR); return if null(exprs) @@ -483,14 +484,13 @@ Expr ::= exprs::[Expr] names::[String] loc::Location base::Expr in if isMonad(ety, env) && fst(monadsMatch(ety, em, sub)) then buildApplication( - monadBind(loc), - [if ety.isDecorated - then mkStrFunctionInvocation(loc, "silver:core:new", [head(exprs)]) - else head(exprs), - buildLambda(head(names), monadInnerType(ety, loc), subcall, loc)], - loc) - else buildApplication(buildLambda(head(names), dropDecorated(ety), subcall, loc), - [head(exprs)], loc) + monadBind(), + [if ety.isDecorated + then mkStrFunctionInvocation("silver:core:new", [head(exprs)]) + else head(exprs), + buildLambda(head(names), monadInnerType(ety), subcall)]) + else buildApplication(buildLambda(head(names), dropDecorated(ety), subcall), + [head(exprs)]) end; } diff --git a/grammars/silver/compiler/extension/implicit_monads/DclInfo.sv b/grammars/silver/compiler/extension/implicit_monads/DclInfo.sv index a773d21e9..5fe9c5c53 100644 --- a/grammars/silver/compiler/extension/implicit_monads/DclInfo.sv +++ b/grammars/silver/compiler/extension/implicit_monads/DclInfo.sv @@ -8,7 +8,7 @@ top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type --copied from synDcl top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); top.dataAccessHandler = synDataAccessHandler; top.attributionDispatcher = defaultAttributionDcl; @@ -52,7 +52,7 @@ top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type --copied from synDcl top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); top.dataAccessHandler = synDataAccessHandler; top.attributionDispatcher = defaultAttributionDcl; diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index 51f7ef4fa..e1e25a46b 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -20,7 +20,7 @@ type MonadInhs = { --list of the attributes accessed in an explicit expression not allowed there --this is turned into a list of appropriate error messages at the equation -monoid attribute notExplicitAttributes::[Pair]; +monoid attribute notExplicitAttributes::[Decorated QNameAttrOccur]; attribute notExplicitAttributes occurs on Expr, AppExprs, AnnoAppExprs, MRuleList, Exprs, MatchRule, AbstractMatchRule, AssignExpr; propagate notExplicitAttributes on Expr, AppExprs, AnnoAppExprs, MRuleList, Exprs, AssignExpr excluding forwardAccess; @@ -221,7 +221,7 @@ top::Expr ::= e::Expr '(' es::AppExprs ',' anns::AnnoAppExprs ')' local ety :: Type = if isMonad(substTy, top.env) && monadsMatch(top.expectedMonad, substTy, top.mDownSubst).fst - then monadInnerType(substTy, top.location) + then monadInnerType(substTy) else substTy; local areMonadicArgs::Boolean = !null(nes.monadTypesLocations) || any(map(\ p::(Type, QName, Boolean) -> p.3, nanns.monadAnns)); @@ -261,7 +261,7 @@ top::Expr ::= e::Expr '(' es::AppExprs ',' anns::AnnoAppExprs ')' -} local lambda_fun::Expr = buildMonadApplicationLambda(nes.realTypes, nes.monadTypesLocations, - nanns.monadAnns, top.expectedMonad, ety, funIsMonadic, wrapReturn, top.location); + nanns.monadAnns, top.expectedMonad, ety, funIsMonadic, wrapReturn); local expanded_args::AppExprs = snocAppExprs(nanns.fullArgs, ',', presentAppExpr(ne.monadRewritten)); top.monadRewritten = @@ -286,13 +286,13 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp --build the lambda to apply to all the original arguments plus the function function buildMonadApplicationLambda Expr ::= realtys::[Type] monadTysLocs::[Pair] monadAnns::[(Type, QName, Boolean)] - expectedMonad::Type funType::Type bindFun::Boolean wrapReturn::Boolean loc::Location + expectedMonad::Type funType::Type bindFun::Boolean wrapReturn::Boolean { - local funargs::AppExprs = buildFunArgs(length(realtys), loc); - local funannargs::AnnoAppExprs = buildFunAnnArgs(monadAnns, length(realtys) + 1, loc); + local funargs::AppExprs = buildFunArgs(length(realtys)); + local funannargs::AnnoAppExprs = buildFunAnnArgs(monadAnns, length(realtys) + 1); local params::ProductionRHS = buildMonadApplicationParams(realtys ++ map(fst, monadAnns), 1, - if bindFun then monadOfType(expectedMonad, funType) else funType, loc); + if bindFun then monadOfType(expectedMonad, funType) else funType); local actualMonadAnns::[(Type, Integer)] = foldr(\ here::(Type, QName, Boolean) rest::([(Type, Integer)], Integer) -> if here.3 @@ -300,44 +300,43 @@ Expr ::= realtys::[Type] monadTysLocs::[Pair] monadAnns::[(Type, Q else (rest.1, rest.2 -1), ([], length(realtys) + length(monadAnns)), monadAnns).1; local body::Expr = buildMonadApplicationBody(monadTysLocs ++ actualMonadAnns, funargs, funannargs, - head(monadTysLocs).fst, funType, bindFun, wrapReturn, loc); + head(monadTysLocs).fst, funType, bindFun, wrapReturn); return lambdap(params, body); } --build the parameters for the lambda applied to all the original arguments plus the function function buildMonadApplicationParams -ProductionRHS ::= realtys::[Type] currentLoc::Integer funType::Type loc::Location +ProductionRHS ::= realtys::[Type] currentLoc::Integer funType::Type { return if null(realtys) then productionRHSCons(productionRHSElem(name("f"), '::', typerepTypeExpr(funType)), productionRHSNil()) - else productionRHSCons(productionRHSElem(name("a"++toString(currentLoc), loc), + else productionRHSCons(productionRHSElem(name("a"++toString(currentLoc)), '::', typerepTypeExpr(dropDecorated(head(realtys)))), - buildMonadApplicationParams(tail(realtys), currentLoc+1, funType, loc)); + buildMonadApplicationParams(tail(realtys), currentLoc+1, funType)); } --build the arguments for the application inside all the binds --currentIndex is the numerical index of the argument for the name (a, like a3) function buildFunArgs -AppExprs ::= currentIndex::Integer loc::Location +AppExprs ::= currentIndex::Integer { return if currentIndex == 0 then emptyAppExprs() - else snocAppExprs(buildFunArgs(currentIndex - 1, loc), ',', - presentAppExpr(baseExpr(qName(loc, - "a"++toString(currentIndex))))); + else snocAppExprs(buildFunArgs(currentIndex - 1), ',', + presentAppExpr(baseExpr(qName("a"++toString(currentIndex))))); } --build the annotation arguments for the application inside all the binds --annotations are the annotations given to the original call --currentIndex is the numerical index of the argument for the name (a, like a3) function buildFunAnnArgs -AnnoAppExprs ::= annotations::[(Type, QName, Boolean)] currentIndex::Integer loc::Location +AnnoAppExprs ::= annotations::[(Type, QName, Boolean)] currentIndex::Integer { return case annotations of | [] -> emptyAnnoAppExprs() | (ty, q, _)::rest -> - snocAnnoAppExprs(buildFunAnnArgs(rest, currentIndex + 1, loc), ',', + snocAnnoAppExprs(buildFunAnnArgs(rest, currentIndex + 1), ',', annoExpr(q, '=', presentAppExpr(baseExpr(qName("a" ++ toString(currentIndex)))))) end; @@ -345,22 +344,21 @@ AnnoAppExprs ::= annotations::[(Type, QName, Boolean)] currentIndex::Integer loc --build the body of the lambda which includes all the binds function buildMonadApplicationBody Expr ::= monadTysLocs::[Pair] funargs::AppExprs annargs::AnnoAppExprs - monadType::Type funTy::Type bindFun::Boolean wrapReturn::Boolean loc::Location + monadType::Type funTy::Type bindFun::Boolean wrapReturn::Boolean { local sub::Expr = buildMonadApplicationBody(tail(monadTysLocs), funargs, annargs, - monadType, funTy, bindFun, wrapReturn, loc); + monadType, funTy, bindFun, wrapReturn); local argty::Type = head(monadTysLocs).fst; - local bind::Expr = monadBind(loc); + local bind::Expr = monadBind(); local binding::ProductionRHS = - productionRHSCons(productionRHSElem(name("a"++toString(head(monadTysLocs).snd), - loc), + productionRHSCons(productionRHSElem(name("a"++toString(head(monadTysLocs).snd)), '::', - typerepTypeExpr(monadInnerType(argty, loc))), + typerepTypeExpr(monadInnerType(argty))), productionRHSNil()); local bindargs::AppExprs = snocAppExprs( oneAppExprs(presentAppExpr( - baseExpr(qName(loc,"a"++toString(head(monadTysLocs).snd))))), + baseExpr(qName("a"++toString(head(monadTysLocs).snd))))), ',', presentAppExpr(lambdap(binding, sub))); @@ -379,7 +377,7 @@ Expr ::= monadTysLocs::[Pair] funargs::AppExprs annargs::AnnoAppEx local funbindargs::AppExprs = snocAppExprs( oneAppExprs(presentAppExpr( - baseExpr(qName(loc,"f")))), + baseExpr(qName("f")))), ',', presentAppExpr(lambdap(funbinding, funapp))); local fullfun::Expr = @@ -506,19 +504,19 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur local noMonad::Expr = access(e.monadRewritten, '.', q); local isEMonad::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep))} -> + $Expr {monadReturn()} (x.$QName {qName(q.name)}) ) ) }; local isBothMonad::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep))} -> (x.$QName {qName(q.name)}) ) ) @@ -545,7 +543,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur | restrictedSynDcl(_, _, _) -> [] | restrictedInhDcl(_, _, _) -> [] | annoDcl(_, _, _) -> [] - | _ -> [(q.unparse, top.location)] + | _ -> [q] end else []; } @@ -566,19 +564,19 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur local noMonad::Expr = access(e.monadRewritten, '.', q); local isEMonad::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep))} -> + $Expr {monadReturn()} (x.$QName {qName(q.name)}) ) ) }; local isBothMonad::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep))} -> (x.$QName {qName(q.name)}) ) ) @@ -625,19 +623,19 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur local noMonad::Expr = access(e.monadRewritten, '.', q); local isEMonad::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep))} -> + $Expr {monadReturn()} (x.$QName {qName(q.name)}) ) ) }; local isBothMonad::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep))} -> (x.$QName {qName(q.name)}) ) ) @@ -677,7 +675,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur | restrictedSynDcl(_, _, _) -> [] | restrictedInhDcl(_, _, _) -> [] | annoDcl(_, _, _) -> [] - | _ -> [(q.unparse, top.location)] + | _ -> [q] end else []; } @@ -702,10 +700,10 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur local noMonad::Expr = access(e.monadRewritten, '.', q); local isEMonad::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep))} -> + $Expr {monadReturn()} (x.$QName {qName(q.name)}) ) ) @@ -746,19 +744,19 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur local noMonad::Expr = access(e.monadRewritten, '.', q); local isEMonad::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep))} -> + $Expr {monadReturn()} (x.$QName {qName(q.name)}) ) ) }; local isBothMonad::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep))} -> (x.$QName {qName(q.name)}) ) ) @@ -798,7 +796,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur | restrictedSynDcl(_, _, _) -> [] | restrictedInhDcl(_, _, _) -> [] | annoDcl(_, _, _) -> [] - | _ -> [(q.unparse, top.location)] + | _ -> [q] end else []; } @@ -819,19 +817,19 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur local noMonad::Expr = access(e.monadRewritten, '.', q); local isEMonad::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep))} -> + $Expr {monadReturn()} (x.$QName {qName(q.name)}) ) ) }; local isBothMonad::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep))} -> (x.$QName {qName(q.name)}) ) ) @@ -871,7 +869,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur | restrictedSynDcl(_, _, _) -> [] | restrictedInhDcl(_, _, _) -> [] | annoDcl(_, _, _) -> [] - | _ -> [(q.unparse, top.location)] + | _ -> [q] end else []; } @@ -903,10 +901,10 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur local noMonad::Expr = access(e.monadRewritten, '.', q); local isEMonad::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep))} -> + $Expr {monadReturn()} (x.$QName {qName(q.name)}) ) ) @@ -927,7 +925,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur -- TODO: restricted translation attributes? -- | restrictedSynDcl(_, _, _) -> [] -- | restrictedInhDcl(_, _, _) -> [] - | _ -> [(q.unparse, top.location)] + | _ -> [q] end else []; } @@ -949,19 +947,19 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur local noMonad::Expr = access(e.monadRewritten, '.', q); local isEMonad::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep))} -> + $Expr {monadReturn()} (x.$QName {qName(q.name)}) ) ) }; local isBothMonad::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep))} -> (x.$QName {qName(q.name)}) ) ) @@ -1001,7 +999,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur | restrictedSynDcl(_, _, _) -> [] | restrictedInhDcl(_, _, _) -> [] | annoDcl(_, _, _) -> [] - | _ -> [(q.unparse, top.location)] + | _ -> [q] end else []; } @@ -1035,10 +1033,10 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur local noMonad::Expr = access(e.monadRewritten, '.', q); local isEMonad::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep))} -> + $Expr {monadReturn()} (x.$QName {qName(q.name)}) ) ) @@ -1055,7 +1053,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur top.notExplicitAttributes <- e.notExplicitAttributes ++ if q.found - then [(q.unparse, top.location)] + then [q] else []; } @@ -1089,10 +1087,10 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur local noMonad::Expr = access(e.monadRewritten, '.', q); local isEMonad::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {eUnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep))} -> + $Expr {monadReturn()} (x.$QName {qName(q.name)}) ) ) @@ -1113,7 +1111,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur -- TODO: restricted translation attributes? -- | restrictedSynDcl(_, _, _) -> [] -- | restrictedInhDcl(_, _, _) -> [] - | _ -> [(q.unparse, top.location)] + | _ -> [q] end else []; } @@ -1138,15 +1136,15 @@ top::Expr ::= 'decorate' e::Expr 'with' '{' inh::ExprInhs '}' then monadOfType( e.mtyperep, decoratedType( - performSubstitution(monadInnerType(e.mtyperep, top.location), e.mUpSubst), + performSubstitution(monadInnerType(e.mtyperep), e.mUpSubst), inhSetType(sort(nub(inh.suppliedInhs))))) else decoratedType(performSubstitution(e.mtyperep, e.mUpSubst), inhSetType(sort(nub(inh.suppliedInhs)))); local newname::String = "__sv_bind_" ++ toString(genInt()); local params::ProductionRHS = - productionRHSCons(productionRHSElem(name(newname, top.location), + productionRHSCons(productionRHSElem(name(newname), '::', - typerepTypeExpr(monadInnerType(e.mtyperep, top.location))), + typerepTypeExpr(monadInnerType(e.mtyperep))), productionRHSNil()); local eUnDec::Expr = if e.mtyperep.isDecorated @@ -1155,11 +1153,11 @@ top::Expr ::= 'decorate' e::Expr 'with' '{' inh::ExprInhs '}' top.monadRewritten = if isMonad(e.mtyperep, top.env) && monadsMatch(e.mtyperep, top.expectedMonad, top.mDownSubst).fst then Silver_Expr { - $Expr{monadBind(top.location)} + $Expr{monadBind()} ($Expr{eUnDec}, $Expr{lambdap(params, Silver_Expr{ - $Expr{monadReturn(top.location)} + $Expr{monadReturn()} ($Expr{decorateExprWith('decorate', baseExpr(qName(newname)), 'with', '{', inh.monadRewritten, '}')}) @@ -1276,10 +1274,10 @@ top::Expr ::= e1::Expr '&&' e2::Expr else []; local ec1::TypeCheck = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then check(monadInnerType(e1.mtyperep, top.location), boolType()) + then check(monadInnerType(e1.mtyperep), boolType()) else check(e1.mtyperep, boolType()); local ec2::TypeCheck = if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then check(monadInnerType(e2.mtyperep, top.location), boolType()) + then check(monadInnerType(e2.mtyperep), boolType()) else check(e2.mtyperep, boolType()); ec1.finalSubst = top.finalSubst; ec2.finalSubst = top.finalSubst; @@ -1309,26 +1307,26 @@ top::Expr ::= e1::Expr '&&' e2::Expr --e1 >>= ( (\x y -> if x then y else Return(false))(_, e2) ) local bindBoth::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - if x then y else $Expr {monadReturn(top.location)}(false)) (_, $Expr {e2UnDec})) + if x then y else $Expr {monadReturn()}(false)) (_, $Expr {e2UnDec})) }; --e1 >>= ( (\x y -> Return(x && y))(_, e2) ) local bind1::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location))} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep))} y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadReturn(top.location)} + $Expr {monadReturn()} (x && y))(_, $Expr {e2UnDec})) }; --if e1 then e2 else Return(false) local bind2::Expr = Silver_Expr { - if $Expr {e1UnDec} then $Expr {e2UnDec} else $Expr {monadReturn(top.location)}(false) + if $Expr {e1UnDec} then $Expr {e2UnDec} else $Expr {monadReturn()}(false) }; top.monadRewritten = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst then if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst @@ -1359,10 +1357,10 @@ top::Expr ::= e1::Expr '||' e2::Expr else []; local ec1::TypeCheck = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then check(monadInnerType(e1.mtyperep, top.location), boolType()) + then check(monadInnerType(e1.mtyperep), boolType()) else check(e1.mtyperep, boolType()); local ec2::TypeCheck = if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then check(monadInnerType(e2.mtyperep, top.location), boolType()) + then check(monadInnerType(e2.mtyperep), boolType()) else check(e2.mtyperep, boolType()); ec1.finalSubst = top.finalSubst; ec2.finalSubst = top.finalSubst; @@ -1392,26 +1390,26 @@ top::Expr ::= e1::Expr '||' e2::Expr --e1 >>= ( (\x y -> if x then Return(true) else y)(_, e2) ) local bindBoth::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - if x then $Expr {monadReturn(top.location)}(true) else y) (_, $Expr {e2UnDec})) + if x then $Expr {monadReturn()}(true) else y) (_, $Expr {e2UnDec})) }; --e1 >>= ( (\x y -> Return(x || y))(_, e2) ) local bind1::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location))} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep))} y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadReturn(top.location)} + $Expr {monadReturn()} (x || y))(_, $Expr {e2UnDec})) }; --if e1 then Return(true) else e2 local bind2::Expr = Silver_Expr { - if $Expr {e1UnDec} then $Expr {monadReturn(top.location)}(true) else $Expr {e2UnDec} + if $Expr {e1UnDec} then $Expr {monadReturn()}(true) else $Expr {e2UnDec} }; top.monadRewritten = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst then if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst @@ -1435,7 +1433,7 @@ top::Expr ::= '!' e::Expr else []; local ec::TypeCheck = if isMonad(e.mtyperep, top.env) - then check(monadInnerType(e.mtyperep, top.location), boolType()) + then check(monadInnerType(e.mtyperep), boolType()) else check(e.mtyperep, boolType()); e.mDownSubst = top.mDownSubst; ec.downSubst = e.mUpSubst; @@ -1453,10 +1451,10 @@ top::Expr ::= '!' e::Expr top.monadRewritten = if isMonad(e.mtyperep, top.env) && monadsMatch(top.expectedMonad, e.mtyperep, top.mDownSubst).fst then Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {eUnDec}, \x::Boolean -> - $Expr {monadReturn(top.location)}(!x)) + $Expr {monadReturn()}(!x)) } else notOp('!', e.monadRewritten); } @@ -1481,7 +1479,7 @@ top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'end' --this is easier than anything " is not an instance of MonadFail and cannot be used with if-then")]; local ec::TypeCheck = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then check(monadInnerType(e1.mtyperep, top.location), boolType()) + then check(monadInnerType(e1.mtyperep), boolType()) else check(e1.mtyperep, boolType()); ec.finalSubst = top.finalSubst; e1.mDownSubst = top.mDownSubst; @@ -1513,7 +1511,7 @@ top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'end' --this is easier than anything e1.isRoot = false; e2.isRoot = false; - forwards to ifThenElse('if', e1, 'then', e2, 'else', monadFail(top.location)); + forwards to ifThenElse('if', e1, 'then', e2, 'else', monadFail()); } aspect production ifThenElse @@ -1529,14 +1527,14 @@ top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'else' e3::Expr else []; local ec1::TypeCheck = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then check(monadInnerType(e1.mtyperep, top.location), boolType()) + then check(monadInnerType(e1.mtyperep), boolType()) else check(e1.mtyperep, boolType()); local ec2::TypeCheck = if isMonad(e3.mtyperep, top.env) && monadsMatch(top.expectedMonad, e3.mtyperep, top.mDownSubst).fst then if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst then check(e3.mtyperep, e2.mtyperep) - else check(monadInnerType(e3.mtyperep, top.location), e2.mtyperep) + else check(monadInnerType(e3.mtyperep), e2.mtyperep) else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then check(e3.mtyperep, monadInnerType(e2.mtyperep, top.location)) + then check(e3.mtyperep, monadInnerType(e2.mtyperep)) else check(e3.mtyperep, e2.mtyperep); ec1.finalSubst = top.finalSubst; ec2.finalSubst = top.finalSubst; @@ -1575,7 +1573,7 @@ top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'else' e3::Expr -- monad and we don't allow monads to become nested. local cMonad::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {e1UnDec}, (\c::Boolean x::$TypeExpr {typerepTypeExpr(dropDecorated(e2Type))} @@ -1585,10 +1583,10 @@ top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'else' e3::Expr if c then $Expr { if isMonad(e2.mtyperep, top.env) then Silver_Expr {x} - else Silver_Expr {$Expr {monadReturn(top.location)}(x)} } + else Silver_Expr {$Expr {monadReturn()}(x)} } else $Expr { if isMonad(e3.mtyperep, top.env) then Silver_Expr {y} - else Silver_Expr {$Expr {monadReturn(top.location)}(y)} }) + else Silver_Expr {$Expr {monadReturn()}(y)} }) (_, $Expr {e2.monadRewritten}, $Expr {e3.monadRewritten})) }; local cBool::Expr = @@ -1597,12 +1595,12 @@ top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'else' e3::Expr then $Expr {if isMonad(e2.mtyperep, top.env) then e2.monadRewritten else if isMonad(e3.mtyperep, top.env) - then Silver_Expr { $Expr {monadReturn(top.location)}($Expr {e2.monadRewritten}) } + then Silver_Expr { $Expr {monadReturn()}($Expr {e2.monadRewritten}) } else e2.monadRewritten} else $Expr {if isMonad(e3.mtyperep, top.env) then e3.monadRewritten else if isMonad(e2.mtyperep, top.env) - then Silver_Expr { $Expr {monadReturn(top.location)}($Expr {e3.monadRewritten}) } + then Silver_Expr { $Expr {monadReturn()}($Expr {e3.monadRewritten}) } else e3.monadRewritten} }; top.monadRewritten = if isMonad(e1.mtyperep, top.env) @@ -1657,9 +1655,9 @@ top::Expr ::= e1::Expr '+' e2::Expr local ec::TypeCheck = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst then if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst then check(e1.mtyperep, e2.mtyperep) - else check(monadInnerType(e1.mtyperep, top.location), e2.mtyperep) + else check(monadInnerType(e1.mtyperep), e2.mtyperep) else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then check(e1.mtyperep, monadInnerType(e2.mtyperep, top.location)) + then check(e1.mtyperep, monadInnerType(e2.mtyperep)) else check(e1.mtyperep, e2.mtyperep); ec.finalSubst = top.mUpSubst; top.mtyperep = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst @@ -1681,34 +1679,34 @@ top::Expr ::= e1::Expr '+' e2::Expr --e1 >>= ( (\x y -> y >>= \z -> Return(x + z))(_, e2) ) local bindBoth::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadBind(top.location)} + $Expr {monadBind()} (y, - \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)} + \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} -> + $Expr {monadReturn()} (x + z))) (_, $Expr {e2UnDec})) }; --e1 >>= ( (\x y -> Return(x + y))(_, e2) ) local bind1::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location))} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep))} y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadReturn(top.location)} + $Expr {monadReturn()} (x + y))(_, $Expr {e2UnDec})) }; --e2 >>= ( (\x y -> Return(x + y))(e1, _) ) local bind2::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {e2UnDec}, (\x::$TypeExpr {typerepTypeExpr(e1.mtyperep)} - y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)} + y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} -> + $Expr {monadReturn()} (x + y))($Expr {e1UnDec}, _)) }; top.monadRewritten = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst @@ -1747,9 +1745,9 @@ top::Expr ::= e1::Expr '-' e2::Expr local ec::TypeCheck = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst then if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst then check(e1.mtyperep, e2.mtyperep) - else check(monadInnerType(e1.mtyperep, top.location), e2.mtyperep) + else check(monadInnerType(e1.mtyperep), e2.mtyperep) else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then check(e1.mtyperep, monadInnerType(e2.mtyperep, top.location)) + then check(e1.mtyperep, monadInnerType(e2.mtyperep)) else check(e1.mtyperep, e2.mtyperep); ec.finalSubst = top.mUpSubst; top.mtyperep = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst @@ -1771,34 +1769,34 @@ top::Expr ::= e1::Expr '-' e2::Expr --e1 >>= ( (\x y -> y >>= \z -> Return(x - z))(_, e2) ) local bindBoth::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadBind(top.location)} + $Expr {monadBind()} (y, - \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)} + \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} -> + $Expr {monadReturn()} (x - z))) (_, $Expr {e2UnDec})) }; --e1 >>= ( (\x y -> Return(x - y))(_, e2) ) local bind1::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location))} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep))} y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadReturn(top.location)} + $Expr {monadReturn()} (x - y))(_, $Expr {e2UnDec})) }; --e2 >>= ( (\x y -> Return(x - y))(e1, _) ) local bind2::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {e2UnDec}, (\x::$TypeExpr {typerepTypeExpr(e1.mtyperep)} - y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)} + y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} -> + $Expr {monadReturn()} (x - y))($Expr {e1UnDec}, _)) }; top.monadRewritten = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst @@ -1837,9 +1835,9 @@ top::Expr ::= e1::Expr '*' e2::Expr local ec::TypeCheck = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst then if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst then check(e1.mtyperep, e2.mtyperep) - else check(monadInnerType(e1.mtyperep, top.location), e2.mtyperep) + else check(monadInnerType(e1.mtyperep), e2.mtyperep) else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then check(e1.mtyperep, monadInnerType(e2.mtyperep, top.location)) + then check(e1.mtyperep, monadInnerType(e2.mtyperep)) else check(e1.mtyperep, e2.mtyperep); ec.finalSubst = top.mUpSubst; top.mtyperep = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst @@ -1861,34 +1859,34 @@ top::Expr ::= e1::Expr '*' e2::Expr --e1 >>= ( (\x y -> y >>= \z -> Return(x * z))(_, e2) ) local bindBoth::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadBind(top.location)} + $Expr {monadBind()} (y, - \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)} + \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} -> + $Expr {monadReturn()} (x * z))) (_, $Expr {e2UnDec})) }; --e1 >>= ( (\x y -> Return(x * y))(_, e2) ) local bind1::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location))} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep))} y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadReturn(top.location)} + $Expr {monadReturn()} (x * y))(_, $Expr {e2UnDec})) }; --e2 >>= ( (\x y -> Return(x * y))(e1, _) ) local bind2::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {e2UnDec}, (\x::$TypeExpr {typerepTypeExpr(e1.mtyperep)} - y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)} + y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} -> + $Expr {monadReturn()} (x * y))($Expr {e1UnDec}, _)) }; top.monadRewritten = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst @@ -1927,9 +1925,9 @@ top::Expr ::= e1::Expr '/' e2::Expr local ec::TypeCheck = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst then if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst then check(e1.mtyperep, e2.mtyperep) - else check(monadInnerType(e1.mtyperep, top.location), e2.mtyperep) + else check(monadInnerType(e1.mtyperep), e2.mtyperep) else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then check(e1.mtyperep, monadInnerType(e2.mtyperep, top.location)) + then check(e1.mtyperep, monadInnerType(e2.mtyperep)) else check(e1.mtyperep, e2.mtyperep); ec.finalSubst = top.mUpSubst; top.mtyperep = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst @@ -1951,34 +1949,34 @@ top::Expr ::= e1::Expr '/' e2::Expr --e1 >>= ( (\x y -> y >>= \z -> Return(x / z))(_, e2) ) local bindBoth::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadBind(top.location)} + $Expr {monadBind()} (y, - \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)} + \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} -> + $Expr {monadReturn()} (x / z))) (_, $Expr {e2UnDec})) }; --e1 >>= ( (\x y -> Return(x / y))(_, e2) ) local bind1::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location))} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep))} y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadReturn(top.location)} + $Expr {monadReturn()} (x / y))(_, $Expr {e2UnDec})) }; --e2 >>= ( (\x y -> Return(x / y))(e1, _) ) local bind2::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {e2UnDec}, (\x::$TypeExpr {typerepTypeExpr(e1.mtyperep)} - y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)} + y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} -> + $Expr {monadReturn()} (x / y))($Expr {e1UnDec}, _)) }; top.monadRewritten = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst @@ -2017,9 +2015,9 @@ top::Expr ::= e1::Expr '%' e2::Expr local ec::TypeCheck = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst then if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst then check(e1.mtyperep, e2.mtyperep) - else check(monadInnerType(e1.mtyperep, top.location), e2.mtyperep) + else check(monadInnerType(e1.mtyperep), e2.mtyperep) else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then check(e1.mtyperep, monadInnerType(e2.mtyperep, top.location)) + then check(e1.mtyperep, monadInnerType(e2.mtyperep)) else check(e1.mtyperep, e2.mtyperep); ec.finalSubst = top.mUpSubst; top.mtyperep = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst @@ -2041,34 +2039,34 @@ top::Expr ::= e1::Expr '%' e2::Expr --e1 >>= ( (\x y -> y >>= \z -> Return(x % z))(_, e2) ) local bindBoth::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadBind(top.location)} + $Expr {monadBind()} (y, - \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)} + \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} -> + $Expr {monadReturn()} (x % z))) (_, $Expr {e2UnDec})) }; --e1 >>= ( (\x y -> Return(x % y))(_, e2) ) local bind1::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep, top.location))} + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep))} y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadReturn(top.location)} + $Expr {monadReturn()} (x % y))(_, $Expr {e2UnDec})) }; --e2 >>= ( (\x y -> Return(x % y))(e1, _) ) local bind2::Expr = Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {e2UnDec}, (\x::$TypeExpr {typerepTypeExpr(e1.mtyperep)} - y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)} + y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} -> + $Expr {monadReturn()} (x % y))($Expr {e1UnDec}, _)) }; top.monadRewritten = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst @@ -2099,10 +2097,10 @@ top::Expr ::= '-' e::Expr top.monadRewritten = if isMonad(e.mtyperep, top.env) then Silver_Expr { - $Expr {monadBind(top.location)} + $Expr {monadBind()} ($Expr {eUnDec}, - \x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep, top.location))} -> - $Expr {monadReturn(top.location)}(-x)) + \x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep))} -> + $Expr {monadReturn()}(-x)) } else neg('-', e.monadRewritten); } @@ -2121,14 +2119,14 @@ top::Expr ::= 'terminal' '(' t::TypeExpr ',' es::Expr ',' el::Expr ')' else t.typerep; top.monadicNames = []; - local bind::Expr = monadBind(top.location); - local ret::Expr = monadReturn(top.location); + local bind::Expr = monadBind(); + local ret::Expr = monadReturn(); local esty::TypeExpr = typerepTypeExpr(if isMonad(es.mtyperep, top.env) then es.mtyperep - else monadInnerType(es.mtyperep, top.location)); + else monadInnerType(es.mtyperep)); local elty::TypeExpr = typerepTypeExpr(if isMonad(es.mtyperep, top.env) then es.mtyperep - else monadInnerType(es.mtyperep, top.location)); + else monadInnerType(es.mtyperep)); local bindes::Expr = Silver_Expr { $Expr {bind} @@ -2245,7 +2243,7 @@ top::AppExpr ::= e::Expr !fst(monadsMatch(e.mtyperep, top.appExprTyperep, e.mUpSubst)); errCheck1a = check(if top.appExprTyperep.isDecorated then e.mtyperep else dropDecorated(e.mtyperep), top.appExprTyperep); - errCheck2a = check(monadInnerType(e.mtyperep, top.location), top.appExprTyperep); + errCheck2a = check(monadInnerType(e.mtyperep), top.appExprTyperep); top.merrors <- if isMonadic then if !errCheck2a.typeerror diff --git a/grammars/silver/compiler/extension/implicit_monads/Let.sv b/grammars/silver/compiler/extension/implicit_monads/Let.sv index e7a870e51..34e193a78 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Let.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Let.sv @@ -36,8 +36,8 @@ top::Expr ::= la::AssignExpr e::Expr ne.monadicallyUsed = false; top.monadicNames = la.monadicNames ++ ne.monadicNames; - local mreturn::Expr = monadReturn(top.location); - local mbind::Expr = monadBind(top.location); + local mreturn::Expr = monadReturn(); + local mbind::Expr = monadBind(); {- Our rewriting here binds in anything after the let to keep names from @@ -63,7 +63,7 @@ top::Expr ::= la::AssignExpr e::Expr buildLambda(x.fst.name, decorate x.snd with {env=top.env; grammarName=top.grammarName; config=top.config; flowEnv=top.flowEnv;}.typerep, - y, top.location)], top.location), + y)]), inside, la.bindInList); } @@ -100,7 +100,7 @@ top::AssignExpr ::= id::Name '::' t::TypeExpr '=' e::Expr then [errFromOrigin(top, "Let bindings may not use a monad type")] else []; local errCheck::TypeCheck = if isMonad(e.mtyperep, top.env) && fst(monadsMatch(e.mtyperep, top.expectedMonad, top.mDownSubst)) - then check(t.typerep, monadInnerType(e.mtyperep, top.location)) + then check(t.typerep, monadInnerType(e.mtyperep)) else check(t.typerep, e.mtyperep); e.mDownSubst = top.mDownSubst; errCheck.downSubst = e.mUpSubst; diff --git a/grammars/silver/compiler/extension/implicit_monads/PrimitiveMatch.sv b/grammars/silver/compiler/extension/implicit_monads/PrimitiveMatch.sv index 76c961f72..f71143284 100644 --- a/grammars/silver/compiler/extension/implicit_monads/PrimitiveMatch.sv +++ b/grammars/silver/compiler/extension/implicit_monads/PrimitiveMatch.sv @@ -63,10 +63,10 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr top.monadicNames = e.monadicNames ++ pr.monadicNames ++ f.monadicNames; local freshname::String = "__sv_bindingInAMatchExpression_" ++ toString(genInt()); - local eBind::Expr = monadBind(top.location); - local eInnerType::TypeExpr = typerepTypeExpr(monadInnerType(e.mtyperep, top.location)); + local eBind::Expr = monadBind(); + local eInnerType::TypeExpr = typerepTypeExpr(monadInnerType(e.mtyperep)); local binde_lambdaparams::ProductionRHS = - productionRHSCons(productionRHSElem(name(freshname, top.location), '::', + productionRHSCons(productionRHSElem(name(freshname), '::', eInnerType), productionRHSNil()); --Since we sometimes need to just use pure() over the top of everything to get a @@ -81,8 +81,8 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr already).-} local eMTyDecorable::Boolean = if eIsMonadic - then isDecorable(performSubstitution(monadInnerType(e.mtyperep, top.location), e.mUpSubst), top.env) || - (!performSubstitution(monadInnerType(e.mtyperep, top.location), e.mUpSubst).isDecorated && isDecorable(pr.patternType, top.env)) + then isDecorable(performSubstitution(monadInnerType(e.mtyperep), e.mUpSubst), top.env) || + (!performSubstitution(monadInnerType(e.mtyperep), e.mUpSubst).isDecorated && isDecorable(pr.patternType, top.env)) else isDecorable(performSubstitution(e.mtyperep, e.mUpSubst), top.env) || (!performSubstitution(e.mtyperep, e.mUpSubst).isDecorated && isDecorable(pr.patternType, top.env)); local decName::Expr = @@ -100,20 +100,18 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr buildApplication(eBind, [e.monadRewritten, lambdap(binde_lambdaparams, matchPrimitiveReal(decName, - outty, pr.monadRewritten, f.monadRewritten))], - top.location); + outty, pr.monadRewritten, f.monadRewritten))]); --bind e, return f based on e's type local bind_e_return_f::Expr = buildApplication(eBind, [e.monadRewritten, lambdap(binde_lambdaparams, matchPrimitiveReal(decName, outty, pr.monadRewritten, - buildApplication(monadReturn(top.location), - [f.monadRewritten], top.location)))], - top.location); + buildApplication(monadReturn(), + [f.monadRewritten])))]); --bind e, returnify pr based on e's type local prReturnify::PrimPatterns = pr.monadRewritten; - prReturnify.returnFun = monadReturn(top.location); + prReturnify.returnFun = monadReturn(); prReturnify.grammarName = top.grammarName; prReturnify.env = top.env; prReturnify.config = top.config; @@ -122,24 +120,22 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr [e.monadRewritten, lambdap(binde_lambdaparams, matchPrimitiveReal(decName, outty, prReturnify.returnify, - f.monadRewritten))], - top.location); + f.monadRewritten))]); --bind e, returnify pr, return f based on e's type local bind_e_returnify_pr_return_f::Expr = buildApplication(eBind, [e.monadRewritten, lambdap(binde_lambdaparams, matchPrimitiveReal(decName, outty, prReturnify.returnify, - buildApplication(monadReturn(top.location), - [f.monadRewritten], top.location)))], - top.location); + buildApplication(monadReturn(), + [f.monadRewritten])))]); --return f from pr's return type local return_f::Expr = matchPrimitiveReal(decE, outty, pr.monadRewritten, - buildApplication(monadReturn(top.location), [f.monadRewritten], top.location)); + buildApplication(monadReturn(), [f.monadRewritten])); --returnify pr from f's type local ret_pr_from_f::PrimPatterns = pr.monadRewritten; - ret_pr_from_f.returnFun = monadReturn(top.location); + ret_pr_from_f.returnFun = monadReturn(); ret_pr_from_f.grammarName = top.grammarName; ret_pr_from_f.env = top.env; ret_pr_from_f.config = top.config; @@ -150,10 +146,9 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr f.monadRewritten); --t is monadic and nothing else is, so return over whole thing local return_whole_thing::Expr = - buildApplication(monadReturn(top.location), + buildApplication(monadReturn(), [matchPrimitiveReal(decE, outty, pr.monadRewritten, - f.monadRewritten)], - top.location); + f.monadRewritten)]); --pick the right rewriting local mRw::Expr = if eIsMonadic @@ -173,7 +168,7 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr else if tIsMonadic then return_whole_thing else if tIsMonadic --and nothing else is, so we need to add return - then Silver_Expr {$Expr {monadReturn(top.location)}($Expr {just_rewrite})} + then Silver_Expr {$Expr {monadReturn()}($Expr {just_rewrite})} else just_rewrite; top.monadRewritten = mRw; } @@ -220,7 +215,7 @@ top::PrimPatterns ::= p::PrimPattern vbar::Vbar_kwd ps::PrimPatterns local basicRewritten::PrimPatterns = consPattern(p.monadRewritten, terminal(Vbar_kwd, "|"), ps.monadRewritten); --when the current clause is a monad but the rest aren't, wrap all of them in Return() local psReturnify::PrimPatterns = ps.monadRewritten; - psReturnify.returnFun = monadReturn(top.location); + psReturnify.returnFun = monadReturn(); psReturnify.env = top.env; psReturnify.config = top.config; psReturnify.grammarName = top.grammarName; @@ -228,7 +223,7 @@ top::PrimPatterns ::= p::PrimPattern vbar::Vbar_kwd ps::PrimPatterns psReturnify.returnify); --when the current clause is not a monad but the rest are, wrap the current one in Return() local pReturnify::PrimPattern = p.monadRewritten; - pReturnify.returnFun = monadReturn(top.location); + pReturnify.returnFun = monadReturn(); pReturnify.grammarName = top.grammarName; pReturnify.config = top.config; pReturnify.env = top.env; diff --git a/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv b/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv index 5111a47f7..052e3d87f 100644 --- a/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv +++ b/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv @@ -44,13 +44,13 @@ top::ProductionStmt ::= 'implicit' dl::DefLHS '.' attr::QNameAttrOccur '=' ';' forwards to if null(merrors) - then attr.attrDcl.attrDefDispatcher(dl, attr, monadFail(top.location), top.location) + then attr.attrDcl.attrDefDispatcher(dl, attr, monadFail()) else errorProductionStmt(merrors); } global partialDefaultAttributeDef::(ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr) = - \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr loc::Location -> + \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr -> attributeDef(newUnique(dl), '.', newUnique(attr), '=', e, ';'); concrete production implicitAttributeDef @@ -87,7 +87,7 @@ top::ProductionStmt ::= 'implicit' dl::DefLHS '.' attr::QNameAttrOccur '=' e::Ex then attr.attrDcl.attrDefDispatcher --if not found, let the normal dispatcher handle it else partialDefaultAttributeDef - else errorAttributeDef(merrors, _, _, _))(dl, attr, e, top.location); + else errorAttributeDef(merrors, _, _, _))(dl, attr, e); } @@ -128,7 +128,7 @@ top::ProductionStmt ::= 'restricted' dl::DefLHS '.' attr::QNameAttrOccur '=' e:: then attr.attrDcl.attrDefDispatcher --if not found, let the normal dispatcher handle it else partialDefaultAttributeDef - else errorAttributeDef(merrors, _, _, _))(dl, attr, e, top.location); + else errorAttributeDef(merrors, _, _, _))(dl, attr, e); } @@ -169,7 +169,7 @@ top::ProductionStmt ::= 'unrestricted' dl::DefLHS '.' attr::QNameAttrOccur '=' e | _ -> partialDefaultAttributeDef end --if not found, let the normal dispatcher handle it - else partialDefaultAttributeDef)(dl, attr, e, top.location); + else partialDefaultAttributeDef)(dl, attr, e); } @@ -179,13 +179,13 @@ top::ProductionStmt ::= 'unrestricted' dl::DefLHS '.' attr::QNameAttrOccur '=' e --take a list of unallowed attributes and generate error messages for them function buildExplicitAttrErrors -[Message] ::= l::[Pair] +[Message] ::= l::[Decorated QNameAttrOccur] { return case l of | [] -> [] - | (name, loca)::t -> - err(loca, "Attributes accessed in restricted equations must be restricted; " ++ - name ++ " is not")::buildExplicitAttrErrors(t) + | a::t -> + errFromOrigin(a, "Attributes accessed in restricted equations must be restricted; " ++ + a.name ++ " is not")::buildExplicitAttrErrors(t) end; } @@ -215,7 +215,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e: forwards to (if null(merrors) then synthesizedAttributeDef(_, _, _) - else errorAttributeDef(merrors, _, _, _))(dl, attr, e, top.location); + else errorAttributeDef(merrors, _, _, _))(dl, attr, e); } @@ -242,7 +242,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e: forwards to (if null(merrors) then inheritedAttributeDef(_, _, _) - else errorAttributeDef(merrors, _, _, _))(dl, attr, e, top.location); + else errorAttributeDef(merrors, _, _, _))(dl, attr, e); } @@ -274,10 +274,10 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e: then if fst(monadsMatch(attr.typerep, e.mtyperep, e.mUpSubst)) then synthesizedAttributeDef(_, _, e.monadRewritten) else synthesizedAttributeDef(_, _, Silver_Expr { - $Expr {monadReturn(top.location)} + $Expr {monadReturn()} ($Expr {e.monadRewritten}) }) - else errorAttributeDef(e.merrors, _, _, e.monadRewritten))(dl, attr, top.location); + else errorAttributeDef(e.merrors, _, _, e.monadRewritten))(dl, attr); } @@ -306,9 +306,9 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e: then if fst(monadsMatch(attr.typerep, e.mtyperep, e.mUpSubst)) then inheritedAttributeDef(_, _, e.monadRewritten) else inheritedAttributeDef(_, _, Silver_Expr { - $Expr {monadReturn(top.location)} + $Expr {monadReturn()} ($Expr {e.monadRewritten}) }) - else errorAttributeDef(e.merrors, _, _, e.monadRewritten))(dl, attr, top.location); + else errorAttributeDef(e.merrors, _, _, e.monadRewritten))(dl, attr); } diff --git a/grammars/silver/compiler/extension/implicit_monads/Util.sv b/grammars/silver/compiler/extension/implicit_monads/Util.sv index 4c3727d95..4172e77e5 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Util.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Util.sv @@ -111,8 +111,9 @@ Pair ::= t1::Type t2::Type subst::Substitution function monadInnerType -Type ::= mty::Type loc::Location +Type ::= mty::Type { + local loc::Location = getParsedOriginLocationOrFallback(ambientOrigin()); return case dropDecorated(mty) of | appType(c, a) -> a | _ -> error("The monadInnerType function should only be called " ++ @@ -152,38 +153,38 @@ String ::= ty::Type {-find the name of the bind/return for a given monad to use to build the rewritten term-} function monadBind -Expr ::= l::Location +Expr ::= { - return baseExpr(qNameId(name("silver:core:bind", l))); + return baseExpr(qNameId(name("silver:core:bind"))); } function monadReturn -Expr ::= l::Location +Expr ::= { - return baseExpr(qNameId(name("silver:core:pure", l))); + return baseExpr(qNameId(name("silver:core:pure"))); } --We want to produce a value, not a function, so we apply it to an argument function monadFail -Expr ::= l::Location +Expr ::= { + local loc::Location = getParsedOriginLocationOrFallback(ambientOrigin()); return buildApplication - (baseExpr(qNameId(name("silver:core:fail", l))), + (baseExpr(qNameId(name("silver:core:fail"))), [stringConst(terminal(String_t, "\"Automatically-inserted fail at " ++ - l.unparse ++ "\""), - location=l)], l); + loc.unparse ++ "\""))]); } function monadPlus -Expr ::= l::Location +Expr ::= { - return baseExpr(qNameId(name("silver:core:alt", l))); + return baseExpr(qNameId(name("silver:core:alt"))); } function monadZero -Expr ::= l::Location +Expr ::= { - return baseExpr(qNameId(name("silver:core:empty", l))); + return baseExpr(qNameId(name("silver:core:empty"))); } @@ -197,20 +198,20 @@ Expr ::= l::Location -} function buildApplication -Expr ::= fun::Expr args::[Expr] loc::Location +Expr ::= fun::Expr args::[Expr] { - return applicationExpr(fun, '(', buildApplicationReverseArgs(reverse(args), loc), ')'); + return applicationExpr(fun, '(', buildApplicationReverseArgs(reverse(args)), ')'); } --because the AST is set up as a snoc list, we build the arguments in reverse --e.g. [a,b,c] gives application arguments (c, b, a) function buildApplicationReverseArgs -AppExprs ::= args::[Expr] loc::Location +AppExprs ::= args::[Expr] { return case args of | [] -> emptyAppExprs() | hd::tl -> - snocAppExprs(buildApplicationReverseArgs(tl, loc), ',', + snocAppExprs(buildApplicationReverseArgs(tl), ',', presentAppExpr(hd)) end; } @@ -218,11 +219,11 @@ AppExprs ::= args::[Expr] loc::Location function buildLambda -Expr ::= n::String ty::Type body::Expr loc::Location +Expr ::= n::String ty::Type body::Expr { -- \ n::ty -> body return lambdap( - productionRHSCons(productionRHSElem(name(n, loc), + productionRHSCons(productionRHSElem(name(n), '::', typerepTypeExpr(ty)), productionRHSNil()), @@ -231,13 +232,13 @@ Expr ::= n::String ty::Type body::Expr loc::Location function buildMultiLambda -Expr ::= names::[Pair] body::Expr loc::Location +Expr ::= names::[Pair] body::Expr { local sig::ProductionRHS = foldr(\ pr::Pair p::ProductionRHS -> case pr of | (n, ty) -> - productionRHSCons(productionRHSElem(name(n, loc), '::', + productionRHSCons(productionRHSElem(name(n), '::', typerepTypeExpr(ty)), p) end, diff --git a/grammars/silver/compiler/extension/patternmatching/Case.sv b/grammars/silver/compiler/extension/patternmatching/Case.sv index ef7133135..49f9b10b7 100644 --- a/grammars/silver/compiler/extension/patternmatching/Case.sv +++ b/grammars/silver/compiler/extension/patternmatching/Case.sv @@ -81,7 +81,7 @@ top::Expr ::= 'case' es::Exprs 'of' Opt_Vbar_t ml::MRuleList 'end' -- introduce the failure case here. forwards to caseExpr(es.rawExprs, ml.matchRuleList, true, - mkStrFunctionInvocation(top.location, "silver:core:error", + mkStrFunctionInvocation("silver:core:error", [stringConst(terminal(String_t, "\"Error: pattern match failed at " ++ top.grammarName ++ " " ++ top.location.unparse ++ "\\n\""))]), freshType()); @@ -122,7 +122,7 @@ top::Expr ::= es::[Expr] ml::[AbstractMatchRule] complete::Boolean failExpr::Exp top.errors <- case completenessCounterExample of | just(lst) when complete -> - [mwdaWrn(top.config, top.location, + [mwdaWrnFromOrigin(top, "This pattern-matching is not exhaustive. Here is an example of a " ++ "case that is not matched: " ++ implode(", ", map((.unparse), lst)))] | _ -> [] @@ -131,7 +131,7 @@ top::Expr ::= es::[Expr] ml::[AbstractMatchRule] complete::Boolean failExpr::Exp --If we have only conditional rules, it isn't complete top.errors <- if complete && length(conditionlessRules) == 0 && length(ml) > 0 - then [mwdaWrn(top.config, top.location, + then [mwdaWrnFromOrigin(top, "This pattern-matching is not exhaustive because it only has conditional rules")] else []; @@ -159,13 +159,12 @@ top::Expr ::= es::[Expr] ml::[AbstractMatchRule] complete::Boolean failExpr::Exp local names::[String] = map(\ x::Expr -> "__match_expr_" ++ toString(genInt()), es); local nameExprs::[Expr] = - map(\ x::String -> baseExpr(qName(bogusLoc(), x), - location=bogusLoc()), names); + map(\ x::String -> baseExpr(qName(x)), names); local compiledCase::Expr = - compileCaseExpr(nameExprs, ml, failExpr, retType, top.location, top.env); + compileCaseExpr(nameExprs, ml, failExpr, retType, top.env); local fwdResult::Expr = foldr(\ p::(String, Expr) rest::Expr -> - makeLet(top.location, p.1, freshType(), p.2, rest), + makeLet(p.1, freshType(), p.2, rest), compiledCase, zip(names, es)); forwards to fwdResult; } @@ -283,14 +282,14 @@ function splitPatternGroups --Compile a case expression `case es of ml` down into primitive matches function compileCaseExpr Expr ::= es::[Expr] ml::[AbstractMatchRule] failExpr::Expr retType::Type - loc::Location env::Env + env::Env { --Split rules into segments of non-forwarding constructors, all same -- forwarding constructor, and variables based on first pattern local groups::[[AbstractMatchRule]] = splitPatternGroups(ml, env); local compiledGroups::Expr = - compilePatternGroups(es, groups, failExpr, retType, loc, env); + compilePatternGroups(es, groups, failExpr, retType, env); --Check if there is any match rule with empty patterns local anyEmptyRules::Boolean = @@ -333,11 +332,11 @@ Expr ::= es::[Expr] ml::[AbstractMatchRule] failExpr::Expr retType::Type --implement the match function compilePatternGroups Expr ::= matchEs::[Expr] ruleGroups::[[AbstractMatchRule]] finalFail::Expr - retType::Type loc::Location env::Env + retType::Type env::Env { local compileRest::Expr = compilePatternGroups(matchEs, tail(ruleGroups), finalFail, - retType, loc, env); + retType, env); local firstGroup::[AbstractMatchRule] = case ruleGroups of @@ -377,10 +376,10 @@ Expr ::= matchEs::[Expr] ruleGroups::[[AbstractMatchRule]] finalFail::Expr local currentVarCase::Expr = compileCaseExpr(tail(matchEs), boundVarRules, baseExpr(qName(failName)), - retType, loc, env); + retType, env); local bindFailName::Expr = - makeLet(loc, failName, retType, compileRest, + makeLet(failName, retType, compileRest, if firstPatt.patternIsVariable then currentVarCase else currentConCase); @@ -415,28 +414,28 @@ PrimPattern ::= currExpr::Expr restExprs::[Expr] failCase::Expr compileCaseExpr( map(exprFromName, names) ++ annoAccesses ++ restExprs, map(\ mr::AbstractMatchRule -> mr.expandHeadPattern(annos), mrs), - failCase, retType, head(mrs).location, env); + failCase, retType, env); local annos :: [String] = nub(map(fst, flatMap((.patternNamedSubPatternList), map((.headPattern), mrs)))); local annoAccesses :: [Expr] = map(\ n::String -> access(currExpr, '.', qNameAttrOccur(qName(n))), annos); - -- Maybe this one is more reasonable? We need to test examples and see what happens... - local l :: Location = head(mrs).headPattern.location; - return - case head(mrs).headPattern of - | prodAppPattern_named(qn,_,_,_,_,_) -> - prodPattern(qn, '(', convStringsToVarBinders(names, l), ')', '->', subcase) - | intPattern(it) -> integerPattern(it, '->', subcase) - | fltPattern(it) -> floatPattern(it, '->', subcase) - | strPattern(it) -> stringPattern(it, '->', subcase) - | truePattern(_) -> booleanPattern("true", '->', subcase) - | falsePattern(_) -> booleanPattern("false", '->', subcase) - | nilListPattern(_,_) -> nilPattern(subcase) - | consListPattern(h,_,t) -> conslstPattern(head(names), head(tail(names)), subcase) - | _ -> error("Can only have constructor patterns in allConCaseTransform: " ++ head(mrs).headPattern.unparse) + -- Maybe this one is more reasonable? We need to test examples and see what happens... + attachNote logicalLocationFromOrigin(head(mrs).headPattern) on + case head(mrs).headPattern of + | prodAppPattern_named(qn,_,_,_,_,_) -> + prodPattern(qn, '(', convStringsToVarBinders(names), ')', '->', subcase) + | intPattern(it) -> integerPattern(it, '->', subcase) + | fltPattern(it) -> floatPattern(it, '->', subcase) + | strPattern(it) -> stringPattern(it, '->', subcase) + | truePattern(_) -> booleanPattern("true", '->', subcase) + | falsePattern(_) -> booleanPattern("false", '->', subcase) + | nilListPattern(_,_) -> nilPattern(subcase) + | consListPattern(h,_,t) -> conslstPattern(head(names), head(tail(names)), subcase) + | _ -> error("Can only have constructor patterns in allConCaseTransform: " ++ head(mrs).headPattern.unparse) + end end; } @@ -452,7 +451,7 @@ function checkOverlappingPatterns --check for multiple match rules, with no patterns/conditions left to distinguish them | matchRule([], _, e) :: _ :: _ -> if areUselessPatterns(ml) - then [err(head(ml).location, "Pattern has overlapping cases!")] + then [errFromOrigin(head(ml), "Pattern has overlapping cases!")] else [] | _ -> [] end; @@ -530,7 +529,7 @@ function allConCaseCheckOverlapping -- This is an erroneous condition, but it means we transform into a maybe-more erroneous condition. local names :: [Name] = map(patternListVars, head(mrs).headPattern.patternSubPatternList); - local l :: Location = head(mrs).headPattern.location; + attachNote logicalLocationFromOrigin(head(mrs).headPattern); local annos :: [String] = nub(map(fst, flatMap((.patternNamedSubPatternList), map((.headPattern), mrs)))); local annoAccesses :: [Expr] = @@ -619,7 +618,7 @@ Maybe<[Pattern]> ::= lst::[[Decorated Pattern]] env::Env else --If we somehow end up with all vars to start, just check the rest case checkCompleteness(map(tail, lst), env, flowEnv) of | nothing() -> nothing() - | just(plst) -> just(wildcPattern('_', location=bogusLoc())::plst) + | just(plst) -> just(wildcPattern('_')::plst) end; } @@ -631,7 +630,7 @@ Maybe<[Pattern]> ::= lst::[[Decorated Pattern]] env::Env function generateWildcards [Pattern] ::= n::Integer { - return repeat(wildcPattern('_', location=bogusLoc()), n); + return repeat(wildcPattern('_'), n); } {- @@ -717,21 +716,21 @@ Pattern ::= lst::[Integer] initial::Integer { return if containsBy(\ a::Integer b::Integer -> a == b, initial, lst) then generateMissingIntegerPattern(lst, initial + 1) - else intPattern(terminal(Int_t, toString(initial), bogusLoc()), location=bogusLoc()); + else intPattern(terminal(Int_t, toString(initial), bogusLoc())); } function generateMissingFloatPattern Pattern ::= lst::[Float] initial::Float { return if containsBy(\ a::Float b::Float -> a == b, initial, lst) then generateMissingFloatPattern(lst, initial + 1.0) - else fltPattern(terminal(Float_t, toString(initial), bogusLoc()), location=bogusLoc()); + else fltPattern(terminal(Float_t, toString(initial), bogusLoc())); } function generateMissingStringPattern Pattern ::= lst::[String] initial::String { return if containsBy(\ a::String b::String -> a == b, initial, lst) then generateMissingStringPattern(lst, initial ++ "*") - else strPattern(terminal(String_t, "\"" ++ initial ++ "\"", bogusLoc()), location=bogusLoc()); + else strPattern(terminal(String_t, "\"" ++ initial ++ "\"", bogusLoc())); } --First pattern in each set in conPatts is a primitive @@ -766,7 +765,7 @@ Maybe<[Pattern]> ::= conPatts::[[Decorated Pattern]] varPatts::[[Decorated Patte --This gives us better error messages for missing patterns case checkCompleteness(map(tail, varPatts), env, flowEnv), firstPattMissing of | just(plst), just(fp) -> just(fp::plst) - | just(plst), nothing() -> just(wildcPattern('_', location=bogusLoc())::plst) + | just(plst), nothing() -> just(wildcPattern('_')::plst) | nothing(), _ -> nothing() end end; @@ -807,10 +806,10 @@ Maybe<[Pattern]> ::= conPatts::[[Decorated Pattern]] varPatts::[[Decorated Patte --What's missing from subcalls, including the first pattern local subcallResult::Maybe<[Pattern]> = case trueSubcall of - | just(lst) -> just(truePattern('true', location=bogusLoc())::lst) + | just(lst) -> just(truePattern('true')::lst) | nothing() -> case falseSubcall of - | just(lst) -> just(falsePattern('false', location=bogusLoc())::lst) + | just(lst) -> just(falsePattern('false')::lst) | nothing() -> --If completed by vars, need to check vars case is complete as well if foundTrue && foundFalse @@ -824,8 +823,8 @@ Maybe<[Pattern]> ::= conPatts::[[Decorated Pattern]] varPatts::[[Decorated Patte else if foundTrue then if foundFalse then subcallResult - else just(falsePattern('false', location=bogusLoc())::generateWildcards(numPatts - 1)) - else just(truePattern('true', location=bogusLoc())::generateWildcards(numPatts - 1)); + else just(falsePattern('false')::generateWildcards(numPatts - 1)) + else just(truePattern('true')::generateWildcards(numPatts - 1)); } --First pattern in each set in consPatts is a list pattern @@ -859,18 +858,17 @@ Maybe<[Pattern]> ::= conPatts::[[Decorated Pattern]] varPatts::[[Decorated Patte --What's missing from subcalls, including the first pattern local subcallResult::Maybe<[Pattern]> = case nilSubcall of - | just(lst) -> just(nilListPattern('[', ']', location=bogusLoc())::lst) + | just(lst) -> just(nilListPattern('[', ']')::lst) | nothing() -> case consSubcall of --If the missing subpattern is also a cons, wrap it in parentheses to display correctly --Otherwise `(a::b)::c` displays as `a::b::c`, which means something different | just(consListPattern(hd1, _, tl1)::tl::lst) -> just(consListPattern( - nestedPatterns('(', consListPattern(hd1, '::', tl1, location=bogusLoc()), ')', - location=bogusLoc()), - '::', tl, location=bogusLoc())::lst) + nestedPatterns('(', consListPattern(hd1, '::', tl1), ')'), + '::', tl)::lst) | just(hd::tl::lst) -> - just(consListPattern(hd, '::', tl, location=bogusLoc())::lst) + just(consListPattern(hd, '::', tl)::lst) | just(_) -> error("List must include patterns for at least head and tail") | nothing() -> --If completed by vars, need to check vars case is complete as well @@ -885,10 +883,10 @@ Maybe<[Pattern]> ::= conPatts::[[Decorated Pattern]] varPatts::[[Decorated Patte else if foundNil then if foundCons then subcallResult - else just(consListPattern(wildcPattern('_', location=bogusLoc()), '::', - wildcPattern('_', location=bogusLoc()), location=bogusLoc()):: + else just(consListPattern(wildcPattern('_'), '::', + wildcPattern('_')):: generateWildcards(numPatts - 1)) - else just(nilListPattern('[', ']', location=bogusLoc())::generateWildcards(numPatts - 1)); + else just(nilListPattern('[', ']')::generateWildcards(numPatts - 1)); } --First pattern in each set in consPatts is a nonterminal pattern @@ -935,14 +933,14 @@ Maybe<[Pattern]> ::= conPatts::[[Decorated Pattern]] varPatts::[[Decorated Patte --This gives us better error messages for missing patterns case checkCompleteness(map(tail, varPatts), env, flowEnv), allRepresented of | nothing(), _ -> nothing() - | just(plst), nothing() -> just(wildcPattern('_', location=bogusLoc())::plst) + | just(plst), nothing() -> just(wildcPattern('_')::plst) | just(plst), just(p) -> just(p::plst) end else nothing() end; --To find out if the nonterminal is closed or not, we need to look it up - local nt::QName = qName(bogusLoc(), builtType); + local nt::QName = qName(builtType); nt.env = env; local isClosed::Boolean = case nt.lookupType.dcls of @@ -958,8 +956,7 @@ Maybe<[Pattern]> ::= conPatts::[[Decorated Pattern]] varPatts::[[Decorated Patte then nothing() else if isClosed && !hasVar --This is a hack to pass up a message about closed nonterminals as a pattern - then just(varPattern(name("", bogusLoc()), - location=bogusLoc())::generateWildcards(numPatts - 1)) + then just(varPattern(name(""))::generateWildcards(numPatts - 1)) else if hasVar then subcallResult else case allRepresented of @@ -994,7 +991,7 @@ Maybe<[Pattern]> ::= conGrps::[ [[Decorated Pattern]] ] varPatts::[[Decorated Pa case hdComplete, hdProdPatt of | just(plst), prodAppPattern_named(qname, _, _, _, _, _) -> just(prodAppPattern(qname, '(', buildPatternList(take(numChildren, plst), bogusLoc()), - ')', location=bogusLoc())::drop(numChildren, plst)) + ')')::drop(numChildren, plst)) | just(_), _ -> error("Should not have anything but prodAppPattern_named here") | nothing(), _ -> checkAllProdGroupsComplete(rest, varPatts, env, flowEnv) end @@ -1012,7 +1009,7 @@ Maybe ::= givenPatts::[Decorated Pattern] requiredProds::[String] env:: (e.g. forwarding productions). -} local firstProdName::String = head(requiredProds); - local firstProdQName::QName = qName(bogusLoc(), firstProdName); + local firstProdQName::QName = qName(firstProdName); local pattFound::Boolean = foldr(\ p::Decorated Pattern b::Boolean -> b || p.patternSortKey == firstProdName, @@ -1021,7 +1018,7 @@ Maybe ::= givenPatts::[Decorated Pattern] requiredProds::[String] env:: firstProdQName.env = env; local firstProdNumArgs::Integer = firstProdQName.lookupValue.typeScheme.typerep.arity; local wildcards::PatternList = - buildPatternList(repeat(wildcPattern('_', location=bogusLoc()), firstProdNumArgs), bogusLoc()); + buildPatternList(repeat(wildcPattern('_'), firstProdNumArgs), bogusLoc()); return case requiredProds of @@ -1029,8 +1026,7 @@ Maybe ::= givenPatts::[Decorated Pattern] requiredProds::[String] env:: | _::rest -> if pattFound then checkAllProdsRepresented(givenPatts, rest, env) - else just(prodAppPattern(firstProdQName, '(', wildcards, ')', - location=bogusLoc())) + else just(prodAppPattern(firstProdQName, '(', wildcards, ')')) end; } @@ -1215,14 +1211,14 @@ Name ::= p::Decorated Pattern | varPattern(pvn) -> "__sv_pv_" ++ toString(genInt()) ++ "_" ++ pvn.name | h -> "__sv_tmp_pv_" ++ toString(genInt()) end; - return name(n, p.location); + return name(n); } function convStringsToVarBinders -VarBinders ::= s::[Name] l::Location +VarBinders ::= s::[Name] { return if null(s) then nilVarBinder() - else if null(tail(s)) then oneVarBinder(varVarBinder(head(s), location=head(s).location)) - else consVarBinder(varVarBinder(head(s), location=head(s).location), ',', convStringsToVarBinders(tail(s), l)); + else if null(tail(s)) then oneVarBinder(varVarBinder(head(s))) + else consVarBinder(varVarBinder(head(s)), ',', convStringsToVarBinders(tail(s))); } function exprFromName Expr ::= n::Name @@ -1233,8 +1229,8 @@ Expr ::= n::Name function foldPrimPatterns PrimPatterns ::= l::[PrimPattern] { - return if null(tail(l)) then onePattern(head(l), location=head(l).location) - else consPattern(head(l), '|', foldPrimPatterns(tail(l)), location=head(l).location); + return if null(tail(l)) then onePattern(head(l)) + else consPattern(head(l), '|', foldPrimPatterns(tail(l))); } {-- @@ -1249,6 +1245,8 @@ PrimPatterns ::= l::[PrimPattern] function bindHeadPattern AbstractMatchRule ::= headExpr::Expr headType::Type absRule::AbstractMatchRule { + attachNote logicalLocationFromOrigin(absRule); + -- If it's '_' we do nothing, otherwise, bind away! return case absRule of | matchRule(headPat :: restPat, cond, e) -> @@ -1257,10 +1255,10 @@ AbstractMatchRule ::= headExpr::Expr headType::Type absRule::AbstractMatchRule matchRule( restPat, case cond of - | just((c, p)) -> just((makeLet(absRule.location, pvn, headType, headExpr, c), p)) + | just((c, p)) -> just((makeLet(pvn, headType, headExpr, c), p)) | nothing() -> nothing() end, - makeLet(absRule.location, pvn, headType, headExpr, e)) + makeLet(pvn, headType, headExpr, e)) | nothing() -> matchRule(restPat, cond, e) end | r -> r -- Don't crash when we see a rule with too few patterns (should be an error) @@ -1281,11 +1279,11 @@ AbstractMatchRule ::= absRule::AbstractMatchRule } function makeLet -Expr ::= l::Location s::String t::Type e::Expr o::Expr +Expr ::= s::String t::Type e::Expr o::Expr { return letp( assignExpr( - name(s, l), '::', typerepTypeExpr(t), '=', e), + name(s), '::', typerepTypeExpr(t), '=', e), o); } diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index c53c17a7a..43beb6d7b 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -268,18 +268,15 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur productionRHSCons( productionRHSElem( name("_e"), '::', - typerepTypeExpr(eUndec.finalType), - location=builtin), + typerepTypeExpr(eUndec.finalType)), inh.lambdaParams, location=builtin), Silver_Expr { $Expr{ decorateExprWith( 'decorate', baseExpr(qName("_e")), - 'with', '{', inh.bodyExprInhTransform, '}', - location=builtin)}.$qName{q.name} - }, - location=builtin)}) + 'with', '{', inh.bodyExprInhTransform, '}')}.$qName{q.name} + })}) }), consASTExpr(eUndec.transform, inh.transform), nilNamedASTExpr()) @@ -409,15 +406,11 @@ top::Expr ::= 'decorate' e::Expr 'with' '{' inh::ExprInhs '}' productionRHSCons( productionRHSElem( name("_e"), '::', - typerepTypeExpr(e.finalType), - location=builtin), - inh.lambdaParams, - location=builtin), + typerepTypeExpr(e.finalType)), + inh.lambdaParams), decorateExprWith( 'decorate', baseExpr(qName("_e")), - 'with', '{', inh.bodyExprInhTransform, '}', - location=builtin), - location=builtin)}) + 'with', '{', inh.bodyExprInhTransform, '}'))}) }), consASTExpr(e.transform, inh.transform), nilNamedASTExpr()); @@ -461,13 +454,10 @@ top::ExprInh ::= lhs::ExprLHSExpr '=' e::Expr ';' local paramName::String = implode("_", explode(":", lhs.name)); top.lambdaParam = productionRHSElem( - name(paramName, builtin), '::', - typerepTypeExpr(e.finalType), - location=builtin); + name(paramName), '::', + typerepTypeExpr(e.finalType)); top.bodyExprInhTransform = - exprInh( - lhs, '=', baseExpr(qName(paramName)), ';', - location=builtin); + exprInh(lhs, '=', baseExpr(qName(paramName)), ';'); } aspect production trueConst @@ -641,9 +631,7 @@ top::Expr ::= 'case' es::Exprs 'of' o::Opt_Vbar_t ml::MRuleList 'end' decEs.lambdaParams, caseExpr_c( 'case', decEs.lambdaParamRefs, 'of', - o, ml, 'end', - location=builtin), - location=builtin)}) + o, ml, 'end'))}) }), decEs.transform, nilNamedASTExpr()); @@ -718,15 +706,12 @@ top::Exprs ::= e::Expr top.lambdaParams = productionRHSCons( productionRHSElem( - name(lambdaParamName, builtin), '::', - typerepTypeExpr(e.finalType), - location=builtin), - productionRHSNil(), - location=builtin); + name(lambdaParamName), '::', + typerepTypeExpr(e.finalType)), + productionRHSNil()); top.lambdaParamRefs = exprsSingle( - baseExpr(qName(builtin,lambdaParamName)), - location=builtin); + baseExpr(qName(lambdaParamName))); } aspect production exprsCons top::Exprs ::= e1::Expr ',' e2::Exprs @@ -737,16 +722,13 @@ top::Exprs ::= e1::Expr ',' e2::Exprs top.lambdaParams = productionRHSCons( productionRHSElem( - name(lambdaParamName, builtin), '::', - typerepTypeExpr(e1.finalType), - location=builtin), - e2.lambdaParams, - location=builtin); + name(lambdaParamName), '::', + typerepTypeExpr(e1.finalType)), + e2.lambdaParams); top.lambdaParamRefs = exprsCons( baseExpr(qName(lambdaParamName)), - ',', e2.lambdaParamRefs, - location=builtin); + ',', e2.lambdaParamRefs); } attribute transform occurs on AppExpr; diff --git a/grammars/silver/compiler/extension/rewriting/Rewriting.sv b/grammars/silver/compiler/extension/rewriting/Rewriting.sv index 6c0edcc1f..8c1da9798 100644 --- a/grammars/silver/compiler/extension/rewriting/Rewriting.sv +++ b/grammars/silver/compiler/extension/rewriting/Rewriting.sv @@ -29,14 +29,14 @@ concrete production sequenceOperator top::Expr ::= s1::Expr '<*' s2::Expr { top.unparse = s"(${s1.unparse} <* ${s2.unparse})"; - forwards to mkStrFunctionInvocation(top.location, "silver:rewrite:sequence", [s1, s2]); + forwards to mkStrFunctionInvocation("silver:rewrite:sequence", [s1, s2]); } concrete production choiceOperator top::Expr ::= s1::Expr '<+' s2::Expr { top.unparse = s"(${s1.unparse} <+ ${s2.unparse})"; - forwards to mkStrFunctionInvocation(top.location, "silver:rewrite:choice", [s1, s2]); + forwards to mkStrFunctionInvocation("silver:rewrite:choice", [s1, s2]); } @@ -67,7 +67,7 @@ top::Expr ::= 'traverse' n::QName '(' es::AppExprs ',' anns::AnnoAppExprs ')' local transform::Strategy = traversal(n.lookupValue.fullName, es.traverseTransform, anns.traverseTransform); - local fwrd::Expr = translate(builtin, reflect(new(transform))); + local fwrd::Expr = translate(reflect(new(transform))); forwards to if !null(localErrors) then errorExpr(localErrors) else fwrd; } @@ -93,7 +93,7 @@ top::Expr ::= 'traverse' '(' h::AppExpr '::' t::AppExpr ')' top.unparse = s"traverse (${h.unparse} :: ${t.unparse})"; local transform::Strategy = consListCongruence(h.traverseTransform, t.traverseTransform); - forwards to translate(top.location, reflect(new(transform))); + forwards to translate(reflect(new(transform))); } concrete production traverseConsListFirstMissing top::Expr ::= 'traverse' '(' h::'_' '::' t::AppExpr ')' @@ -112,7 +112,7 @@ top::Expr ::= 'traverse' '[' ']' top.unparse = s"traverse []"; local transform::Strategy = nilListCongruence(); - forwards to translate(top.location, reflect(new(transform))); + forwards to translate(reflect(new(transform))); } concrete production traverseList @@ -121,7 +121,7 @@ top::Expr ::= 'traverse' '[' es::AppExprs ']' top.unparse = s"traverse [${es.unparse}]"; local transform::Strategy = foldr(consListCongruence, nilListCongruence(), es.traverseTransform); - forwards to translate(top.location, reflect(new(transform))); + forwards to translate(reflect(new(transform))); } -- Compute our own errors on AnnoAppExprs, since we want to ignore missing annotations (like in patterns) @@ -200,7 +200,10 @@ top::Expr ::= 'rule' 'on' ty::TypeExpr 'of' Opt_Vbar_t ml::MRuleList 'end' -- Find the free type variables (i.e. lacking a definition) to add as skolem constants local freeTyVars::[String] = filter(\ tv::String -> null(getTypeDcl(tv, top.env)), nub(ty.lexicalTypeVariables)); - ty.env = newScopeEnv(addNewLexicalTyVars(top.grammarName, ty.location, [], freeTyVars), top.env); + ty.env = newScopeEnv( + attachNote logicalLocationFromOrigin(ty) on + addNewLexicalTyVars(top.grammarName, [], freeTyVars) + end, top.env); -- Pattern matching error checking (mostly) happens on what caseExpr forwards to, -- so we need to decorate one of those here. @@ -209,8 +212,7 @@ top::Expr ::= 'rule' 'on' ty::TypeExpr 'of' Opt_Vbar_t ml::MRuleList 'end' [hackExprType(ty.typerep)], ml.wrappedMatchRuleList, false, errorExpr([]), - ty.typerep, - location=builtin); + ty.typerep); checkExpr.env = top.env; checkExpr.flowEnv = top.flowEnv; checkExpr.finalSubst = checkExpr.upSubst; -- Not top.finalSubst to avoid circularity @@ -254,7 +256,7 @@ top::Expr ::= 'rule' 'on' ty::TypeExpr 'of' Opt_Vbar_t ml::MRuleList 'end' })) <* ml.transform else ml.transform; - local fwrd::Expr = translate(top.location, reflect(new(transform))); + local fwrd::Expr = translate(reflect(new(transform))); --forwards to unsafeTrace(fwrd, print(top.location.unparse ++ ": " ++ show(80, transform.pp) ++ "\n\n\n", unsafeIO())); forwards to fwrd; diff --git a/grammars/silver/compiler/extension/silverconstruction/Syntax.sv b/grammars/silver/compiler/extension/silverconstruction/Syntax.sv index 404fc3df2..77feba0af 100644 --- a/grammars/silver/compiler/extension/silverconstruction/Syntax.sv +++ b/grammars/silver/compiler/extension/silverconstruction/Syntax.sv @@ -12,42 +12,42 @@ concrete production quoteAGDcl top::Expr ::= 'Silver_AGDcl' '{' ast::AGDcl '}' { top.unparse = s"Silver_AGDcl " ++ substitute("\n"," ", "{${ast.unparse}}"); - forwards to translate(top.location, reflect(new(ast))); + forwards to translate(reflect(new(ast))); } concrete production quoteProductionStmt top::Expr ::= 'Silver_ProductionStmt' '{' ast::ProductionStmt '}' { top.unparse = s"Silver_ProductionStmt" ++ substitute("\n"," ", "{${ast.unparse}}"); - forwards to translate(top.location, reflect(new(ast))); + forwards to translate(reflect(new(ast))); } concrete production quoteExpr top::Expr ::= 'Silver_Expr' '{' ast::Expr '}' { top.unparse = s"Silver_Expr {${ast.unparse}}"; - forwards to translate(top.location, reflect(new(ast))); + forwards to translate(reflect(new(ast))); } concrete production quoteExprInh top::Expr ::= 'Silver_ExprInh' '{' ast::ExprInh '}' { top.unparse = s"Silver_ExprInh {${ast.unparse}}"; - forwards to translate(top.location, reflect(new(ast))); + forwards to translate(reflect(new(ast))); } concrete production quotePattern top::Expr ::= 'Silver_Pattern' '{' ast::Pattern '}' { top.unparse = s"Silver_Pattern {${ast.unparse}}"; - forwards to translate(top.location, reflect(new(ast))); + forwards to translate(reflect(new(ast))); } concrete production quoteTypeExpr top::Expr ::= 'Silver_TypeExpr' '{' ast::TypeExpr '}' { top.unparse = s"Silver_TypeExpr {${ast.unparse}}"; - forwards to translate(top.location, reflect(new(ast))); + forwards to translate(reflect(new(ast))); } concrete production antiquoteExpr diff --git a/grammars/silver/compiler/extension/silverconstruction/Translation.sv b/grammars/silver/compiler/extension/silverconstruction/Translation.sv index a68cc69c5..e6d536c4e 100644 --- a/grammars/silver/compiler/extension/silverconstruction/Translation.sv +++ b/grammars/silver/compiler/extension/silverconstruction/Translation.sv @@ -29,7 +29,6 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs | right(e) -> just( mkFullFunctionInvocation( - givenLocation, baseExpr(qName("silver:compiler:metatranslation:makeQName")), [e, locAST.translation], [])) @@ -44,7 +43,6 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs | right(e) -> just( mkFullFunctionInvocation( - givenLocation, baseExpr(qName("silver:compiler:metatranslation:makeName")), [e, locAST.translation], [])) diff --git a/grammars/silver/compiler/extension/strategyattr/ConcreteSyntax.sv b/grammars/silver/compiler/extension/strategyattr/ConcreteSyntax.sv index 781aca6df..848e92f6b 100644 --- a/grammars/silver/compiler/extension/strategyattr/ConcreteSyntax.sv +++ b/grammars/silver/compiler/extension/strategyattr/ConcreteSyntax.sv @@ -236,6 +236,6 @@ concrete productions top::StrategyExprs_c tracked nonterminal StrategyQName with ast; concrete productions top::StrategyQName (strategyQNameOne) | id::StrategyName_t -{ top.ast = qNameId(name(id.lexeme, id.nameLoc)); } +{ top.ast = qNameId(name(id.lexeme)); } (strategyQNameCons) | id::StrategyName_t ':' qn::StrategyQName -{ top.ast = qNameCons(name(id.lexeme, id.nameLoc), $2, qn.ast); } +{ top.ast = qNameCons(name(id.lexeme), $2, qn.ast); } diff --git a/grammars/silver/compiler/extension/strategyattr/DclInfo.sv b/grammars/silver/compiler/extension/strategyattr/DclInfo.sv index a4a4f1dd0..d8a422a01 100644 --- a/grammars/silver/compiler/extension/strategyattr/DclInfo.sv +++ b/grammars/silver/compiler/extension/strategyattr/DclInfo.sv @@ -44,7 +44,7 @@ top::AttributeDclInfo ::= top.isStrategy = true; top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler(_, _), _, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations top.attributionDispatcher = strategyAttributionDcl; diff --git a/grammars/silver/compiler/extension/strategyattr/Strategy.sv b/grammars/silver/compiler/extension/strategyattr/Strategy.sv index 3bdd02f46..b42f240ed 100644 --- a/grammars/silver/compiler/extension/strategyattr/Strategy.sv +++ b/grammars/silver/compiler/extension/strategyattr/Strategy.sv @@ -42,11 +42,11 @@ top::AGDcl ::= isTotal::Boolean a::Name recVarNameEnv::[Pair] rec strategyDcl( fName, isTotal, !null(top.errors), map(fst, e.liftedStrategies), recVarNameEnv, recVarTotalEnv, e.partialRefs, e.totalRefs, e.containsTraversal, e, - sourceGrammar=top.grammarName, sourceLocation=a.location)))]), + sourceGrammar=top.grammarName)))]), map( \ d::(String, Decorated StrategyExpr with LiftedInhs) -> strategyAttributeDcl( - d.snd.isTotalNoEnv, name(d.fst, top.location), d.snd.recVarNameEnv, d.snd.recVarTotalNoEnvEnv, new(d.snd)), + d.snd.isTotalNoEnv, name(d.fst), d.snd.recVarNameEnv, d.snd.recVarTotalNoEnvEnv, new(d.snd)), e.liftedStrategies)); -- Uncomment for debugging diff --git a/grammars/silver/compiler/extension/strategyattr/StrategyExpr.sv b/grammars/silver/compiler/extension/strategyattr/StrategyExpr.sv index 5180fe521..5ea4bee5e 100644 --- a/grammars/silver/compiler/extension/strategyattr/StrategyExpr.sv +++ b/grammars/silver/compiler/extension/strategyattr/StrategyExpr.sv @@ -367,7 +367,7 @@ top::StrategyExpr ::= s::StrategyExpr else Silver_Expr { $name{a.fst} }, childAccesses), map( - makeAnnoArg(top.location, top.frame.signature.outputElement.elementName, _), + makeAnnoArg(top.frame.signature.outputElement.elementName, _), top.frame.signature.namedInputElements))}) })], false, @@ -379,7 +379,6 @@ top::StrategyExpr ::= s::StrategyExpr {- When s is total, optimized translation of all(s) for prod::(Foo ::= a::Foo b::Integer c::Bar): prod(a.s, b, c.s) -} mkFullFunctionInvocation( - top.location, baseExpr(qName(top.frame.fullName)), map( \ a::Pair -> @@ -388,7 +387,7 @@ top::StrategyExpr ::= s::StrategyExpr else Silver_Expr { $name{a.fst} }, childAccesses), map( - makeAnnoArg(top.location, top.frame.signature.outputElement.elementName, _), + makeAnnoArg(top.frame.signature.outputElement.elementName, _), top.frame.signature.namedInputElements)) else asTotal(top.frame.signature.outputElement.typerep, top.partialTranslation); } @@ -449,7 +448,7 @@ top::StrategyExpr ::= s::StrategyExpr else Silver_Expr { $name{a.fst} }, childAccesses), map( - makeAnnoArg(top.location, top.frame.signature.outputElement.elementName, _), + makeAnnoArg(top.frame.signature.outputElement.elementName, _), top.frame.signature.namedInputElements))}) else silver:core:nothing() }; @@ -468,7 +467,7 @@ top::StrategyExpr ::= s::StrategyExpr else Silver_Expr { $name{a.fst} }, childAccesses), map( - makeAnnoArg(top.location, top.frame.signature.outputElement.elementName, _), + makeAnnoArg(top.frame.signature.outputElement.elementName, _), top.frame.signature.namedInputElements)) else asTotal(top.frame.signature.outputElement.typerep, top.partialTranslation); } @@ -544,7 +543,7 @@ top::StrategyExpr ::= s::StrategyExpr \ a::Pair -> Silver_Expr { $name{a.fst} }, drop(childIndex + 1, childAccesses)), map( - makeAnnoArg(top.location, top.frame.signature.outputElement.elementName, _), + makeAnnoArg(top.frame.signature.outputElement.elementName, _), top.frame.signature.namedInputElements))}) }) end end, @@ -567,7 +566,7 @@ top::StrategyExpr ::= s::StrategyExpr else Silver_Expr { $name{a.fst} }, childAccesses), map( - makeAnnoArg(top.location, top.frame.signature.outputElement.elementName, _), + makeAnnoArg(top.frame.signature.outputElement.elementName, _), top.frame.signature.namedInputElements)) else asTotal(top.frame.signature.outputElement.typerep, top.partialTranslation); } @@ -642,7 +641,7 @@ top::StrategyExpr ::= prod::QName s::StrategyExprs end, childAccesses), map( - makeAnnoArg(top.location, top.frame.signature.outputElement.elementName, _), + makeAnnoArg(top.frame.signature.outputElement.elementName, _), top.frame.signature.namedInputElements))}) })], false, @@ -1046,7 +1045,7 @@ function attrMatchesFrame Boolean ::= env::Env attrName::String attrFor::Type { return - decorate qNameAttrOccur(qName(loc("", -1, -1, -1, -1, -1, -1), attrName)("", -1, -1, -1, -1, -1, -1)) + decorate qNameAttrOccur(qName(attrName)) with { env = env; attrFor = attrFor; }.matchesFrame; } diff --git a/grammars/silver/compiler/extension/strategyattr/construction/Construction.sv b/grammars/silver/compiler/extension/strategyattr/construction/Construction.sv index 765d5d159..62e10fe23 100644 --- a/grammars/silver/compiler/extension/strategyattr/construction/Construction.sv +++ b/grammars/silver/compiler/extension/strategyattr/construction/Construction.sv @@ -33,7 +33,7 @@ top::Expr ::= 'Silver_StrategyExpr' '(' genName::Expr ')' '{' cst::StrategyExpr_ | annoExpr(n, _, presentAppExpr(e)) when n.name == "genName" -> annoExpr(n, '=', presentAppExpr(plusPlus(genName, '++', e))) end), - translate(top.location, reflect(cst.ast))).fromJust; + translate(reflect(cst.ast))).fromJust; } concrete production antiquoteStrategyExpr_c diff --git a/grammars/silver/compiler/extension/strategyattr/convenience/Convenience.sv b/grammars/silver/compiler/extension/strategyattr/convenience/Convenience.sv index ba08700bf..36f4c011e 100644 --- a/grammars/silver/compiler/extension/strategyattr/convenience/Convenience.sv +++ b/grammars/silver/compiler/extension/strategyattr/convenience/Convenience.sv @@ -15,7 +15,7 @@ top::AGDcl ::= 'partial' 'strategy' 'attribute' a::Name '=' e::StrategyExpr_c 'o forwards to appendAGDcl( partialStrategyAttributeDcl($1, $2, $3, a, $5, e, $10), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(a), botlNone()), qs.qnames)); + makeOccursDclsHelp(qNameWithTL(qNameId(a), botlNone()), qs.qnames)); } concrete production totalStrategyAttributeDclMultiple @@ -25,5 +25,5 @@ top::AGDcl ::= 'strategy' 'attribute' a::Name '=' e::StrategyExpr_c 'occurs' 'on forwards to appendAGDcl( totalStrategyAttributeDcl($1, $2, a, $4, e, $9), - makeOccursDclsHelp($1.location, qNameWithTL(qNameId(a), botlNone()), qs.qnames)); + makeOccursDclsHelp(qNameWithTL(qNameId(a), botlNone()), qs.qnames)); } diff --git a/grammars/silver/compiler/extension/templating/StringTemplating.sv b/grammars/silver/compiler/extension/templating/StringTemplating.sv index ab3382bfa..345cda882 100644 --- a/grammars/silver/compiler/extension/templating/StringTemplating.sv +++ b/grammars/silver/compiler/extension/templating/StringTemplating.sv @@ -104,7 +104,7 @@ top::TemplateString ::= b::TemplateStringBody _ aspect production templateStringEmpty top::TemplateString ::= _ { - top.stringTemplate = [stringConst(terminal(String_t, "\"\"", top.location))]; + top.stringTemplate = [Silver_Expr { "" }]; top.ppTemplate = notext(); } @@ -118,7 +118,7 @@ top::SingleLineTemplateString ::= b::SingleLineTemplateStringBody _ aspect production singleLineTemplateStringEmpty top::SingleLineTemplateString ::= _ { - top.stringTemplate = [stringConst(terminal(String_t, "\"\"", top.location))]; + top.stringTemplate = [Silver_Expr { "" }]; top.ppTemplate = notext(); } @@ -139,7 +139,7 @@ top::TemplateStringBody ::= h::TemplateStringBodyItem aspect production bodyOneWater top::TemplateStringBody ::= w::Water { - top.stringTemplate = [stringConst(terminal(String_t, "\"" ++ w.waterString ++ "\"", w.location))]; + top.stringTemplate = [stringConst(terminal(String_t, "\"" ++ w.waterString ++ "\""))]; top.ppTemplate = w.waterDoc; } @@ -160,7 +160,7 @@ top::SingleLineTemplateStringBody ::= h::SingleLineTemplateStringBodyItem aspect production singleLineBodyOneWater top::SingleLineTemplateStringBody ::= w::SingleLineWater { - top.stringTemplate = [stringConst(terminal(String_t, "\"" ++ w.waterString ++ "\"", w.location))]; + top.stringTemplate = [stringConst(terminal(String_t, "\"" ++ w.waterString ++ "\""))]; top.ppTemplate = w.waterDoc; } @@ -168,7 +168,7 @@ aspect production itemWaterEscape top::TemplateStringBodyItem ::= w::Water nw::NonWater { top.stringTemplate = [ - stringConst(terminal(String_t, "\"" ++ w.waterString ++ "\"", w.location))] ++ + stringConst(terminal(String_t, "\"" ++ w.waterString ++ "\""))] ++ nw.stringTemplate; top.ppTemplate = cat(w.waterDoc, nw.ppTemplate); } @@ -184,7 +184,7 @@ aspect production singleLineItemWaterEscape top::SingleLineTemplateStringBodyItem ::= w::SingleLineWater nw::NonWater { top.stringTemplate = [ - stringConst(terminal(String_t, "\"" ++ w.waterString ++ "\"", w.location))] ++ + stringConst(terminal(String_t, "\"" ++ w.waterString ++ "\""))] ++ nw.stringTemplate; top.ppTemplate = cat(w.waterDoc, nw.ppTemplate); } @@ -200,5 +200,5 @@ aspect production nonwater top::NonWater ::= '${' e::Expr '}' { top.stringTemplate = [e]; - top.ppTemplate = antiquoteDoc(mkStrFunctionInvocation(top.location, "silver:langutil:pp:pp", [e])); + top.ppTemplate = antiquoteDoc(mkStrFunctionInvocation("silver:langutil:pp:pp", [e])); } diff --git a/grammars/silver/compiler/extension/testing/EqualityTest.sv b/grammars/silver/compiler/extension/testing/EqualityTest.sv index 03f2ecd5e..9e5187db9 100644 --- a/grammars/silver/compiler/extension/testing/EqualityTest.sv +++ b/grammars/silver/compiler/extension/testing/EqualityTest.sv @@ -48,7 +48,7 @@ ag::AGDcl ::= kwd::'equalityTest' local eqCtx::Context = instContext("silver:core:Eq", valueType.typerep); eqCtx.env = ag.env; - eqCtx.contextLoc = valueType.location; + eqCtx.contextLoc = getParsedOriginLocationOrFallback(valueType); eqCtx.contextSource = "equalityTest"; eqCtx.frame = value.frame; eqCtx.config = ag.config; @@ -129,7 +129,7 @@ ag::AGDcl ::= kwd::'equalityTest' -- TODO: BUG: FIXME: these names should be mangled. I ran into 't' being shadowed in a test I wrote! local tref :: Name = name("t"); - local testNameref :: Name = name(testName, ag.location); + local testNameref :: Name = name(testName); local valueref :: Name = name("value"); local expectedref :: Name = name("expected"); local msgref :: Name = name("msg"); @@ -141,7 +141,7 @@ ag::AGDcl ::= kwd::'equalityTest' productionSignature( nilConstraint(), '=>', productionLHS(tref, '::', - nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "Test", ag.location)))), + nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "Test")))), '::=', productionRHSNil()), productionBody('{', foldl(productionStmtsSnoc(_, _), productionStmtsNil(), [ localAttributeDcl('local', 'attribute', valueref, '::', valueType, ';'), @@ -150,7 +150,7 @@ ag::AGDcl ::= kwd::'equalityTest' valueEq(qNameId(expectedref), '=', expected, ';'), attributeDef(concreteDefLHS(qNameId(tref)), '.', qNameAttrOccur(qNameId(msgref)), '=', foldStringExprs([ - strCnst("Test at " ++ ag.location.unparse ++ " failed.\nChecking that expression\n " ++ + strCnst("Test at " ++ getParsedOriginLocationOrFallback(ag).unparse ++ " failed.\nChecking that expression\n " ++ stringifyString(value.unparse) ++ "\nshould be same as expression\n " ++ stringifyString(expected.unparse) ++ "\nActual value:\n "), Silver_Expr { silver:testing:showTestValue(value) }, @@ -159,7 +159,7 @@ ag::AGDcl ::= kwd::'equalityTest' strCnst("\n")]), ';'), attributeDef(concreteDefLHS(qNameId(tref)), '.', qNameAttrOccur(qNameId(passref)), '=', Silver_Expr { value == expected }, ';'), - forwardsTo('forwards', 'to', mkStrFunctionInvocation(ag.location, "defTest", []), ';')]), '}')); + forwardsTo('forwards', 'to', mkStrFunctionInvocation("defTest", []), ';')]), '}')); {- local aspProdCS :: AGDcl = asAGDcl ( diff --git a/grammars/silver/compiler/extension/testing/Helper.sv b/grammars/silver/compiler/extension/testing/Helper.sv index 09a4770e7..3e74b8cb4 100644 --- a/grammars/silver/compiler/extension/testing/Helper.sv +++ b/grammars/silver/compiler/extension/testing/Helper.sv @@ -22,15 +22,15 @@ function foldStringExprs Expr ::= es::[Expr] { return if null(es) - then stringConst(terminal(String_t, "\"\""), location=bogusLoc()) - else plusPlus(head(es), '++', foldStringExprs(tail(es)), location=head(es).location); + then stringConst(terminal(String_t, "\"\"")) + else plusPlus(head(es), '++', foldStringExprs(tail(es))); } -- Create an Expr that is a string constant from a string. function strCnst Expr ::= s::String { - return stringConst(terminal(String_t, "\"" ++ stringifyString(s) ++ "\""), location=bogusLoc()); + return stringConst(terminal(String_t, "\"" ++ stringifyString(s) ++ "\"")); } -- Create an attribute reference from two names. as in "n.a" diff --git a/grammars/silver/compiler/extension/testing/MainTestSuite.sv b/grammars/silver/compiler/extension/testing/MainTestSuite.sv index c976d3224..79b57a8fb 100644 --- a/grammars/silver/compiler/extension/testing/MainTestSuite.sv +++ b/grammars/silver/compiler/extension/testing/MainTestSuite.sv @@ -22,13 +22,13 @@ top::AGDcl ::= 'makeTestSuite' nme::IdLower_t ';' productionSignature( nilConstraint(), '=>', productionLHS(name("t"), '::', - nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "TestSuite", top.location)))), + nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "TestSuite")))), '::=', productionRHSNil()); local bod :: [ProductionStmt] = - [forwardsTo('forwards', 'to', mkStrFunctionInvocation(top.location, "testsAsNT", [mkNameExpr("testsToPerform", top.location)]), ';'), + [forwardsTo('forwards', 'to', mkStrFunctionInvocation(top.location, "testsAsNT", [mkNameExpr("testsToPerform")]), ';'), collectionAttributeDclProd('production', 'attribute', name("testsToPerform"), '::', - listTypeExpr('[', nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "Test", top.location))), ']'), + listTypeExpr('[', nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "Test"))), ']'), 'with', plusplusOperator('++'), ';'), valContainsBase(qName("testsToPerform"), ':=', emptyList('[',']'), ';') ]; @@ -64,7 +64,7 @@ top::AGDcl ::= 'mainTestSuite' nme::IdLower_t ';' nilConstraint(), '=>', functionLHS( appTypeExpr( - nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "IOVal", top.location))), + nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "IOVal"))), bTypeList('<', typeListSingle(integerTypeExpr('Integer')), '>'))), '::=', productionRHSCons( @@ -80,7 +80,7 @@ top::AGDcl ::= 'mainTestSuite' nme::IdLower_t ';' -- local testResults :: TestSuite; localAttributeDcl( 'local', 'attribute', name("testResults"), '::', - nominalTypeExpr( qNameTypeId(terminal(IdUpper_t,"TestSuite", top.location))), ';'), + nominalTypeExpr( qNameTypeId(terminal(IdUpper_t,"TestSuite"))), ';'), -- testResults = name() valueEq( qName("testResults"), '=', applicationEmpty( baseExpr( qNameId(nameIdLower(nme))), @@ -89,19 +89,19 @@ top::AGDcl ::= 'mainTestSuite' nme::IdLower_t ';' -- testResults.ioIn = ... attributeDef( concreteDefLHS( qName("testResults")), '.', qNameAttrOccur(qName("ioIn")), - '=', mkNameExpr("mainIO", top.location), ';'), + '=', mkNameExpr("mainIO"), ';'), -- return ... returnDef('return', mkStrFunctionInvocation(top.location, "ioval", [ mkStrFunctionInvocation(top.location, "exitT", - [ attrAcc("testResults","numFailed", top.location), + [ attrAcc("testResults","numFailed"), mkStrFunctionInvocation(top.location, "printT", [ foldStringExprs( [ strCnst("\n\n"), strCnst("============================================================\n"), strCnst("Test Results:\n"), - attrAcc("testResults","msg", top.location), + attrAcc("testResults","msg"), strCnst("\n\n"), strCnst("Passed "), Silver_Expr { silver:core:integerToString(testResults.numPassed) }, @@ -110,10 +110,10 @@ top::AGDcl ::= 'mainTestSuite' nme::IdLower_t ';' strCnst("\n"), strCnst("============================================================\n") ]), - attrAcc("testResults", "ioOut", top.location) + attrAcc("testResults", "ioOut") ]) ]), - intConst( terminal(Int_t, "0", top.location)) + intConst( terminal(Int_t, "0")) ]), ';') ]), '}')), diff --git a/grammars/silver/compiler/extension/treegen/Arbitrary.sv b/grammars/silver/compiler/extension/treegen/Arbitrary.sv index 8b1a3fe52..c0277e890 100644 --- a/grammars/silver/compiler/extension/treegen/Arbitrary.sv +++ b/grammars/silver/compiler/extension/treegen/Arbitrary.sv @@ -27,7 +27,7 @@ top::AGDcl ::= 'generator' n::Name '::' t::TypeExpr '{' grammars::GeneratorCompo -- Compute the defs exported by the specified grammars local med::ModuleExportedDefs = moduleExportedDefs( - top.location, top.compiledGrammars, top.grammarDependencies, + top.compiledGrammars, top.grammarDependencies, grammars.moduleNames, []); production specEnv::Env = newScopeEnv(med.defs, emptyEnv()); @@ -37,7 +37,7 @@ top::AGDcl ::= 'generator' n::Name '::' t::TypeExpr '{' grammars::GeneratorCompo -- function and refer to its production attributes, which is probably good anyway. top.defs := case forward of - | functionDcl(_, _, ns, _) -> [funDef(top.grammarName, n.location, ns.namedSignature)] + | functionDcl(_, _, ns, _) -> [funDef(top.grammarName, n.nameLoc, ns.namedSignature)] | _ -> error("forward should be a function") end; @@ -51,7 +51,7 @@ top::AGDcl ::= 'generator' n::Name '::' t::TypeExpr '{' grammars::GeneratorCompo top.moduleNames <- implicitImports; local extraMED::ModuleExportedDefs = moduleExportedDefs( - top.location, top.compiledGrammars, top.grammarDependencies, + top.compiledGrammars, top.grammarDependencies, "silver:core" :: implicitImports, []); -- Generator components must be imported for the translation here, @@ -74,9 +74,9 @@ top::AGDcl ::= 'generator' n::Name '::' t::TypeExpr '{' grammars::GeneratorCompo foldr( productionStmtAppend(_, _), errorProductionStmt([]), -- TODO: No nullProductionStmt? - map(genNtLocalDecl(top.location, forward.env, specEnv, _), map((.fullName), syntax.allNonterminals)) ++ - map(genTermLocalDecl(top.location, forward.env, specEnv, syntax.dominatingTerminals, _), map((.fullName), syntax.allTerminals)))} - return $Expr{genForType(top.location, forward.env, specEnv, Silver_Expr { 0 }, t.typerep)}; + map(genNtLocalDecl(forward.env, specEnv, _), map((.fullName), syntax.allNonterminals)) ++ + map(genTermLocalDecl(forward.env, specEnv, syntax.dominatingTerminals, _), map((.fullName), syntax.allTerminals)))} + return $Expr{genForType(forward.env, specEnv, Silver_Expr { 0 }, t.typerep)}; } }; @@ -109,7 +109,7 @@ top::GeneratorComponent ::= m::ModuleName ';' -- Generate the expression for constructing a type function genForType -Expr ::= loc::Location env::Env specEnv::Env depth::Expr t::Type +Expr ::= env::Env specEnv::Env depth::Expr t::Type { return case t of @@ -117,11 +117,11 @@ Expr ::= loc::Location env::Env specEnv::Env depth::Expr t::Type -- call the appropriate local generator function. | nonterminalType(ntName, [], _, _) when (getTypeDcl(ntName, specEnv), getInstanceDcl("silver:util:random:Arbitrary", t, env)) - matches (dcl :: _, []) -> Silver_Expr { $Name{name("gen_" ++ substitute(":", "_", ntName), loc)}($Expr{depth}) } + matches (dcl :: _, []) -> Silver_Expr { $Name{name("gen_" ++ substitute(":", "_", ntName))}($Expr{depth}) } | terminalType(tName) when (getTypeDcl(tName, specEnv), getInstanceDcl("silver:util:random:Arbitrary", t, env)) - matches (dcl :: _, []) -> Silver_Expr { $Name{name("gen_" ++ substitute(":", "_", tName), loc)}($Expr{depth}) } + matches (dcl :: _, []) -> Silver_Expr { $Name{name("gen_" ++ substitute(":", "_", tName))}($Expr{depth}) } -- Lists are handled specially here, to allow recusively generating for -- e.g. lists of nonterminals in a production RHS. @@ -129,13 +129,13 @@ Expr ::= loc::Location env::Env specEnv::Env depth::Expr t::Type Silver_Expr { silver:core:bind(silver:util:random:randomRange(0, $Expr{depth}), \ len::Integer -> silver:core:traverseA( - \ depth::Integer -> $Expr{genForType(loc, env, specEnv, Silver_Expr { depth - 1 }, elemT)}, + \ depth::Integer -> $Expr{genForType(env, specEnv, Silver_Expr { depth - 1 }, elemT)}, silver:core:take(len, silver:core:reverse(silver:core:range(0, $Expr{depth}))))) } -- Primitives and polymorphic nonterminals (e.g. Pair for tuples) are -- handled by the Arbitrary type class. - | _ -> Silver_Expr { $Name{name("silver:util:random:genArb", loc)}($Expr{depth}) } + | _ -> Silver_Expr { $Name{name("silver:util:random:genArb")}($Expr{depth}) } end; } @@ -197,7 +197,7 @@ function takeWhile2 -- local genExpr::(RandomGen ::= Integer) = \ depth::Integer -> ...; function genNtLocalDecl -ProductionStmt ::= loc::Location env::Env specEnv::Env nt::String +ProductionStmt ::= env::Env specEnv::Env nt::String { -- All productions that are generatable for nt, sorted by arity local prods :: [ValueDclInfo] = @@ -224,7 +224,7 @@ ProductionStmt ::= loc::Location env::Env specEnv::Env nt::String $Expr{intConst(terminal(Int_t, toString(length(prods) - 1)))}) -- All productions else randomRange(0, $Expr{intConst(terminal(Int_t, toString(length(prods) - 1)))}), - \ i::Integer -> $Expr{generateExprChain(loc, env, specEnv, nt, 0, prods)}) + \ i::Integer -> $Expr{generateExprChain(env, specEnv, nt, 0, prods)}) }; return @@ -235,7 +235,7 @@ ProductionStmt ::= loc::Location env::Env specEnv::Env nt::String } function genTermLocalDecl -ProductionStmt ::= loc::Location env::Env specEnv::Env dominatingTerminals::EnvTree t::String +ProductionStmt ::= env::Env specEnv::Env dominatingTerminals::EnvTree t::String { local te::TypeExpr = nominalTypeExpr(qName(t).qNameType); @@ -260,7 +260,7 @@ ProductionStmt ::= loc::Location env::Env specEnv::Env dominatingTerminals::E falseConst('false'), map( \ term::Decorated SyntaxDcl -> Silver_Expr { - silver:regex:matches($Expr{translate(loc, reflect(term.terminalRegex))}, term.lexeme) + silver:regex:matches($Expr{translate(reflect(term.terminalRegex))}, term.lexeme) }, searchEnvTree(t, dominatingTerminals))); return @@ -287,7 +287,7 @@ Note that this expects lst to be non-empty! -} function generateExprChain -Expr ::= loc::Location env::Env specEnv::Env nt::String index::Integer lst::[ValueDclInfo] +Expr ::= env::Env specEnv::Env nt::String index::Integer lst::[ValueDclInfo] { local prod::ValueDclInfo = head(lst); local prodType::Type = prod.typeScheme.typerep; @@ -295,10 +295,10 @@ Expr ::= loc::Location env::Env specEnv::Env nt::String index::Integer lst::[ zip(map(\ i::Integer -> "a" ++ toString(i), range(0, length(prodType.inputTypes))), prodType.inputTypes) ++ prodType.namedTypes; local argGenExprs::[Expr] = - map(genForType(loc, env, specEnv, Silver_Expr { depth + 1 }, _), map(snd, args)); + map(genForType(env, specEnv, Silver_Expr { depth + 1 }, _), map(snd, args)); local genRes::Expr = mkFullFunctionInvocation( - loc, Silver_Expr { $name{prod.fullName} }, + Silver_Expr { $name{prod.fullName} }, map(\ i::Integer -> Silver_Expr { $name{"a" ++ toString(i)} }, range(0, length(prodType.inputTypes))), map(\ a::String -> (a, Silver_Expr { $name{a} }), map(fst, prodType.namedTypes))); local lambdaChain::Expr = @@ -318,6 +318,6 @@ Expr ::= loc::Location env::Env specEnv::Env nt::String index::Integer lst::[ else Silver_Expr { if i == $Expr{intConst(terminal(Int_t, toString(index)))} then $Expr{genProd} - else $Expr{generateExprChain(loc, env, specEnv, nt, index + 1, tail(lst))} + else $Expr{generateExprChain(env, specEnv, nt, index + 1, tail(lst))} }; } diff --git a/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv b/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv index 74ded81cf..19b3c165c 100644 --- a/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv +++ b/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv @@ -159,7 +159,7 @@ top::VarBinder ::= n::Name else []; -- Unique refs are forbidden in the scrutinee. - top.defs <- [lexicalLocalDef(top.grammarName, n.location, fName, ty, vt, deps, [])]; + top.defs <- [lexicalLocalDef(top.grammarName, n.nameLoc, fName, ty, vt, deps, [])]; top.boundNames <- [n.name]; top.translation = From b0fab3687a7c33b95514721fd4f0ed3e0fda19e2 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 28 Sep 2023 15:03:51 -0500 Subject: [PATCH 042/283] Removing location in modifications and translation --- .../modification/collection/Collection.sv | 30 +++++++++---------- .../modification/collection/DclInfo.sv | 14 ++++----- .../modification/copper/ActionCode.sv | 6 ++-- .../copper/DisambiguationGroup.sv | 5 ++-- .../compiler/modification/copper/Env.sv | 4 +-- .../modification/copper/LexerClass.sv | 10 +++---- .../modification/copper/ParserAttributes.sv | 6 ++-- .../compiler/modification/copper/ParserDcl.sv | 4 +-- .../compiler/modification/copper/Prefix.sv | 21 ++++++------- .../modification/copper/ProductionStmt.sv | 2 +- .../compiler/modification/copper/TermList.sv | 2 +- .../modification/copper_mda/Analysis.sv | 8 ++--- .../modification/defaultattr/DefaultAttr.sv | 4 +-- .../compiler/modification/lambda_fn/Lambda.sv | 4 +-- .../modification/lambda_fn/java/Lambda.sv | 2 +- .../silver/compiler/modification/list/List.sv | 26 ++++------------ .../primitivepattern/PrimitiveMatch.sv | 12 ++++---- .../compiler/translation/java/core/Origins.sv | 3 +- .../translation/java/core/ProductionDcl.sv | 2 +- 19 files changed, 75 insertions(+), 90 deletions(-) diff --git a/grammars/silver/compiler/modification/collection/Collection.sv b/grammars/silver/compiler/modification/collection/Collection.sv index b85c0fe17..7fdb426ac 100644 --- a/grammars/silver/compiler/modification/collection/Collection.sv +++ b/grammars/silver/compiler/modification/collection/Collection.sv @@ -163,7 +163,7 @@ top::AGDcl ::= 'synthesized' 'attribute' a::Name tl::BracketedOptTypeExprs '::' q.operatorForType = te.typerep; q.env = top.env; - top.defs := [synColDef(top.grammarName, a.location, fName, tl.freeVariables, te.typerep, q.operation)]; + top.defs := [synColDef(top.grammarName, a.nameLoc, fName, tl.freeVariables, te.typerep, q.operation)]; top.errors <- tl.errorsTyVars; top.errors <- te.errorsKindStar; @@ -190,7 +190,7 @@ top::AGDcl ::= 'inherited' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te q.operatorForType = te.typerep; q.env = top.env; - top.defs := [inhColDef(top.grammarName, a.location, fName, tl.freeVariables, te.typerep, q.operation)]; + top.defs := [inhColDef(top.grammarName, a.nameLoc, fName, tl.freeVariables, te.typerep, q.operation)]; top.errors <- tl.errorsTyVars; top.errors <- te.errorsKindStar; @@ -208,7 +208,7 @@ top::ProductionStmt ::= 'production' 'attribute' a::Name '::' te::TypeExpr 'with top.unparse = "production attribute " ++ a.name ++ " :: " ++ te.unparse ++ " with " ++ q.unparse ++ " ;" ; propagate config, grammarName, compiledGrammars, env, flowEnv; - top.productionAttributes := [localColDef(top.grammarName, a.location, fName, te.typerep, q.operation)]; + top.productionAttributes := [localColDef(top.grammarName, a.nameLoc, fName, te.typerep, q.operation)]; production attribute fName :: String; fName = top.frame.fullName ++ ":local:" ++ top.grammarName ++ ":" ++ a.name; @@ -377,9 +377,9 @@ top::ProductionStmt ::= dl::DefLHS '.' attr::QNameAttrOccur '<-' e::Expr ';' attr.attrFor = dl.typerep; forwards to - (if !dl.found || !attr.found - then errorAttributeDef(dl.errors ++ attr.errors, _, _, _) - else attr.attrDcl.attrAppendDefDispatcher)(dl, attr, e, top.location); + if !dl.found || !attr.found + then errorAttributeDef(dl.errors ++ attr.errors, dl, attr, e) + else attr.attrDcl.attrAppendDefDispatcher(dl, attr, e); } concrete production attrContainsBase @@ -396,9 +396,9 @@ top::ProductionStmt ::= dl::DefLHS '.' attr::QNameAttrOccur ':=' e::Expr ';' attr.attrFor = dl.typerep; forwards to - (if !dl.found || !attr.found - then errorAttributeDef(dl.errors ++ attr.errors, _, _, _) - else attr.attrDcl.attrBaseDefDispatcher)(dl, attr, e, top.location); + if !dl.found || !attr.found + then errorAttributeDef(dl.errors ++ attr.errors, dl, attr, e) + else attr.attrDcl.attrBaseDefDispatcher(dl, attr, e); } concrete production valContainsAppend @@ -413,9 +413,9 @@ top::ProductionStmt ::= val::QName '<-' e::Expr ';' top.defs := []; forwards to - (if null(val.lookupValue.dcls) - then errorValueDef(_, _) - else val.lookupValue.dcl.appendDefDispatcher)(val, e, top.location); + if null(val.lookupValue.dcls) + then errorValueDef(val, e) + else val.lookupValue.dcl.appendDefDispatcher(val, e); } concrete production valContainsBase @@ -430,8 +430,8 @@ top::ProductionStmt ::= val::QName ':=' e::Expr ';' top.defs := []; forwards to - (if null(val.lookupValue.dcls) - then errorValueDef(_, _) - else val.lookupValue.dcl.baseDefDispatcher)(val, e, top.location); + if null(val.lookupValue.dcls) + then errorValueDef(val, e) + else val.lookupValue.dcl.baseDefDispatcher(val, e); } diff --git a/grammars/silver/compiler/modification/collection/DclInfo.sv b/grammars/silver/compiler/modification/collection/DclInfo.sv index 862579aa6..9b81d09b8 100644 --- a/grammars/silver/compiler/modification/collection/DclInfo.sv +++ b/grammars/silver/compiler/modification/collection/DclInfo.sv @@ -47,7 +47,7 @@ top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type o::Operation top.operation = o; top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = collectionAttrDefError; top.attributionDispatcher = defaultAttributionDcl; @@ -105,16 +105,16 @@ top::ValueDclInfo ::= fn::String ty::Type o::Operation } global nonCollectionAttrBaseDefError::(ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr) = - \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr l::Location -> - errorAttributeDef([err(l, "The ':=' operator can only be used for collections. " ++ attr.name ++ " is not a collection.")], dl, attr, e); + \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr -> + errorAttributeDef([errFromOrigin(ambientOrigin(), "The ':=' operator can only be used for collections. " ++ attr.name ++ " is not a collection.")], dl, attr, e); global nonCollectionAttrAppendDefError::(ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr) = - \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr l::Location -> - errorAttributeDef([err(l, "The '<-' operator can only be used for collections. " ++ attr.name ++ " is not a collection.")], dl, attr, e); + \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr -> + errorAttributeDef([errFromOrigin(ambientOrigin(), "The '<-' operator can only be used for collections. " ++ attr.name ++ " is not a collection.")], dl, attr, e); global collectionAttrDefError::(ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr) = - \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr l::Location -> - errorAttributeDef([err(l, attr.name ++ " is a collection attribute, and you must use ':=' or '<-', not '='.")], dl, attr, e); + \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr -> + errorAttributeDef([errFromOrigin(ambientOrigin(), attr.name ++ " is a collection attribute, and you must use ':=' or '<-', not '='.")], dl, attr, e); -- Defs diff --git a/grammars/silver/compiler/modification/copper/ActionCode.sv b/grammars/silver/compiler/modification/copper/ActionCode.sv index b6e628470..160d7537e 100644 --- a/grammars/silver/compiler/modification/copper/ActionCode.sv +++ b/grammars/silver/compiler/modification/copper/ActionCode.sv @@ -12,7 +12,9 @@ top::AGDcl ::= 'concrete' 'production' id::Name ns::ProductionSignature pm::Prod top.syntaxAst := [ syntaxProduction(ns.namedSignature, - foldr(consProductionMod, nilProductionMod(), prodAction(acode.actionCode) :: pm.productionModifiers), sourceGrammar=top.grammarName) + foldr(consProductionMod, nilProductionMod(), prodAction(acode.actionCode) :: pm.productionModifiers), + sourceGrammar=top.grammarName, + location=id.nameLoc) ]; -- oh no again! @@ -148,5 +150,5 @@ top::ProductionRHS ::= h::ProductionRHSElem t::ProductionRHS aspect production productionRHSElem top::ProductionRHSElem ::= id::Name '::' t::TypeExpr { - top.actionDefs = [actionChildDef(top.grammarName, t.location, id.name, t.typerep)]; + top.actionDefs = [actionChildDef(top.grammarName, id.nameLoc, id.name, t.typerep)]; } diff --git a/grammars/silver/compiler/modification/copper/DisambiguationGroup.sv b/grammars/silver/compiler/modification/copper/DisambiguationGroup.sv index 10d17c5e8..a3ff6c902 100644 --- a/grammars/silver/compiler/modification/copper/DisambiguationGroup.sv +++ b/grammars/silver/compiler/modification/copper/DisambiguationGroup.sv @@ -12,7 +12,8 @@ top::AGDcl ::= 'disambiguate' terms::TermList acode::ActionCode_c acode.env = newScopeEnv(disambiguationActionVars ++ acode.defs ++ terms.defs, top.env); -- Give the group a name, deterministically, based on line number - production fName :: String = top.grammarName ++ ":__disam" ++ toString(top.location.line); + local loc :: Location = getParsedOriginLocation(top).fromJust; + production fName :: String = top.grammarName ++ ":__disam" ++ toString(loc.line); -- oh no again! local myFlow :: EnvTree = head(searchEnvTree(top.grammarName, top.compiledGrammars)).grammarFlowTypes; @@ -24,6 +25,6 @@ top::AGDcl ::= 'disambiguate' terms::TermList acode::ActionCode_c acode.frame = disambiguationContext(myFlowGraph, sourceGrammar=top.grammarName); top.syntaxAst := - [ syntaxDisambiguationGroup(fName, terms.termList, false, acode.actionCode, sourceGrammar=top.grammarName) + [ syntaxDisambiguationGroup(fName, terms.termList, false, acode.actionCode, sourceGrammar=top.grammarName, location=loc) ]; } diff --git a/grammars/silver/compiler/modification/copper/Env.sv b/grammars/silver/compiler/modification/copper/Env.sv index 8ccc49119..0dfbdf088 100644 --- a/grammars/silver/compiler/modification/copper/Env.sv +++ b/grammars/silver/compiler/modification/copper/Env.sv @@ -124,13 +124,13 @@ synthesized attribute lookupLexerClass :: QNameLookup occurs on QN aspect production qNameId top::QName ::= id::Name { - top.lookupLexerClass = customLookup("lexer class", getLexerClassDcl(top.name, top.env), top.name, top.location); + top.lookupLexerClass = customLookup("lexer class", getLexerClassDcl(top.name, top.env), top.name); } aspect production qNameCons top::QName ::= id::Name ':' qn::QName { - top.lookupLexerClass = customLookup("lexer class", getLexerClassDcl(top.name, top.env), top.name, top.location); + top.lookupLexerClass = customLookup("lexer class", getLexerClassDcl(top.name, top.env), top.name); } aspect production qNameError diff --git a/grammars/silver/compiler/modification/copper/LexerClass.sv b/grammars/silver/compiler/modification/copper/LexerClass.sv index 948b7593e..11eb6a01f 100644 --- a/grammars/silver/compiler/modification/copper/LexerClass.sv +++ b/grammars/silver/compiler/modification/copper/LexerClass.sv @@ -34,7 +34,7 @@ top::AGDcl ::= 'lexer' 'class' id::Name modifiers::LexerClassModifiers ';' top.syntaxAst := [ syntaxLexerClass(fName, foldr(consLexerClassMod, nilLexerClassMod(), modifiers.lexerClassModifiers), - location=top.location, sourceGrammar=top.grammarName)]; + location=id.nameLoc, sourceGrammar=top.grammarName)]; } action { insert semantic token IdLexerClassDcl_t at id.nameLoc; } @@ -76,7 +76,7 @@ top::LexerClassModifier ::= 'extends' cls::LexerClasses top.unparse = "extends " ++ cls.unparse; top.lexerClassModifiers := - [ lexerClassExtends(cls.lexerClasses, location=top.location, + [ lexerClassExtends(cls.lexerClasses, location=getParsedOriginLocationOrFallback(top), sourceGrammar=top.grammarName) ]; top.superClasses := cls.lexerClasses; @@ -88,7 +88,7 @@ top::LexerClassModifier ::= 'dominates' terms::TermPrecs top.unparse = "dominates " ++ terms.unparse; top.lexerClassModifiers := - [ lexerClassDominates(terms.precTermList, location=top.location, + [ lexerClassDominates(terms.precTermList, location=getParsedOriginLocationOrFallback(top), sourceGrammar=top.grammarName) ]; } @@ -99,7 +99,7 @@ top::LexerClassModifier ::= 'submits' 'to' terms::TermPrecs top.unparse = "submits to " ++ terms.unparse; top.lexerClassModifiers := - [ lexerClassSubmits(terms.precTermList, location=top.location, + [ lexerClassSubmits(terms.precTermList, location=getParsedOriginLocationOrFallback(top), sourceGrammar=top.grammarName) ]; } @@ -110,7 +110,7 @@ top::LexerClassModifier ::= 'disambiguate' acode::ActionCode_c top.unparse = "disambiguate " ++ acode.unparse; top.lexerClassModifiers := - [ lexerClassDisambiguate(acode.actionCode, location=top.location, + [ lexerClassDisambiguate(acode.actionCode, location=getParsedOriginLocationOrFallback(top), sourceGrammar=top.grammarName) ]; diff --git a/grammars/silver/compiler/modification/copper/ParserAttributes.sv b/grammars/silver/compiler/modification/copper/ParserAttributes.sv index 266ad8f5a..d5baf30fa 100644 --- a/grammars/silver/compiler/modification/copper/ParserAttributes.sv +++ b/grammars/silver/compiler/modification/copper/ParserAttributes.sv @@ -9,7 +9,7 @@ top::AGDcl ::= 'parser' 'attribute' a::Name '::' te::TypeExpr 'action' acode::Ac production attribute fName :: String; fName = top.grammarName ++ ":" ++ a.name; - top.defs := [parserAttrDef(top.grammarName, a.location, fName, te.typerep)]; + top.defs := [parserAttrDef(top.grammarName, a.nameLoc, fName, te.typerep)]; top.errors <- if length(getValueDclAll(fName, top.env)) > 1 then [errFromOrigin(a, "Attribute '" ++ fName ++ "' is already bound.")] @@ -30,7 +30,7 @@ top::AGDcl ::= 'parser' 'attribute' a::Name '::' te::TypeExpr 'action' acode::Ac top.syntaxAst := [ syntaxParserAttribute(fName, te.typerep, acode.actionCode, - location=top.location, sourceGrammar=top.grammarName) + location=a.nameLoc, sourceGrammar=top.grammarName) ]; } @@ -63,6 +63,6 @@ top::AGDcl ::= 'aspect' 'parser' 'attribute' a::QName 'action' acode::ActionCode top.syntaxAst := [ syntaxParserAttributeAspect(fName, acode.actionCode, - location=top.location, sourceGrammar=top.grammarName) + location=a.nameLoc, sourceGrammar=top.grammarName) ]; } diff --git a/grammars/silver/compiler/modification/copper/ParserDcl.sv b/grammars/silver/compiler/modification/copper/ParserDcl.sv index eb0d09ccc..52cc7649b 100644 --- a/grammars/silver/compiler/modification/copper/ParserDcl.sv +++ b/grammars/silver/compiler/modification/copper/ParserDcl.sv @@ -15,7 +15,7 @@ top::AGDcl ::= 'parser' n::Name '::' t::TypeExpr '{' m::ParserComponents '}' -- Right now parsers masquerade as functions. This is probably fine. -- Only bug is that you can aspect it, but it's pointless to do so, you can't affect anything. - top.defs := [funDef(top.grammarName, n.location, namedSig)]; + top.defs := [funDef(top.grammarName, n.nameLoc, namedSig)]; -- Parser spec grammarDependancies based off grammars included in the parser spec m.grammarDependencies = computeDependencies(m.moduleNames, top.compiledGrammars); @@ -40,7 +40,7 @@ top::AGDcl ::= 'parser' n::Name '::' t::TypeExpr '{' m::ParserComponents '}' production spec :: ParserSpec = parserSpec(fName, t.typerep.typeName, m.moduleNames, m.customLayout, m.terminalPrefixes, m.grammarTerminalPrefixes, m.syntaxAst, - sourceGrammar=top.grammarName, location=top.location); + sourceGrammar=top.grammarName, location=n.nameLoc); spec.compiledGrammars = top.compiledGrammars; top.parserSpecs := [spec]; -- Note that this is undecorated. diff --git a/grammars/silver/compiler/modification/copper/Prefix.sv b/grammars/silver/compiler/modification/copper/Prefix.sv index afc1fcf8b..4a0589ef9 100644 --- a/grammars/silver/compiler/modification/copper/Prefix.sv +++ b/grammars/silver/compiler/modification/copper/Prefix.sv @@ -39,8 +39,9 @@ top::TerminalPrefix ::= r::RegExpr tm::TerminalModifiers { top.unparse = r.unparse ++ " " ++ tm.unparse; production regex::Regex = r.terminalRegExprSpec; + local loc::Location = getParsedOriginLocation(top).fromJust; local terminalName::String = - "Prefix_" ++ toString(top.location.line) ++ + "Prefix_" ++ toString(loc.line) ++ case regex.asLiteral of | just(a) when isAlpha(a) -> "_" ++ a | _ -> "" @@ -50,7 +51,7 @@ top::TerminalPrefix ::= r::RegExpr tm::TerminalModifiers [ syntaxTerminal( terminalFullName, regex, foldr(consTerminalMod, nilTerminalMod(), tm.terminalModifiers), - location=top.location, sourceGrammar=top.grammarName) + location=loc, sourceGrammar=top.grammarName) ]; top.genFiles <- terminalTranslation(terminalName, top.grammarName, tm.lexerClasses); top.terminalPrefix = makeCopperName(terminalFullName); @@ -74,9 +75,7 @@ top::TerminalPrefix ::= t::String_t -- Specify which terminals this prefix prefixes. This is used to find the separator to -- append to the regex when normalizing the CST AST terminalModifierSingle( - terminalModifierUsePrefixSeperatorFor(top.prefixedTerminals, top.prefixedGrammars), - location=top.location), - location=top.location); + terminalModifierUsePrefixSeperatorFor(top.prefixedTerminals, top.prefixedGrammars))); } -- Needed when generating seperated terminal declarations, this is pretty useless otherwise so abstract only @@ -144,10 +143,7 @@ concrete production easyTerminalRefTerminalPrefixItem top::TerminalPrefixItem ::= t::EasyTerminalRef { propagate env; - forwards to - qNameTerminalPrefixItem( - qName(head(t.dcls).fullName), - location=top.location); + forwards to qNameTerminalPrefixItem(qName(head(t.dcls).fullName)); } -- For now, manually write this to specify priorities between terminals @@ -173,6 +169,7 @@ top::ParserComponent ::= 'prefer' t::QName 'over' ts::TermList ';' pluckTAction.originRules = []; local tName::String = t.lookupType.dcl.fullName; + local loc::Location = getParsedOriginLocation(top).fromJust; top.syntaxAst <- if !t.lookupType.found then [] else -- Generate a disambiguation function for every combination of ts. -- TODO: we can't use Copper's subset disambiguation functions here unfourtunately, @@ -182,9 +179,9 @@ top::ParserComponent ::= 'prefer' t::QName 'over' ts::TermList ';' map( \ tsNames::[String] -> syntaxDisambiguationGroup( - s"Prefer_${toString(top.location.line)}_${tName}__${implode("__", tsNames)}", + s"Prefer_${toString(loc.line)}_${tName}__${implode("__", tsNames)}", tName :: tsNames, false, pluckTAction.translation, - location=top.location, sourceGrammar=top.grammarName), + location=loc, sourceGrammar=top.grammarName), tail(powerSet(ts.termList))); } action { insert semantic token IdType_t at t.nameLoc; @@ -201,7 +198,7 @@ top::LexerClassModifier ::= 'prefix' 'separator' s::String_t top.lexerClassModifiers := [ lexerClassPrefixSeperator( substring(1, length(s.lexeme) - 1, s.lexeme), - location=top.location, sourceGrammar=top.grammarName) + location=getParsedOriginLocationOrFallback(top), sourceGrammar=top.grammarName) ]; } diff --git a/grammars/silver/compiler/modification/copper/ProductionStmt.sv b/grammars/silver/compiler/modification/copper/ProductionStmt.sv index 83f589aca..ac2afdd76 100644 --- a/grammars/silver/compiler/modification/copper/ProductionStmt.sv +++ b/grammars/silver/compiler/modification/copper/ProductionStmt.sv @@ -167,7 +167,7 @@ top::ProductionStmt ::= 'insert' 'semantic' 'token' n::QNameType 'at' loc::Expr then [errFromOrigin(loc, s"Semantic token position expected a ${errCheck1.rightpp}, but got ${errCheck1.leftpp}")] else []; } action { - insert semantic token IdType_t at n.location; + insert semantic token IdType_t at n.nameLoc; } concrete production blockStmt diff --git a/grammars/silver/compiler/modification/copper/TermList.sv b/grammars/silver/compiler/modification/copper/TermList.sv index 5670f7cd9..2d2ea4dc6 100644 --- a/grammars/silver/compiler/modification/copper/TermList.sv +++ b/grammars/silver/compiler/modification/copper/TermList.sv @@ -42,7 +42,7 @@ top::TermList ::= h::QName t::TermList -- Itd be nice if we didnt need this guard top.defs := if null(h.lookupType.dcls) then t.defs - else pluckTermDef(top.grammarName, h.location, fName) :: t.defs; + else pluckTermDef(top.grammarName, h.nameLoc, fName) :: t.defs; -- Since were looking it up in two ways, do the errors ourselves -- Todo: Consider: should this report a different error if the element of the list diff --git a/grammars/silver/compiler/modification/copper_mda/Analysis.sv b/grammars/silver/compiler/modification/copper_mda/Analysis.sv index 8b612fd4d..68995dce2 100644 --- a/grammars/silver/compiler/modification/copper_mda/Analysis.sv +++ b/grammars/silver/compiler/modification/copper_mda/Analysis.sv @@ -33,7 +33,7 @@ top::AGDcl ::= 'copper_mda' testname::Name '(' orig::QName ')' '{' m::ParserComp top.mdaSpecs = case spec of | parserSpec(fn,snt,hg,csl,_,_,_) :: _ -> [mdaSpec(top.grammarName ++":"++ testname.name, snt, - hg, m.moduleNames, csl, location=top.location, sourceGrammar=top.grammarName)] + hg, m.moduleNames, csl, sourceGrammar=top.grammarName)] | _ -> [] end; } @@ -55,18 +55,18 @@ top::MdaSpec ::= fn::String snt::String hostgrams::[String] extgrams::[String -- TODO: see TODO s in ParserSpec production hostmed :: ModuleExportedDefs = - moduleExportedDefs(error("no sl"), top.compiledGrammars, + moduleExportedDefs(top.compiledGrammars, computeDependencies(hostgrams ++ extgrams, top.compiledGrammars), hostgrams, []); production extmed :: ModuleExportedDefs = - moduleExportedDefs(error("no sl"), top.compiledGrammars, + moduleExportedDefs(top.compiledGrammars, computeDependencies(hostgrams ++ extgrams, top.compiledGrammars), extgrams, []); top.cstAst = cstCopperMdaRoot(fn, snt, foldr(consSyntax, nilSyntax(), hostmed.syntaxAst), foldr(consSyntax, nilSyntax(), extmed.syntaxAst), - customStartLayout, location=top.location, + customStartLayout, location=getParsedOriginLocationOrFallback(top), sourceGrammar=top.sourceGrammar); } diff --git a/grammars/silver/compiler/modification/defaultattr/DefaultAttr.sv b/grammars/silver/compiler/modification/defaultattr/DefaultAttr.sv index c824bd80f..3a8338225 100644 --- a/grammars/silver/compiler/modification/defaultattr/DefaultAttr.sv +++ b/grammars/silver/compiler/modification/defaultattr/DefaultAttr.sv @@ -53,7 +53,7 @@ concrete production aspectDefaultProductionSignature top::AspectDefaultProductionSignature ::= lhs::Name '::' te::TypeExpr '::=' { top.unparse = lhs.unparse ++ "::" ++ te.unparse ++ " ::="; - top.defs := [defaultLhsDef(top.grammarName, lhs.location, lhs.name, te.typerep)]; + top.defs := [defaultLhsDef(top.grammarName, lhs.nameLoc, lhs.name, te.typerep)]; top.namedSignature = namedSignature(top.grammarName ++ ":default" ++ te.typerep.typeName, nilContext(), nilNamedSignatureElement(), @@ -79,7 +79,7 @@ top::AspectDefaultProductionSignature ::= lhs::Name '::' te::TypeExpr '::=' | _ -> [] end; } action { - insert semantic token IdSigNameDcl_t at lhs.location; + insert semantic token IdSigNameDcl_t at lhs.nameLoc; sigNames = [lhs.name]; } diff --git a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv index c293967a7..155dfd50a 100644 --- a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv +++ b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv @@ -31,7 +31,7 @@ top::Expr ::= params::ProductionRHS e::Expr sigDefs := params.lambdaDefs; sigDefs <- addNewLexicalTyVars_ActuallyVariables( - top.grammarName, top.location, params.lexicalTyVarKinds, + top.grammarName, getParsedOriginLocationOrFallback(params), params.lexicalTyVarKinds, filter(\ tv::String -> null(getTypeDcl(tv, top.env)), nub(params.lexicalTypeVariables))); propagate downSubst, upSubst, finalSubst; @@ -70,7 +70,7 @@ top::ProductionRHSElem ::= id::Name '::' t::TypeExpr { production fName :: String = toString(genInt()) ++ ":" ++ id.name; -- production transName :: String = "lambda_param" ++ id.name ++ toString(genInt()); - top.lambdaDefs := [lambdaParamDef(top.grammarName, t.location, fName, t.typerep, top.givenLambdaId, top.givenLambdaParamIndex)]; + top.lambdaDefs := [lambdaParamDef(top.grammarName, id.nameLoc, fName, t.typerep, top.givenLambdaId, top.givenLambdaParamIndex)]; top.lambdaBoundVars := [id.name]; } diff --git a/grammars/silver/compiler/modification/lambda_fn/java/Lambda.sv b/grammars/silver/compiler/modification/lambda_fn/java/Lambda.sv index c2c16c8ab..8a04c296b 100644 --- a/grammars/silver/compiler/modification/lambda_fn/java/Lambda.sv +++ b/grammars/silver/compiler/modification/lambda_fn/java/Lambda.sv @@ -36,7 +36,7 @@ ${makeTyVarDecls(5, top.finalType.freeVariables)} @Override public final String toString() { - return "lambda at ${top.grammarName}:${top.location.unparse}"; + return "lambda at ${top.grammarName}:${getParsedOriginLocationOrFallback(top).unparse}"; } })"""; diff --git a/grammars/silver/compiler/modification/list/List.sv b/grammars/silver/compiler/modification/list/List.sv index 40e334090..19235cee5 100644 --- a/grammars/silver/compiler/modification/list/List.sv +++ b/grammars/silver/compiler/modification/list/List.sv @@ -47,7 +47,7 @@ top::Expr ::= '[' ']' { top.unparse = "[]"; - forwards to mkStrFunctionInvocation(top.location, "silver:core:nil", []); + forwards to Silver_Expr { silver:core:nil() }; } -- TODO: BUG: '::' is HasType_t. We probably want to have a different @@ -58,23 +58,7 @@ top::Expr ::= h::Expr '::' t::Expr { top.unparse = "(" ++ h.unparse ++ " :: " ++ t.unparse ++ ")" ; - -- Needed to satisfy flow analysis, since we demand translation of h and t. - h.decSiteVertexInfo = nothing(); - t.decSiteVertexInfo = nothing(); - h.alwaysDecorated = false; - t.alwaysDecorated = false; - - forwards to application( - baseExpr( - qName("silver:core:cons")), '(', - snocAppExprs( - snocAppExprs( - emptyAppExprs(), ',', - presentAppExpr(@h)), ',', - presentAppExpr(@t)), - ',', - emptyAnnoAppExprs(), - ')'); + forwards to Silver_Expr { silver:core:cons($Expr{@h}, $Expr{@t}) }; } concrete production fullList @@ -85,7 +69,7 @@ top::Expr ::= '[' es::Exprs ']' forwards to es.listtrans; } -synthesized attribute listtrans :: Expr occurs on Exprs; +translation attribute listtrans :: Expr occurs on Exprs; aspect production exprsEmpty top::Exprs ::= @@ -96,11 +80,11 @@ top::Exprs ::= aspect production exprsSingle top::Exprs ::= e::Expr { - top.listtrans = consListOp(e, '::', emptyList('[',']')); + top.listtrans = consListOp(@e, '::', emptyList('[',']')); } aspect production exprsCons top::Exprs ::= e1::Expr ',' e2::Exprs { - top.listtrans = consListOp(e1, '::', e2.listtrans); + top.listtrans = consListOp(@e1, '::', @e2.listtrans); } diff --git a/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv b/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv index 18de9cf5d..7b3ca14ae 100644 --- a/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv +++ b/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv @@ -233,7 +233,7 @@ top::PrimPattern ::= qn::Decorated QName ns::VarBinders e::Expr c.contextPatternOccursDefs( oc, if null(qn.lookupValue.dcls) then [] else qn.lookupValue.dcl.namedSignature.freeVariables, - scrutineeName, top.location, top.grammarName), + scrutineeName, qn.nameLoc, top.grammarName), prod_contexts, if null(qn.lookupValue.dcls) then [] else qn.lookupValue.dcl.namedSignature.contexts)); ns.env = occursEnv(contextOccursDefs, top.env); @@ -268,7 +268,7 @@ top::PrimPattern ::= qn::Decorated QName ns::VarBinders e::Expr performContextSubstitution(c, e.downSubst).contextPatternDefs( oc, if null(qn.lookupValue.dcls) then [] else qn.lookupValue.dcl.namedSignature.freeVariables, - scrutineeName, top.location, top.grammarName), + scrutineeName, qn.nameLoc, top.grammarName), prod_contexts, if null(qn.lookupValue.dcls) then [] else qn.lookupValue.dcl.namedSignature.contexts)); e.env = newScopeEnv(contextDefs ++ ns.defs, ns.env); e.isRoot = false; @@ -313,7 +313,7 @@ top::PrimPattern ::= qn::Decorated QName ns::VarBinders e::Expr c.contextPatternOccursDefs( oc, if null(qn.lookupValue.dcls) then [] else qn.lookupValue.dcl.namedSignature.freeVariables, - scrutineeName, top.location, top.grammarName), + scrutineeName, qn.nameLoc, top.grammarName), prod_contexts, if null(qn.lookupValue.dcls) then [] else qn.lookupValue.dcl.namedSignature.contexts)); ns.env = occursEnv(contextOccursDefs, top.env); @@ -359,7 +359,7 @@ top::PrimPattern ::= qn::Decorated QName ns::VarBinders e::Expr performContextSubstitution(c, e.finalSubst).contextPatternDefs( oc, if null(qn.lookupValue.dcls) then [] else qn.lookupValue.dcl.namedSignature.freeVariables, - scrutineeName, top.location, top.grammarName), + scrutineeName, qn.nameLoc, top.grammarName), prod_contexts, if null(qn.lookupValue.dcls) then [] else qn.lookupValue.dcl.namedSignature.contexts)); e.env = newScopeEnv(contextDefs ++ ns.defs, ns.env); @@ -526,8 +526,8 @@ top::PrimPattern ::= h::Name t::Name e::Expr propagate finalSubst; local consdefs :: [Def] = - [lexicalLocalDef(top.grammarName, top.location, h_fName, elemType, nothing(), [], []), - lexicalLocalDef(top.grammarName, top.location, t_fName, top.scrutineeType, nothing(), [], [])]; + [lexicalLocalDef(top.grammarName, h.nameLoc, h_fName, elemType, nothing(), [], []), + lexicalLocalDef(top.grammarName, t.nameLoc, t_fName, top.scrutineeType, nothing(), [], [])]; e.env = newScopeEnv(consdefs, top.env); e.isRoot = false; diff --git a/grammars/silver/compiler/translation/java/core/Origins.sv b/grammars/silver/compiler/translation/java/core/Origins.sv index f47d69d02..13cdd6c29 100644 --- a/grammars/silver/compiler/translation/java/core/Origins.sv +++ b/grammars/silver/compiler/translation/java/core/Origins.sv @@ -43,7 +43,8 @@ function makeOriginContextRef String ::= top::Decorated Expr --need .frame anno { local rulesTrans :: [String] = (if top.config.tracingOrigins then [locRule] else []) ++ map((.translation), top.originRules); - local locRule :: String = s"new silver.core.PtraceNote(new common.StringCatter(\"${top.grammarName}:${escapeString(top.location.unparse)}\"))"; + local loc :: Location = getParsedOriginLocationOrFallback(top); + local locRule :: String = s"new silver.core.PtraceNote(new common.StringCatter(\"${top.grammarName}:${escapeString(loc.unparse)}\"))"; return if top.config.noOrigins then "null" else if length(rulesTrans)==0 diff --git a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv index fa0929ac2..6281eea14 100644 --- a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv +++ b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv @@ -203,7 +203,7 @@ ${if isData then "" else s""" then s"throw new common.exceptions.SilverInternalError(\"Production ${fName} erroneously claimed to forward\")" else s"return ((common.Node)${head(body.forwardExpr).translation}${ if wantsTracking && !top.config.noRedex - then s".duplicateForForwarding(context.getNode(), \"${escapeString(hackUnparse(head(body.forwardExpr).location))}\")" + then s".duplicateForForwarding(context.getNode(), \"${escapeString(getParsedOriginLocationOrFallback(head(body.forwardExpr)).unparse)}\")" else ""})"}; } From dfe31bc6556b1700b2090c0b5dc4e29c80d3b091 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 28 Sep 2023 15:25:48 -0500 Subject: [PATCH 043/283] Fix remaining errors due to use of location --- .../compiler/definition/core/ModuleStmts.sv | 10 ++++ .../silver/compiler/definition/core/QName.sv | 3 +- .../silver/compiler/definition/core/Root.sv | 10 ---- .../compiler/extension/autoattr/BiEquality.sv | 4 +- .../compiler/extension/autoattr/Equality.sv | 2 +- .../compiler/extension/autoattr/Ordering.sv | 4 +- .../convenienceaspects/AbstractSyntax.sv | 2 +- .../extension/implicit_monads/Expr.sv | 2 +- .../extension/patternmatching/Case.sv | 2 +- .../silver/compiler/extension/regex/Regex.sv | 2 +- .../compiler/extension/rewriting/Expr.sv | 3 +- .../extension/strategyattr/Strategy.sv | 2 +- .../extension/strategyattr/StrategyExpr.sv | 6 -- .../compiler/extension/testing/Helper.sv | 8 ++- .../extension/testing/MainTestSuite.sv | 8 +-- .../compiler/extension/treegen/Arbitrary.sv | 2 +- .../compiler/extension/treegen/TerminalGen.sv | 4 +- .../compiler/langserver/ReferenceLocations.sv | 56 +++++++++---------- 18 files changed, 63 insertions(+), 67 deletions(-) diff --git a/grammars/silver/compiler/definition/core/ModuleStmts.sv b/grammars/silver/compiler/definition/core/ModuleStmts.sv index 9c06591b3..2f42aea5a 100644 --- a/grammars/silver/compiler/definition/core/ModuleStmts.sv +++ b/grammars/silver/compiler/definition/core/ModuleStmts.sv @@ -131,6 +131,16 @@ concrete production importStmt top::ImportStmt ::= 'import' m::ModuleExpr ';' { top.unparse = "import " ++ m.unparse ++ ";"; + + -- See https://github.com/melt-umn/silver/issues/444. + -- An explicit file-scope import of silver:core would cause silver:core to not get implicitly imported + -- for the whole grammar, but since it is file scope silver:core wouldn't be visible in other files. + -- This behaviour is unintuitative, and the user probably meant to write a grammar-scope import hiding + -- or renaming something - so raise an error in this case. + top.errors <- + if contains("silver:core", m.moduleNames) + then [errFromOrigin(top, "File-scope import of silver:core is non supported. Did you mean 'imports silver:core ...;'?")] + else []; } concrete production nilImportStmts diff --git a/grammars/silver/compiler/definition/core/QName.sv b/grammars/silver/compiler/definition/core/QName.sv index 4453cfe77..5cbc82c34 100644 --- a/grammars/silver/compiler/definition/core/QName.sv +++ b/grammars/silver/compiler/definition/core/QName.sv @@ -156,7 +156,7 @@ top::QNameType ::= id::Name ':' qn::QNameType {-- - Qualified name looked up CONTEXTUALLY -} -tracked nonterminal QNameAttrOccur with config, name, grammarName, env, unparse, attrFor, errors, typerep, dcl, attrDcl, found, attrFound; +tracked nonterminal QNameAttrOccur with config, name, grammarName, env, unparse, nameLoc, attrFor, errors, typerep, dcl, attrDcl, found, attrFound; flowtype QNameAttrOccur = decorate {grammarName, config, env, attrFor}, dcl {grammarName, env, attrFor}, attrDcl {grammarName, env, attrFor}; @@ -187,6 +187,7 @@ top::QNameAttrOccur ::= at::QName { top.name = at.name; top.unparse = at.unparse; + top.nameLoc = at.nameLoc; propagate env; local attrs :: [AttributeDclInfo] = diff --git a/grammars/silver/compiler/definition/core/Root.sv b/grammars/silver/compiler/definition/core/Root.sv index 963a2bb55..d7717abbf 100644 --- a/grammars/silver/compiler/definition/core/Root.sv +++ b/grammars/silver/compiler/definition/core/Root.sv @@ -43,16 +43,6 @@ top::Root ::= gdcl::GrammarDcl ms::ModuleStmts ims::ImportStmts ags::AGDcls -- THEN, we have the grammar-wide definitions, from the whole grammr. That's top.env here. -- So we're kind of injecting local imports in between two grammar-wide things there. ags.env = appendEnv(top.env, newScopeEnv(ims.defs, occursEnv(ims.occursDefs, top.globalImports))); - - -- See https://github.com/melt-umn/silver/issues/444. - -- An explicit file-scope import of silver:core would cause silver:core to not get implicitly imported - -- for the whole grammar, but since it is file scope silver:core wouldn't be visible in other files. - -- This behaviour is unintuitative, and the user probably meant to write a grammar-scope import hiding - -- or renaming something - so raise an error in this case. - top.errors <- - if contains("silver:core", ims.moduleNames) - then [err(ims.location, "File-scope import of silver:core is non supported. Did you mean 'imports silver:core ...;'?")] - else []; } concrete production noGrammarDcl diff --git a/grammars/silver/compiler/extension/autoattr/BiEquality.sv b/grammars/silver/compiler/extension/autoattr/BiEquality.sv index afa66e2f4..47d1a82b4 100644 --- a/grammars/silver/compiler/extension/autoattr/BiEquality.sv +++ b/grammars/silver/compiler/extension/autoattr/BiEquality.sv @@ -26,8 +26,8 @@ top::AGDcl ::= 'biequality' 'attribute' synPartial::Name ',' syn::Name 'with' in forwards to defsAGDcl( - [attrDef(defaultEnvItem(biequalityPartialDcl(inhFName, synPartialFName, synFName, sourceGrammar=top.grammarName, sourceLocation=synPartial.location))), - attrDef(defaultEnvItem(biequalityDcl(inhFName, synPartialFName, synFName, sourceGrammar=top.grammarName, sourceLocation=syn.location)))]); + [attrDef(defaultEnvItem(biequalityPartialDcl(inhFName, synPartialFName, synFName, sourceGrammar=top.grammarName, sourceLocation=synPartial.nameLoc))), + attrDef(defaultEnvItem(biequalityDcl(inhFName, synPartialFName, synFName, sourceGrammar=top.grammarName, sourceLocation=syn.nameLoc)))]); } abstract production biequalityInhAttributionDcl diff --git a/grammars/silver/compiler/extension/autoattr/Equality.sv b/grammars/silver/compiler/extension/autoattr/Equality.sv index b02e5c723..9223e0b0e 100644 --- a/grammars/silver/compiler/extension/autoattr/Equality.sv +++ b/grammars/silver/compiler/extension/autoattr/Equality.sv @@ -20,7 +20,7 @@ top::AGDcl ::= 'equality' 'attribute' syn::Name 'with' inh::QName ';' forwards to defsAGDcl( - [attrDef(defaultEnvItem(equalityDcl(inhFName, synFName, sourceGrammar=top.grammarName, sourceLocation=syn.location)))]); + [attrDef(defaultEnvItem(equalityDcl(inhFName, synFName, sourceGrammar=top.grammarName, sourceLocation=syn.nameLoc)))]); } {-- diff --git a/grammars/silver/compiler/extension/autoattr/Ordering.sv b/grammars/silver/compiler/extension/autoattr/Ordering.sv index af55680c3..1d5581a3b 100644 --- a/grammars/silver/compiler/extension/autoattr/Ordering.sv +++ b/grammars/silver/compiler/extension/autoattr/Ordering.sv @@ -27,8 +27,8 @@ top::AGDcl ::= 'ordering' 'attribute' keySyn::Name ',' syn::Name 'with' inh::QNa forwards to defsAGDcl( - [attrDef(defaultEnvItem(orderingKeyDcl(keySynFName, sourceGrammar=top.grammarName, sourceLocation=syn.location))), - attrDef(defaultEnvItem(orderingDcl(inhFName, keySynFName, synFName, sourceGrammar=top.grammarName, sourceLocation=syn.location)))]); + [attrDef(defaultEnvItem(orderingKeyDcl(keySynFName, sourceGrammar=top.grammarName, sourceLocation=syn.nameLoc))), + attrDef(defaultEnvItem(orderingDcl(inhFName, keySynFName, synFName, sourceGrammar=top.grammarName, sourceLocation=syn.nameLoc)))]); } {-- diff --git a/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv b/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv index ebae714d5..c0f282070 100644 --- a/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv +++ b/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv @@ -355,7 +355,7 @@ Pair ::= rules::[MatchRule] aspectLHS::Decorated ConvAspectLHS aspect default production $Name{aspectLHS.aspectName}::$TypeExpr{aspectLHS.aspectType} ::= { $ProductionStmt{eqKind.makeAspectEquation( - makeDefinitionLHSFromName(spectLHS.aspectName), + makeDefinitionLHSFromName(aspectLHS.aspectName), aspectAttr, makeLetExprForTopRenaming(name, aspectLHS, e))}} }, diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index e1e25a46b..0b0a2b950 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -368,7 +368,7 @@ Expr ::= monadTysLocs::[Pair] funargs::AppExprs annargs::AnnoAppEx local baseapp::Expr = application(baseExpr(qName("f")), '(', funargs, ',', annargs, ')'); local funapp::Expr = if wrapReturn - then Silver_Expr { $Expr {monadReturn(loc)}($Expr {baseapp}) } + then Silver_Expr { $Expr {monadReturn()}($Expr {baseapp}) } else baseapp; local funbinding::ProductionRHS = productionRHSCons(productionRHSElem(name("f"), '::', diff --git a/grammars/silver/compiler/extension/patternmatching/Case.sv b/grammars/silver/compiler/extension/patternmatching/Case.sv index 49f9b10b7..71cc1d9d5 100644 --- a/grammars/silver/compiler/extension/patternmatching/Case.sv +++ b/grammars/silver/compiler/extension/patternmatching/Case.sv @@ -83,7 +83,7 @@ top::Expr ::= 'case' es::Exprs 'of' Opt_Vbar_t ml::MRuleList 'end' caseExpr(es.rawExprs, ml.matchRuleList, true, mkStrFunctionInvocation("silver:core:error", [stringConst(terminal(String_t, - "\"Error: pattern match failed at " ++ top.grammarName ++ " " ++ top.location.unparse ++ "\\n\""))]), + "\"Error: pattern match failed at " ++ top.grammarName ++ ":" ++ getParsedOriginLocationOrFallback(top).unparse ++ "\\n\""))]), freshType()); } diff --git a/grammars/silver/compiler/extension/regex/Regex.sv b/grammars/silver/compiler/extension/regex/Regex.sv index 0a4ec72de..2c4edca01 100644 --- a/grammars/silver/compiler/extension/regex/Regex.sv +++ b/grammars/silver/compiler/extension/regex/Regex.sv @@ -19,7 +19,7 @@ layout {} forwards to if null(getTypeDcl("silver:regex:Regex", top.env)) then errorExpr([errFromOrigin(top, "Use of regexes requires import of silver:regex")]) - else translate(top.location, reflect(reg.ast)); + else translate(reflect(reg.ast)); } concrete production matches diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index 43beb6d7b..a518ab4c7 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -269,8 +269,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur productionRHSElem( name("_e"), '::', typerepTypeExpr(eUndec.finalType)), - inh.lambdaParams, - location=builtin), + inh.lambdaParams), Silver_Expr { $Expr{ decorateExprWith( diff --git a/grammars/silver/compiler/extension/strategyattr/Strategy.sv b/grammars/silver/compiler/extension/strategyattr/Strategy.sv index b42f240ed..b38c0513d 100644 --- a/grammars/silver/compiler/extension/strategyattr/Strategy.sv +++ b/grammars/silver/compiler/extension/strategyattr/Strategy.sv @@ -42,7 +42,7 @@ top::AGDcl ::= isTotal::Boolean a::Name recVarNameEnv::[Pair] rec strategyDcl( fName, isTotal, !null(top.errors), map(fst, e.liftedStrategies), recVarNameEnv, recVarTotalEnv, e.partialRefs, e.totalRefs, e.containsTraversal, e, - sourceGrammar=top.grammarName)))]), + sourceGrammar=top.grammarName, sourceLocation=a.nameLoc)))]), map( \ d::(String, Decorated StrategyExpr with LiftedInhs) -> strategyAttributeDcl( diff --git a/grammars/silver/compiler/extension/strategyattr/StrategyExpr.sv b/grammars/silver/compiler/extension/strategyattr/StrategyExpr.sv index 5ea4bee5e..c8b8c2e7e 100644 --- a/grammars/silver/compiler/extension/strategyattr/StrategyExpr.sv +++ b/grammars/silver/compiler/extension/strategyattr/StrategyExpr.sv @@ -358,7 +358,6 @@ top::StrategyExpr ::= s::StrategyExpr silver:core:just( $Expr{ mkFullFunctionInvocation( - top.location, baseExpr(qName(top.frame.fullName)), map( \ a::Pair -> @@ -439,7 +438,6 @@ top::StrategyExpr ::= s::StrategyExpr silver:core:just( $Expr{ mkFullFunctionInvocation( - top.location, baseExpr(qName(top.frame.fullName)), map( \ a::Pair -> @@ -458,7 +456,6 @@ top::StrategyExpr ::= s::StrategyExpr {- When s is total, optimized translation of all(s) for prod::(Foo ::= a::Foo b::Integer c::Bar): prod(a.s, b, c.s) -} mkFullFunctionInvocation( - top.location, baseExpr(qName(top.frame.fullName)), map( \ a::Pair -> @@ -533,7 +530,6 @@ top::StrategyExpr ::= s::StrategyExpr silver:core:just( $Expr{ mkFullFunctionInvocation( - top.location, baseExpr(qName(top.frame.fullName)), map( \ a::Pair -> Silver_Expr { $name{a.fst} }, @@ -557,7 +553,6 @@ top::StrategyExpr ::= s::StrategyExpr {- When s is total, optimized translation of one(s) for prod::(Foo ::= a::Foo b::Integer c::Bar): prod(a.s, b, c) -} mkFullFunctionInvocation( - top.location, baseExpr(qName(top.frame.fullName)), map( \ a::Pair -> @@ -630,7 +625,6 @@ top::StrategyExpr ::= prod::QName s::StrategyExprs silver:core:just( $Expr{ mkFullFunctionInvocation( - top.location, baseExpr(qName(top.frame.fullName)), map( \ a::Pair> -> diff --git a/grammars/silver/compiler/extension/testing/Helper.sv b/grammars/silver/compiler/extension/testing/Helper.sv index 3e74b8cb4..a6e8a7215 100644 --- a/grammars/silver/compiler/extension/testing/Helper.sv +++ b/grammars/silver/compiler/extension/testing/Helper.sv @@ -9,10 +9,12 @@ import silver:compiler:modification:collection; import silver:compiler:modification:list; -- Expression creating functions +-- TODO: These are duplicates of existing helpers, are obsolete with concrete syntax quotation, +-- or otherwise don't belong here! -- Create an Expr from a String. function mkNameExpr -Expr ::= name::String l::Location +Expr ::= name::String { return baseExpr(qName(name)); } @@ -35,10 +37,10 @@ Expr ::= s::String -- Create an attribute reference from two names. as in "n.a" function attrAcc -Expr ::= n::String a::String l::Location +Expr ::= n::String a::String { return - access(mkNameExpr(n, l), '.', qNameAttrOccur(qName(a))); + access(mkNameExpr(n), '.', qNameAttrOccur(qName(a))); } -- replace " characters with two: \ and " diff --git a/grammars/silver/compiler/extension/testing/MainTestSuite.sv b/grammars/silver/compiler/extension/testing/MainTestSuite.sv index 79b57a8fb..cd792308c 100644 --- a/grammars/silver/compiler/extension/testing/MainTestSuite.sv +++ b/grammars/silver/compiler/extension/testing/MainTestSuite.sv @@ -26,7 +26,7 @@ top::AGDcl ::= 'makeTestSuite' nme::IdLower_t ';' '::=', productionRHSNil()); local bod :: [ProductionStmt] = - [forwardsTo('forwards', 'to', mkStrFunctionInvocation(top.location, "testsAsNT", [mkNameExpr("testsToPerform")]), ';'), + [forwardsTo('forwards', 'to', mkStrFunctionInvocation("testsAsNT", [mkNameExpr("testsToPerform")]), ';'), collectionAttributeDclProd('production', 'attribute', name("testsToPerform"), '::', listTypeExpr('[', nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "Test"))), ']'), 'with', plusplusOperator('++'), ';'), @@ -92,11 +92,11 @@ top::AGDcl ::= 'mainTestSuite' nme::IdLower_t ';' '=', mkNameExpr("mainIO"), ';'), -- return ... returnDef('return', - mkStrFunctionInvocation(top.location, "ioval", + mkStrFunctionInvocation("ioval", [ - mkStrFunctionInvocation(top.location, "exitT", + mkStrFunctionInvocation("exitT", [ attrAcc("testResults","numFailed"), - mkStrFunctionInvocation(top.location, "printT", + mkStrFunctionInvocation("printT", [ foldStringExprs( [ strCnst("\n\n"), strCnst("============================================================\n"), diff --git a/grammars/silver/compiler/extension/treegen/Arbitrary.sv b/grammars/silver/compiler/extension/treegen/Arbitrary.sv index c0277e890..1d667bc6a 100644 --- a/grammars/silver/compiler/extension/treegen/Arbitrary.sv +++ b/grammars/silver/compiler/extension/treegen/Arbitrary.sv @@ -44,7 +44,7 @@ top::AGDcl ::= 'generator' n::Name '::' t::TypeExpr '{' grammars::GeneratorCompo -- Build the syntax AST from the specified grammars to extract lexical precedence info production syntax::SyntaxRoot = cstRoot( n.name, t.typerep.typeName, foldr(consSyntax, nilSyntax(), med.syntaxAst), - nothing(), [], [], sourceGrammar=top.grammarName); + nothing(), [], [], sourceGrammar=top.grammarName, location=n.nameLoc); production attribute implicitImports::[String] with ++; implicitImports := []; diff --git a/grammars/silver/compiler/extension/treegen/TerminalGen.sv b/grammars/silver/compiler/extension/treegen/TerminalGen.sv index a51bd2352..5864879dd 100644 --- a/grammars/silver/compiler/extension/treegen/TerminalGen.sv +++ b/grammars/silver/compiler/extension/treegen/TerminalGen.sv @@ -34,7 +34,7 @@ top::Expr ::= 'genArbTerminal' '(' te::TypeExpr ',' '_' ')' then errorExpr([errFromOrigin(top, "Generation of arbitrary terminal values requires import of silver:regex")]) else Silver_Expr { let genLexeme::RandomGen = - decorate $Expr{translate(top.location, reflect(new(regex)))} with { + decorate $Expr{translate(reflect(new(regex)))} with { starProb = $Expr{floatConst(terminal(Float_t, toString(genRepeatProb)))}; altCountIn = 0; }.genArbMatch @@ -48,7 +48,7 @@ top::Expr ::= 'genArbTerminal' '(' te::TypeExpr ',' loc::Expr ')' { top.unparse = s"genArbTerminal(${te.unparse}, ${loc.unparse})"; forwards to - mkFunctionInvocation(top.location, + mkFunctionInvocation( genArbTerminalNoLocExpr('genArbTerminal', '(', te, ',', '_', ')'), [loc]); } diff --git a/grammars/silver/compiler/langserver/ReferenceLocations.sv b/grammars/silver/compiler/langserver/ReferenceLocations.sv index 72d991968..49db2cbba 100644 --- a/grammars/silver/compiler/langserver/ReferenceLocations.sv +++ b/grammars/silver/compiler/langserver/ReferenceLocations.sv @@ -27,33 +27,33 @@ propagate valueRefLocs, typeRefLocs, attributeRefLocs on PrimPatterns, PrimPattern, ProdNameList; aspect valueRefLocs on NameList using <- of -| nameListCons(q, _, _) -> if q.lookupValue.found then [(q.location, q.lookupValue.dcl)] else [] -| nameListOne(q) -> if q.lookupValue.found then [(q.location, q.lookupValue.dcl)] else [] +| nameListCons(q, _, _) -> if q.lookupValue.found then [(q.nameLoc, q.lookupValue.dcl)] else [] +| nameListOne(q) -> if q.lookupValue.found then [(q.nameLoc, q.lookupValue.dcl)] else [] end; aspect typeRefLocs on NameList using <- of -| nameListCons(q, _, _) -> if q.lookupType.found then [(q.location, q.lookupType.dcl)] else [] -| nameListOne(q) -> if q.lookupType.found then [(q.location, q.lookupType.dcl)] else [] +| nameListCons(q, _, _) -> if q.lookupType.found then [(q.nameLoc, q.lookupType.dcl)] else [] +| nameListOne(q) -> if q.lookupType.found then [(q.nameLoc, q.lookupType.dcl)] else [] end; aspect attributeRefLocs on NameList using <- of -| nameListCons(q, _, _) -> if q.lookupAttribute.found then [(q.location, q.lookupAttribute.dcl)] else [] -| nameListOne(q) -> if q.lookupAttribute.found then [(q.location, q.lookupAttribute.dcl)] else [] +| nameListCons(q, _, _) -> if q.lookupAttribute.found then [(q.nameLoc, q.lookupAttribute.dcl)] else [] +| nameListOne(q) -> if q.lookupAttribute.found then [(q.nameLoc, q.lookupAttribute.dcl)] else [] end; attribute typeRefLocs occurs on QNameType; aspect typeRefLocs on top::QNameType using := of -| _ -> if top.lookupType.found then [(top.location, top.lookupType.dcl)] else [] +| _ -> if top.lookupType.found then [(top.nameLoc, top.lookupType.dcl)] else [] end; attribute attributeRefLocs occurs on QNameAttrOccur; aspect attributeRefLocs on top::QNameAttrOccur using := of -| qNameAttrOccur(at) -> if top.found then [(at.location, top.attrDcl)] else [] +| qNameAttrOccur(at) -> if top.found then [(at.nameLoc, top.attrDcl)] else [] end; aspect valueRefLocs on AGDcl using <- of -| aspectProductionDcl(_, _, q, _, _) -> if q.lookupValue.found then [(q.location, q.lookupValue.dcl)] else [] -| aspectFunctionDcl(_, _, q, _, _) -> if q.lookupValue.found then [(q.location, q.lookupValue.dcl)] else [] +| aspectProductionDcl(_, _, q, _, _) -> if q.lookupValue.found then [(q.nameLoc, q.lookupValue.dcl)] else [] +| aspectFunctionDcl(_, _, q, _, _) -> if q.lookupValue.found then [(q.nameLoc, q.lookupValue.dcl)] else [] end; aspect valueRefLocs on AGDcl using := of @@ -64,7 +64,7 @@ aspect valueRefLocs on AGDcl using := of end; aspect typeRefLocs on AGDcl using <- of -| defaultAttributionDcl(_, _, nt, _) -> if nt.lookupType.found then [(nt.location, nt.lookupType.dcl)] else [] +| defaultAttributionDcl(_, _, nt, _) -> if nt.lookupType.found then [(nt.nameLoc, nt.lookupType.dcl)] else [] end; aspect typeRefLocs on AGDcl using := of @@ -73,7 +73,7 @@ aspect typeRefLocs on AGDcl using := of end; aspect attributeRefLocs on AGDcl using <- of -| defaultAttributionDcl(at, _, _, _) -> if at.lookupAttribute.found then [(at.location, at.lookupAttribute.dcl)] else [] +| defaultAttributionDcl(at, _, _, _) -> if at.lookupAttribute.found then [(at.nameLoc, at.lookupAttribute.dcl)] else [] end; aspect attributeRefLocs on AGDcl using := of @@ -95,9 +95,9 @@ top::AGDcl ::= 'monoid' 'attribute' a::Name tl::BracketedOptTypeExprs _ te::Type } aspect attributeRefLocs on Constraint using <- of -| inhOccursConstraint(_, at, _, _, _, _) -> if at.lookupAttribute.found then [(at.location, at.lookupAttribute.dcl)] else [] -| synOccursConstraint(_, at, _, _, _, _, _) -> if at.lookupAttribute.found then [(at.location, at.lookupAttribute.dcl)] else [] -| annoOccursConstraint(_, at, _, _, _, _) -> if at.lookupAttribute.found then [(at.location, at.lookupAttribute.dcl)] else [] +| inhOccursConstraint(_, at, _, _, _, _) -> if at.lookupAttribute.found then [(at.nameLoc, at.lookupAttribute.dcl)] else [] +| synOccursConstraint(_, at, _, _, _, _, _) -> if at.lookupAttribute.found then [(at.nameLoc, at.lookupAttribute.dcl)] else [] +| annoOccursConstraint(_, at, _, _, _, _) -> if at.lookupAttribute.found then [(at.nameLoc, at.lookupAttribute.dcl)] else [] end; aspect valueRefLocs on top::ProductionStmt using <- of @@ -111,7 +111,7 @@ aspect valueRefLocs on ProductionStmt using := of end; aspect attributeRefLocs on ProductionStmt using := of -| propagateOneAttr(at) -> if at.lookupAttribute.found then [(at.location, at.lookupAttribute.dcl)] else [] +| propagateOneAttr(at) -> if at.lookupAttribute.found then [(at.nameLoc, at.lookupAttribute.dcl)] else [] end; aspect typeRefLocs on ProductionStmt using := of @@ -119,13 +119,13 @@ aspect typeRefLocs on ProductionStmt using := of end; aspect valueRefLocs on DefLHS using <- of -| lhsDefLHS(q) -> if q.lookupValue.found then [(q.location, q.lookupValue.dcl)] else [] -| childDefLHS(q) -> if q.lookupValue.found then [(q.location, q.lookupValue.dcl)] else [] -| localDefLHS(q) -> if q.lookupValue.found then [(q.location, q.lookupValue.dcl)] else [] +| lhsDefLHS(q) -> if q.lookupValue.found then [(q.nameLoc, q.lookupValue.dcl)] else [] +| childDefLHS(q) -> if q.lookupValue.found then [(q.nameLoc, q.lookupValue.dcl)] else [] +| localDefLHS(q) -> if q.lookupValue.found then [(q.nameLoc, q.lookupValue.dcl)] else [] end; aspect valueRefLocs on Expr using <- of -| baseExpr(q) -> if q.lookupValue.found then [(q.location, q.lookupValue.dcl)] else [] +| baseExpr(q) -> if q.lookupValue.found then [(q.nameLoc, q.lookupValue.dcl)] else [] end; aspect valueRefLocs on Expr using := of @@ -146,17 +146,17 @@ aspect typeRefLocs on Expr using := of end; aspect attributeRefLocs on AnnoExpr using <- of -| annoExpr(q, _, _) -> if q.lookupAttribute.found then [(q.location, q.lookupAttribute.dcl)] else [] +| annoExpr(q, _, _) -> if q.lookupAttribute.found then [(q.nameLoc, q.lookupAttribute.dcl)] else [] end; aspect valueRefLocs on PrimPattern using <- of -| prodPatternNormal(q, _, _) -> if q.lookupValue.found then [(q.location, q.lookupValue.dcl)] else [] -| prodPatternGadt(q, _, _) -> if q.lookupValue.found then [(q.location, q.lookupValue.dcl)] else [] +| prodPatternNormal(q, _, _) -> if q.lookupValue.found then [(q.nameLoc, q.lookupValue.dcl)] else [] +| prodPatternGadt(q, _, _) -> if q.lookupValue.found then [(q.nameLoc, q.lookupValue.dcl)] else [] end; aspect valueRefLocs on ProdNameList using <- of -| prodNameListCons(q, _, _) -> if q.lookupValue.found then [(q.location, q.lookupValue.dcl)] else [] -| prodNameListOne(q) -> if q.lookupValue.found then [(q.location, q.lookupValue.dcl)] else [] +| prodNameListCons(q, _, _) -> if q.lookupValue.found then [(q.nameLoc, q.lookupValue.dcl)] else [] +| prodNameListOne(q) -> if q.lookupValue.found then [(q.nameLoc, q.lookupValue.dcl)] else [] end; attribute valueRefLocs, typeRefLocs, attributeRefLocs occurs on StrategyExpr, StrategyExprs; @@ -168,7 +168,7 @@ propagate attributeRefLocs on StrategyExpr, StrategyExprs excluding partialRef, totalRef; aspect valueRefLocs on top::StrategyExpr using <- of -| prodTraversal(q, _) -> if q.lookupValue.found then [(q.location, q.lookupValue.dcl)] else [] +| prodTraversal(q, _) -> if q.lookupValue.found then [(q.nameLoc, q.lookupValue.dcl)] else [] | rewriteRule(_, _, _) -> checkExpr.valueRefLocs end; @@ -181,8 +181,8 @@ aspect attributeRefLocs on top::StrategyExpr using <- of end; aspect attributeRefLocs on StrategyExpr using := of -| partialRef(a) -> if attrDclFound then [(a.location, attrDcl)] else [] -| totalRef(a) -> if attrDclFound then [(a.location, attrDcl)] else [] +| partialRef(a) -> if attrDclFound then [(a.nameLoc, attrDcl)] else [] +| totalRef(a) -> if attrDclFound then [(a.nameLoc, attrDcl)] else [] end; -- Productions From f496c9bcc6537e19a99374c2529d0cea02259c6e Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 29 Sep 2023 14:15:06 -0500 Subject: [PATCH 044/283] Debugging translation attr issue --- grammars/silver/compiler/modification/list/List.sv | 6 +++--- .../silver/compiler/translation/java/core/NamedSignature.sv | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/grammars/silver/compiler/modification/list/List.sv b/grammars/silver/compiler/modification/list/List.sv index 19235cee5..43a096e56 100644 --- a/grammars/silver/compiler/modification/list/List.sv +++ b/grammars/silver/compiler/modification/list/List.sv @@ -69,7 +69,7 @@ top::Expr ::= '[' es::Exprs ']' forwards to es.listtrans; } -translation attribute listtrans :: Expr occurs on Exprs; +synthesized attribute listtrans :: Expr occurs on Exprs; aspect production exprsEmpty top::Exprs ::= @@ -80,11 +80,11 @@ top::Exprs ::= aspect production exprsSingle top::Exprs ::= e::Expr { - top.listtrans = consListOp(@e, '::', emptyList('[',']')); + top.listtrans = consListOp(e, '::', emptyList('[',']')); } aspect production exprsCons top::Exprs ::= e1::Expr ',' e2::Exprs { - top.listtrans = consListOp(@e1, '::', @e2.listtrans); + top.listtrans = consListOp(e1, '::', e2.listtrans); } diff --git a/grammars/silver/compiler/translation/java/core/NamedSignature.sv b/grammars/silver/compiler/translation/java/core/NamedSignature.sv index 168abdde8..3c3d708db 100644 --- a/grammars/silver/compiler/translation/java/core/NamedSignature.sv +++ b/grammars/silver/compiler/translation/java/core/NamedSignature.sv @@ -347,7 +347,11 @@ String ::= env::Env flowEnv::FlowEnv lhsNtName::String v::VertexType | [] -> error("Couldn't find decl for local " ++ fName) end | transAttrVertexType(lhsVertexType_real(), transAttr) -> - let transIndexName::String = head(getOccursDcl(transAttr, lhsNtName, env)).attrGlobalOccursInitIndex + let transIndexName::String = + case getOccursDcl(transAttr, lhsNtName, env) of + | h :: _ -> h.attrGlobalOccursInitIndex + | [] -> error(s"Trans attr ${transAttr} occurs on ${lhsNtName} dcl not found!") + end in s"context.translation(${transIndexName}, ${transIndexName}_inhs, ${transIndexName}_dec_site)" end | transAttrVertexType(_, transAttr) -> error("trans attr on non-lhs can't be a ref decoration site") From 48d64159bc6e8354cf67c741ea7efd17ca39e918 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 29 Sep 2023 14:32:29 -0500 Subject: [PATCH 045/283] Tweak compare --- grammars/silver/compiler/extension/autoattr/DclInfo.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grammars/silver/compiler/extension/autoattr/DclInfo.sv b/grammars/silver/compiler/extension/autoattr/DclInfo.sv index 95e1c0e7f..670423549 100644 --- a/grammars/silver/compiler/extension/autoattr/DclInfo.sv +++ b/grammars/silver/compiler/extension/autoattr/DclInfo.sv @@ -39,11 +39,11 @@ abstract production monoidDcl top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type empty::Expr append::Operation { top.fullName = fn; - propagate compareKey; + propagate compareTo, compareKey; top.isEqual = case top.compareTo of | monoidDcl(fn2, _, _, empty2, append2) -> - fn == fn2 && top.typeScheme == top.compareTo.typeScheme && empty.unparse == empty2.unparse && append == append2 + fn == fn2 && top.typeScheme == top.compareTo.typeScheme && empty.unparse == empty2.unparse && append.isEqual | _ -> false end; From e5982d2a7318f5c2ff99955176983e904315d044 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 2 Oct 2023 12:06:55 -0500 Subject: [PATCH 046/283] Avoid comparing interface files when doing a clean build --- grammars/silver/compiler/driver/CompileGrammar.sv | 1 + 1 file changed, 1 insertion(+) diff --git a/grammars/silver/compiler/driver/CompileGrammar.sv b/grammars/silver/compiler/driver/CompileGrammar.sv index 473abf65c..200c59119 100644 --- a/grammars/silver/compiler/driver/CompileGrammar.sv +++ b/grammars/silver/compiler/driver/CompileGrammar.sv @@ -44,6 +44,7 @@ MaybeT ::= -- IO Step 5: Check for an old interface file, to tell if we need to transitively re-translate oldInterface::Maybe <- lift(do { + guard(!clean); -- Skip this if we are doing a clean build anyway, to avoid comparing old interface files. gen :: String <- findInterfaceLocation(gramPath, benv.silverHostGen); let file :: String = gen ++ "src/" ++ gramPath ++ "Silver.svi"; --lift(eprintln(s"Found old interface ${file}")); From 049dafdbb995e8b746565f5732c93e43fab31eae Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 2 Oct 2023 12:42:46 -0500 Subject: [PATCH 047/283] Fix overlapping pattern error filtering for convenience aspects --- .../compiler/extension/convenienceaspects/AbstractSyntax.sv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv b/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv index c0f282070..d078072d9 100644 --- a/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv +++ b/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv @@ -579,7 +579,8 @@ top::AGDcl ::= attr::QNameAttrOccur aspectLHS::Decorated ConvAspectLHS eqKind::C \message::Message -> -- Note: If you see this error unexpectedly that might mean the string for this error has changed. case message of - | err(l, "Pattern has overlapping cases!") when l == getParsedOriginLocationOrFallback(top) -> false + | err(l, "Pattern has overlapping cases!") + when contains(l, map(getParsedOriginLocationOrFallback, ml.matchRuleList)) -> false | _ -> true end, forward.errors); From 6db29b46cb994610e1a63a38e0a49a0a926be1fc Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 2 Oct 2023 13:51:09 -0500 Subject: [PATCH 048/283] Fix location handling for silver construction antiquotes --- .../silverconstruction/Translation.sv | 18 ++++++++---------- .../compiler/metatranslation/Translation.sv | 1 + 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/grammars/silver/compiler/extension/silverconstruction/Translation.sv b/grammars/silver/compiler/extension/silverconstruction/Translation.sv index e6d536c4e..6fb289e1e 100644 --- a/grammars/silver/compiler/extension/silverconstruction/Translation.sv +++ b/grammars/silver/compiler/extension/silverconstruction/Translation.sv @@ -21,35 +21,33 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs -- "Indirect" antiquote productions antiquoteTranslation <- - case prodName, children, annotations of + case prodName, children of | "silver:compiler:extension:silverconstruction:antiquote_qName", - consAST(_, consAST(_, consAST(a, consAST(_, nilAST())))), - consNamedAST(namedAST("silver:core:location", locAST), nilNamedAST()) -> + consAST(_, consAST(_, consAST(a, consAST(_, nilAST())))) -> case reify(a) of | right(e) -> just( mkFullFunctionInvocation( baseExpr(qName("silver:compiler:metatranslation:makeQName")), - [e, locAST.translation], + [e, translate(reflect(givenLocation))], [])) | left(msg) -> error(s"Error in reifying child of production ${prodName}:\n${msg}") end - | "silver:compiler:extension:silverconstruction:antiquote_qName", _, _ -> + | "silver:compiler:extension:silverconstruction:antiquote_qName", _ -> error(s"Unexpected antiquote production arguments: ${show(80, top.pp)}") | "silver:compiler:extension:silverconstruction:antiquote_name", - consAST(_, consAST(_, consAST(a, consAST(_, nilAST())))), - consNamedAST(namedAST("silver:core:location", locAST), nilNamedAST()) -> + consAST(_, consAST(_, consAST(a, consAST(_, nilAST())))) -> case reify(a) of | right(e) -> just( mkFullFunctionInvocation( baseExpr(qName("silver:compiler:metatranslation:makeName")), - [e, locAST.translation], + [e, translate(reflect(givenLocation))], [])) | left(msg) -> error(s"Error in reifying child of production ${prodName}:\n${msg}") end - | "silver:compiler:extension:silverconstruction:antiquote_name", _, _ -> + | "silver:compiler:extension:silverconstruction:antiquote_name", _ -> error(s"Unexpected antiquote production arguments: ${show(80, top.pp)}") - | _, _, _ -> nothing() + | _, _ -> nothing() end; } diff --git a/grammars/silver/compiler/metatranslation/Translation.sv b/grammars/silver/compiler/metatranslation/Translation.sv index 153cfe654..07af1c188 100644 --- a/grammars/silver/compiler/metatranslation/Translation.sv +++ b/grammars/silver/compiler/metatranslation/Translation.sv @@ -42,6 +42,7 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs { production givenLocation::Location = fromMaybe(top.givenLocation, alt(getParsedOriginLocation(top), alt(children.foundLocation, annotations.foundLocation))); + attachNote logicalLocationNote(givenLocation); -- In case the quoted language doesn't use origins production attribute antiquoteTranslation::Maybe with orElse; antiquoteTranslation := nothing(); From 28ec9ccfc283ea6213616a2e0cd86342623a5c4e Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 2 Oct 2023 13:57:51 -0500 Subject: [PATCH 049/283] Fix flow errors using tree sharing --- grammars/silver/compiler/definition/core/Expr.sv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index cb15bb5e8..45779e6fb 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -302,17 +302,17 @@ top::Expr ::= e::Expr '(' es::AppExprs ',' anns::AnnoAppExprs ')' concrete production applicationAnno top::Expr ::= e::Expr '(' anns::AnnoAppExprs ')' { - forwards to application(e, $2, emptyAppExprs(), ',', anns, $4); + forwards to application(@e, $2, emptyAppExprs(), ',', @anns, $4); } concrete production applicationExpr top::Expr ::= e::Expr '(' es::AppExprs ')' { - forwards to application(e, $2, es, ',', emptyAnnoAppExprs(), $4); + forwards to application(@e, $2, @es, ',', emptyAnnoAppExprs(), $4); } concrete production applicationEmpty top::Expr ::= e::Expr '(' ')' { - forwards to application(e, $2, emptyAppExprs(), ',', emptyAnnoAppExprs(), $3); + forwards to application(@e, $2, emptyAppExprs(), ',', emptyAnnoAppExprs(), $3); } abstract production errorApplication From da2cf6f0f8535358c2c6ba8c96c91df6e46bb5cd Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 2 Oct 2023 14:09:04 -0500 Subject: [PATCH 050/283] Fix a flow error --- .../compiler/extension/convenienceaspects/AbstractSyntax.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv b/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv index d078072d9..7f2ddad32 100644 --- a/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv +++ b/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv @@ -580,7 +580,7 @@ top::AGDcl ::= attr::QNameAttrOccur aspectLHS::Decorated ConvAspectLHS eqKind::C -- Note: If you see this error unexpectedly that might mean the string for this error has changed. case message of | err(l, "Pattern has overlapping cases!") - when contains(l, map(getParsedOriginLocationOrFallback, ml.matchRuleList)) -> false + when contains(l, map(getParsedOriginLocationOrFallback, mList)) -> false | _ -> true end, forward.errors); From 4b24baa41c90422fecf88a5da5542e0ecf6b6301 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 2 Oct 2023 14:24:41 -0500 Subject: [PATCH 051/283] Fix another flow error --- grammars/silver/compiler/modification/list/List.sv | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/grammars/silver/compiler/modification/list/List.sv b/grammars/silver/compiler/modification/list/List.sv index 43a096e56..7711b899d 100644 --- a/grammars/silver/compiler/modification/list/List.sv +++ b/grammars/silver/compiler/modification/list/List.sv @@ -58,6 +58,11 @@ top::Expr ::= h::Expr '::' t::Expr { top.unparse = "(" ++ h.unparse ++ " :: " ++ t.unparse ++ ")" ; + h.decSiteVertexInfo = nothing(); + h.alwaysDecorated = false; + t.decSiteVertexInfo = nothing(); + t.alwaysDecorated = false; + forwards to Silver_Expr { silver:core:cons($Expr{@h}, $Expr{@t}) }; } From 6cf219a685a18ae4c35534fb1bdef0ebf3ea86c3 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 2 Oct 2023 18:18:44 -0500 Subject: [PATCH 052/283] Make QNameLookup tracked --- grammars/silver/compiler/definition/core/QName.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/compiler/definition/core/QName.sv b/grammars/silver/compiler/definition/core/QName.sv index 5cbc82c34..b8d46b070 100644 --- a/grammars/silver/compiler/definition/core/QName.sv +++ b/grammars/silver/compiler/definition/core/QName.sv @@ -67,7 +67,7 @@ top::QName ::= msg::[Message] top.lookupAttribute = errorLookup(msg); } -data nonterminal QNameLookup with fullName, typeScheme, errors, dcls, dcl, found; +tracked data nonterminal QNameLookup with fullName, typeScheme, errors, dcls, dcl, found; synthesized attribute lookupValue :: QNameLookup occurs on QName; synthesized attribute lookupType :: QNameLookup occurs on QName; From 689196c3c786272991daa5acc87016c2899af850 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 2 Oct 2023 18:19:07 -0500 Subject: [PATCH 053/283] Fix default terminal location bug --- grammars/silver/compiler/definition/core/Expr.sv | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index 45779e6fb..5043e3f21 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -914,8 +914,11 @@ top::Expr ::= 'terminal' '(' t::TypeExpr ',' es::Expr ',' el::Expr ')' concrete production terminalFunction top::Expr ::= 'terminal' '(' t::TypeExpr ',' e::Expr ')' { - local locExpr :: Expr = - Silver_Expr { getParsedOriginLocationOrFallback(ambientOrigin()) }; + local locExpr :: Expr = Silver_Expr { + silver:core:fromMaybe( + silver:core:bogusLoc(), + silver:core:getParsedOriginLocation(silver:core:ambientOrigin())) + }; forwards to terminalConstructor($1, $2, t, $4, e, ',', locExpr, $6); } From 693ac6179cbc601cb6458c36bb8a8a41c74e9229 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 3 Oct 2023 11:11:07 -0500 Subject: [PATCH 054/283] Remove workaround for rewriting transform on consListOp --- grammars/silver/compiler/extension/rewriting/Expr.sv | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index a518ab4c7..47c1db8bb 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -572,14 +572,7 @@ top::Expr ::= '[' ']' aspect production consListOp top::Expr ::= h::Expr '::' t::Expr { - top.transform = - -- This is a forwarding prod, so we can't decorate e1 and e2 with boundVars here. - -- TODO: need some way for the flow analysis to track that e1 and e2 will be provided with boundVars through the forward. - case forward of - | functionInvocation(_, snocAppExprs(snocAppExprs(emptyAppExprs(), _, decH), _, decT), _) -> - consListASTExpr(decH.transform, decT.transform) - | _ -> error("Unexpected forward") - end; + top.transform = consListASTExpr(h.transform, t.transform); } aspect production fullList From 2e829d70587293d65007c4cbbd1098dda92935fd Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 3 Oct 2023 21:58:34 -0500 Subject: [PATCH 055/283] Add missing equation current missed by MWDA due to #810 --- grammars/silver/compiler/extension/rewriting/Expr.sv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index 47c1db8bb..bf6736262 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -4,7 +4,7 @@ grammar silver:compiler:extension:rewriting; -- the variable was explicitly (i.e. not implicitly) decorated in the pattern. inherited attribute boundVars::[Pair] occurs on Expr, Exprs, ExprInhs, ExprInh, AppExprs, AppExpr, AnnoAppExprs, AnnoExpr, AssignExpr, PrimPatterns, PrimPattern; propagate boundVars on Expr, Exprs, ExprInhs, ExprInh, AppExprs, AppExpr, AnnoAppExprs, AnnoExpr, AssignExpr, PrimPatterns, PrimPattern - excluding baseExpr, application, access, letp, prodPatternNormal, prodPatternGadt; + excluding letp, prodPatternNormal, prodPatternGadt; attribute transform occurs on Expr; @@ -572,6 +572,7 @@ top::Expr ::= '[' ']' aspect production consListOp top::Expr ::= h::Expr '::' t::Expr { + propagate boundVars; top.transform = consListASTExpr(h.transform, t.transform); } From c3d076ba1b1788e433186026d226ebf70f6c307d Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 3 Oct 2023 23:21:24 -0500 Subject: [PATCH 056/283] Avoid reading and deserializing interface files twice --- .../silver/compiler/driver/CompileGrammar.sv | 37 ++++++++++--------- .../compiler/driver/CompileInterface.sv | 12 ++---- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/grammars/silver/compiler/driver/CompileGrammar.sv b/grammars/silver/compiler/driver/CompileGrammar.sv index 473abf65c..33e3e8ccd 100644 --- a/grammars/silver/compiler/driver/CompileGrammar.sv +++ b/grammars/silver/compiler/driver/CompileGrammar.sv @@ -21,16 +21,25 @@ MaybeT ::= -- IO Step 2: List those files, and obtain their newest modification time files :: [String] <- lift(listSilverFiles(grammarLocation)); - when_(null(files), empty); -- Grammar had no files! + guard(!null(files)); -- Grammar had no files! grammarTime :: Integer <- lift(fileTimes(grammarLocation, files)); return (grammarTime, grammarLocation, files); }.run); + findInterface::Maybe <- lift(do { + guard(!clean); -- Ignore interface files if this is a clean build + + -- IO Step 3: Let's look for an interface file + compileInterface(grammarName, benv.silverHostGen); + }.run); + let interfaceDirty::Boolean = do { + -- If we found both, check if the interface file is out of date + foundGrammar::(Integer, String, [String]) <- findGrammar; + foundInterface::RootSpec <- findInterface; + guard(foundGrammar.1 > foundInterface.grammarTime); + }.isJust; alt( - -- IO Step 3: Let's look for a valid interface file - if clean - then empty -- We just skip this search if it's a clean build - else compileInterface(grammarName, benv.silverHostGen, map(fst, findGrammar)), + if interfaceDirty then empty else maybeT(pure(findInterface)), do { -- We didn't find a valid interface file foundGrammar::(Integer, String, [String]) <- maybeT(pure(findGrammar)); @@ -42,18 +51,12 @@ MaybeT ::= lift(eprintln("Compiling " ++ grammarName ++ "\n\t[" ++ grammarLocation ++ "]\n\t[" ++ renderFileNames(files, 0) ++ "]")); gramCompile::([Root], [ParseError]) <- lift(compileFiles(svParser, grammarLocation, files)); - -- IO Step 5: Check for an old interface file, to tell if we need to transitively re-translate - oldInterface::Maybe <- lift(do { - gen :: String <- findInterfaceLocation(gramPath, benv.silverHostGen); - let file :: String = gen ++ "src/" ++ gramPath ++ "Silver.svi"; - --lift(eprintln(s"Found old interface ${file}")); - content::ByteArray <- lift(readBinaryFile(file)); - case nativeDeserialize(content) of - | left(msg) -> empty - | right(ii) -> pure(ii) - end; - }.run); - + -- The old interface file contents, used to tell if we need to transitively re-translate + let oldInterface::Maybe = + case findInterface of + | just(interfaceRootSpec(i, _)) -> just(i) + | _ -> nothing() + end; return if null(gramCompile.2) then grammarRootSpec(foldRoot(gramCompile.1), oldInterface, grammarName, grammarLocation, grammarTime, benv.silverGen) else errorRootSpec(gramCompile.2, grammarName, grammarLocation, grammarTime, benv.silverGen); diff --git a/grammars/silver/compiler/driver/CompileInterface.sv b/grammars/silver/compiler/driver/CompileInterface.sv index 4c477303b..ba3d2a424 100644 --- a/grammars/silver/compiler/driver/CompileInterface.sv +++ b/grammars/silver/compiler/driver/CompileInterface.sv @@ -4,14 +4,13 @@ import silver:reflect; import silver:reflect:nativeserialize; {-- - - Find an interface file, if it exists, and it's valid (parsable and modification time is newer). + - Find an interface file, if it exists, and can be deserialized. - - @param grammarName The grammar we're looking for an interface file for - @param silverHostGen The search path to look for interface files within - - @param grammarTime The newest modification time of the source files, to compare against -} function compileInterface -MaybeT ::= grammarName::String silverHostGen::[String] grammarTime::Maybe +MaybeT ::= grammarName::String silverHostGen::[String] { local gramPath :: String = grammarToPath(grammarName); @@ -41,12 +40,7 @@ MaybeT ::= grammarName::String silverHostGen::[String] grammarTim "\n\tRecovering by parsing grammar....")); empty; } - | right(i) -> - case grammarTime of - -- Fail if the grammar sources are newer than the ones used to build the interface file - | just(t) when t > i.maybeGrammarTime.fromJust -> empty - | _ -> pure(interfaceRootSpec(i, gen)) - end + | right(i) -> pure(interfaceRootSpec(i, gen)) end; }; } From 5e7e97ec909aa049599d45281e11fe0b934e90c5 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 4 Oct 2023 11:04:26 -0500 Subject: [PATCH 057/283] Reinstate consListOp transform hack due to flow analysis deficiencies --- grammars/silver/compiler/extension/rewriting/Expr.sv | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index bf6736262..07acba388 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -572,8 +572,15 @@ top::Expr ::= '[' ']' aspect production consListOp top::Expr ::= h::Expr '::' t::Expr { - propagate boundVars; - top.transform = consListASTExpr(h.transform, t.transform); + top.transform = + -- TODO: We should be able to override boundVars on h and t here, + -- but currently the flow analysis forbids this due to the hidden + -- transitive dependencies check. + case forward of + | functionInvocation(_, snocAppExprs(oneAppExprs(presentAppExpr(decH)), _, presentAppExpr(decT)), _) -> + consListASTExpr(decH.transform, decT.transform) + | _ -> error("Unexpected forward: " ++ hackUnparse(forward)) + end; } aspect production fullList From 56d9d2ad8c385dd44849e6230082d9fe4f7ffbaa Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 4 Oct 2023 11:27:54 -0500 Subject: [PATCH 058/283] Add comment --- grammars/silver/compiler/analysis/warnings/flow/Inh.sv | 2 +- grammars/silver/compiler/extension/rewriting/Expr.sv | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index b0d12f7d5..1cee4d8f0 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -274,7 +274,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur local lhsInhExceedsForwardFlowType :: [String] = set:toList( set:removeAll( - [dl.inhAttrName], + [dl.inhAttrName], -- TODO: I don't think excluding this is well-founded? set:difference( lhsInhDeps, inhDepsForSyn("forward", top.frame.lhsNtName, myFlow)))); diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index 07acba388..969094b2b 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -572,7 +572,7 @@ top::Expr ::= '[' ']' aspect production consListOp top::Expr ::= h::Expr '::' t::Expr { - top.transform = + top.transform = -- TODO: We should be able to override boundVars on h and t here, -- but currently the flow analysis forbids this due to the hidden -- transitive dependencies check. From 409f2392c8128c7310e31780d261375d14d9e4cc Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 4 Oct 2023 11:36:59 -0500 Subject: [PATCH 059/283] Revert "Temporarily exclude location annotation in metatranslation" This reverts commit f6550eddcfabd3ab01698432b0807b2c1bf465bd. --- grammars/silver/compiler/metatranslation/Translation.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/compiler/metatranslation/Translation.sv b/grammars/silver/compiler/metatranslation/Translation.sv index 07af1c188..00814a727 100644 --- a/grammars/silver/compiler/metatranslation/Translation.sv +++ b/grammars/silver/compiler/metatranslation/Translation.sv @@ -127,7 +127,7 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs mkFullFunctionInvocation( baseExpr(qName(prodName)), children.translation, - filter(\ a::(String, Expr) -> a.1 != "location", annotations.translation)), + annotations.translation), antiquoteTranslation); production attribute patternAntiquoteTranslation::Maybe with orElse; From c0859f477bda7384033d243097aa87f8dc0fc757 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 4 Oct 2023 22:10:48 -0500 Subject: [PATCH 060/283] Revert TODO comment, I was looking at the wrong equation --- grammars/silver/compiler/analysis/warnings/flow/Inh.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index 1cee4d8f0..b0d12f7d5 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -274,7 +274,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur local lhsInhExceedsForwardFlowType :: [String] = set:toList( set:removeAll( - [dl.inhAttrName], -- TODO: I don't think excluding this is well-founded? + [dl.inhAttrName], set:difference( lhsInhDeps, inhDepsForSyn("forward", top.frame.lhsNtName, myFlow)))); From 2f29f392956c45a5279b0fc244a207a9a9902b39 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 5 Oct 2023 11:04:00 -0500 Subject: [PATCH 061/283] Update package-lock.json --- support/vs-code/silverlsp/package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/support/vs-code/silverlsp/package-lock.json b/support/vs-code/silverlsp/package-lock.json index 09008ea18..03b8a5d7f 100644 --- a/support/vs-code/silverlsp/package-lock.json +++ b/support/vs-code/silverlsp/package-lock.json @@ -1,12 +1,12 @@ { "name": "silverlsp", - "version": "0.0.4", + "version": "0.0.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "silverlsp", - "version": "0.0.4", + "version": "0.0.5", "license": "LGPL-3.0-or-later", "dependencies": { "vscode-languageclient": "8.0.1" From d5175e09803726a318fc2a996d2cf2de3b56a1a7 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 5 Oct 2023 11:04:11 -0500 Subject: [PATCH 062/283] Fix indentation --- .../silver/compiler/analysis/uniqueness/Expr.sv | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/grammars/silver/compiler/analysis/uniqueness/Expr.sv b/grammars/silver/compiler/analysis/uniqueness/Expr.sv index c3b932069..eb5a83f51 100644 --- a/grammars/silver/compiler/analysis/uniqueness/Expr.sv +++ b/grammars/silver/compiler/analysis/uniqueness/Expr.sv @@ -22,7 +22,7 @@ top::Expr ::= aspect production childReference top::Expr ::= q::Decorated! QName { - top.uniqueRefs <- + top.uniqueRefs <- case top.finalType, refSet of | uniqueDecoratedType(_, _), just(inhs) when isExportedBy(top.grammarName, [q.lookupValue.dcl.sourceGrammar], top.compiledGrammars) -> @@ -53,7 +53,7 @@ top::Expr ::= q::Decorated! QName aspect production localReference top::Expr ::= q::Decorated! QName { - top.uniqueRefs <- + top.uniqueRefs <- case top.finalType, refSet of | uniqueDecoratedType(_, _), just(inhs) when isExportedBy(top.grammarName, [q.lookupValue.dcl.sourceGrammar], top.compiledGrammars) -> @@ -84,7 +84,7 @@ top::Expr ::= q::Decorated! QName aspect production lhsReference top::Expr ::= q::Decorated! QName { - top.errors <- + top.errors <- case top.finalType of | uniqueDecoratedType(_, _) -> [errFromOrigin(top, s"Cannot take a unique reference of type ${prettyType(top.finalType)} to ${q.name}.")] @@ -94,7 +94,7 @@ top::Expr ::= q::Decorated! QName aspect production forwardReference top::Expr ::= q::Decorated! QName { - top.errors <- + top.errors <- case top.finalType of | uniqueDecoratedType(_, _) -> [errFromOrigin(top, s"Cannot take a unique reference of type ${prettyType(top.finalType)} to the forward tree.")] @@ -220,7 +220,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur aspect production transDecoratedAccessHandler top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur { - top.uniqueRefs := + top.uniqueRefs := case top.finalType, refSet of | uniqueDecoratedType(_, _), just(inhs) -> [(case e.flowVertexInfo of @@ -311,7 +311,7 @@ top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'else' e3::Expr aspect production lambdaParamReference top::Expr ::= q::Decorated! QName { - top.uniqueRefs <- + top.uniqueRefs <- if top.finalType.isUniqueDecorated then [(q.name, uniqueRefSite( refSet=top.finalType.inhSetMembers, @@ -340,7 +340,7 @@ top::Expr ::= params::ProductionRHS e::Expr aspect production lexicalLocalReference top::Expr ::= q::Decorated! QName fi::Maybe fd::[FlowVertex] rs::[(String, UniqueRefSite)] { - top.errors <- + top.errors <- -- This check is needed due to how we handle let binding auto-undecoration in the type system: -- unique and regular references can both undecorate and unique references can become regular ones, -- but ensure that we don't create a unique reference out of a regular one. From 7521713bcc10815f08682cd292e1a0f32ee302e5 Mon Sep 17 00:00:00 2001 From: unironically Date: Mon, 2 Oct 2023 19:11:26 -0500 Subject: [PATCH 063/283] Introducing NTs LambdaRHS, LambdaRHSElem. Productions lambda_c_new, lambdap_new. lambdap -> lambdap_new for all aspects. --- .../compiler/analysis/uniqueness/Expr.sv | 6 +- .../compiler/definition/flow/env/Expr.sv | 4 +- .../definition/type/syntax/ProductionDcl.sv | 7 + .../extension/implicit_monads/Lambda.sv | 6 +- .../compiler/modification/lambda_fn/Lambda.sv | 166 ++++++++++++++++-- .../modification/lambda_fn/Project.sv | 1 + .../modification/lambda_fn/java/Lambda.sv | 4 +- 7 files changed, 168 insertions(+), 26 deletions(-) diff --git a/grammars/silver/compiler/analysis/uniqueness/Expr.sv b/grammars/silver/compiler/analysis/uniqueness/Expr.sv index eb5a83f51..70e767ba6 100644 --- a/grammars/silver/compiler/analysis/uniqueness/Expr.sv +++ b/grammars/silver/compiler/analysis/uniqueness/Expr.sv @@ -8,7 +8,7 @@ propagate uniqueRefs on Expr, Exprs, AppExprs, AppExpr, PrimPatterns, PrimPatter transDecoratedAccessHandler, annoAccessHandler, synDataAccessHandler, unknownDclAccessHandler, inhUndecoratedAccessErrorHandler, transUndecoratedAccessErrorHandler, - ifThenElse, lambdap, letp, matchPrimitiveReal, consPattern; + ifThenElse, lambdap, lambdap_new, letp, matchPrimitiveReal, consPattern; -- Unique references taken when this expression is wrapped in an attribute access synthesized attribute accessUniqueRefs::[(String, UniqueRefSite)] occurs on Expr; @@ -323,8 +323,8 @@ top::Expr ::= q::Decorated! QName top.accessUniqueRefs = []; } -aspect production lambdap -top::Expr ::= params::ProductionRHS e::Expr +aspect production lambdap_new +top::Expr ::= params::LambdaRHS e::Expr { top.uniqueRefs := filter(\ r::(String, UniqueRefSite) -> !contains(r.1, params.lambdaBoundVars), e.uniqueRefs); top.errors <- flatMap(\ n::String -> diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index 3e785bbff..127308520 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -541,8 +541,8 @@ top::Exprs ::= e1::Expr ',' e2::Exprs e1.alwaysDecorated = false; } -aspect production lambdap -top::Expr ::= params::ProductionRHS e::Expr +aspect production lambdap_new +top::Expr ::= params::LambdaRHS e::Expr { e.decSiteVertexInfo = nothing(); e.alwaysDecorated = false; diff --git a/grammars/silver/compiler/definition/type/syntax/ProductionDcl.sv b/grammars/silver/compiler/definition/type/syntax/ProductionDcl.sv index e457072ab..30350a31f 100644 --- a/grammars/silver/compiler/definition/type/syntax/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/type/syntax/ProductionDcl.sv @@ -28,3 +28,10 @@ top::ProductionRHS ::= h::ProductionRHSElem t::ProductionRHS { top.lexicalTypeVariables := nub(h.lexicalTypeVariables ++ t.lexicalTypeVariables); } + +--aspect production lambdaRHSCons +--top::ProductionRHS ::= h::LambdaRHSElem t::LambdaRHS +--{ +-- top.lexicalTypeVariables := nub(h.lexicalTypeVariables ++ t.lexicalTypeVariables); +--} + diff --git a/grammars/silver/compiler/extension/implicit_monads/Lambda.sv b/grammars/silver/compiler/extension/implicit_monads/Lambda.sv index 542a38971..3fae077eb 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Lambda.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Lambda.sv @@ -1,7 +1,7 @@ grammar silver:compiler:extension:implicit_monads; -aspect production lambdap -top::Expr ::= params::ProductionRHS e::Expr +aspect production lambdap_new +top::Expr ::= params::LambdaRHS e::Expr { top.merrors := e.merrors; propagate mDownSubst, mUpSubst; @@ -11,7 +11,7 @@ top::Expr ::= params::ProductionRHS e::Expr e.monadicallyUsed = false; top.monadicNames = e.monadicNames; - top.monadRewritten = lambdap(params, e.monadRewritten); + top.monadRewritten = lambdap_new(params, e.monadRewritten); } diff --git a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv index 155dfd50a..5f9a6bb97 100644 --- a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv +++ b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv @@ -1,24 +1,19 @@ import silver:compiler:definition:env; import silver:util:treeset as ts; ---- Concrete Syntax for lambdas +--- New concrete Syntax for lambdas -------------------------------------------------------------------------------- -terminal Lambda_kwd '\' lexer classes {KEYWORD,RESERVED}; -terminal Arrow_t '->' precedence = 0, lexer classes {SPECOP}; - --- Using ProductionRHS here, it is basicly just a list of names with type expressions --- It is also used for the parameter definitions in functions, so using it here for consistancy -concrete production lambda_c -top::Expr ::= '\' params::ProductionRHS '->' e::Expr +abstract production lambda_c_new +top::Expr ::= '\' params::LambdaRHS '->' e::Expr { top.unparse = "\\ " ++ params.unparse ++ " -> " ++ e.unparse; - forwards to lambdap(params, e); + forwards to lambdap_new(params, e); } -abstract production lambdap -top::Expr ::= params::ProductionRHS e::Expr +abstract production lambdap_new +top::Expr ::= params::LambdaRHS e::Expr { top.unparse = "\\ " ++ params.unparse ++ " -> " ++ e.unparse; top.freeVars := ts:removeAll(params.lambdaBoundVars, e.freeVars); @@ -44,6 +39,125 @@ top::Expr ::= params::ProductionRHS e::Expr e.isRoot = false; } + +nonterminal LambdaRHS with + --location, + givenLambdaParamIndex, givenLambdaId, env, grammarName, flowEnv, + lambdaBoundVars, lambdaDefs, lexicalTypeVariables, lexicalTyVarKinds, inputElements, unparse, elementCount; + +nonterminal LambdaRHSElem with + --location, + givenLambdaParamIndex, givenLambdaId, grammarName, deterministicCount, env, flowEnv, + lambdaBoundVars, lambdaDefs, unparse, lexicalTypeVariables, inputElements, lexicalTyVarKinds; + + +{- How much of the below belongs in other grammars? -} + +flowtype decorate {forward, grammarName, flowEnv} on LambdaRHS, LambdaRHSElem; +flowtype forward {env} on LambdaRHS; +flowtype forward {deterministicCount, env} on LambdaRHSElem; + +flowtype lambdaDefs {decorate, givenLambdaId, givenLambdaParamIndex} on LambdaRHS, LambdaRHSElem; +flowtype lambdaBoundVars {} on LambdaRHS; +flowtype lambdaBoundVars {deterministicCount} on LambdaRHSElem; + +propagate lambdaDefs, lambdaBoundVars on LambdaRHS; +propagate flowEnv, env, grammarName, givenLambdaId, lexicalTyVarKinds on LambdaRHS, LambdaRHSElem; +propagate lexicalTypeVariables on LambdaRHS, LambdaRHSElem excluding lambdaRHSCons; + + +{- LambdaRHS productions -} + +concrete production lambdaRHSCons +top::LambdaRHS ::= h::LambdaRHSElem t::LambdaRHS +{ + t.givenLambdaParamIndex = top.givenLambdaParamIndex + 1; + h.givenLambdaParamIndex = top.givenLambdaParamIndex; + + top.lexicalTypeVariables := nub(h.lexicalTypeVariables ++ t.lexicalTypeVariables); + top.inputElements = h.inputElements ++ t.inputElements; + + top.unparse = h.unparse ++ " " ++ t.unparse; + + h.deterministicCount = t.elementCount; + top.elementCount = 1 + t.elementCount; +} + +concrete production lambdaRHSNil +top::LambdaRHS ::= +{ + top.inputElements = []; + top.unparse = ""; + top.elementCount = 0; +} + +{- LambdaRHSElem productions -} + +concrete production lambdaRHSElemIdTy +top::LambdaRHSElem ::= id::Name '::' t::TypeExpr +{ + production fName :: String = toString(genInt()) ++ ":" ++ id.name; + top.lambdaDefs := [lambdaParamDef(top.grammarName, id.nameLoc, fName, t.typerep, top.givenLambdaId, top.givenLambdaParamIndex)]; + top.lambdaBoundVars := [id.name]; + + top.inputElements = [namedSignatureElement(id.name, t.typerep)]; + + top.unparse = id.unparse ++ "::" ++ t.unparse; +} + +concrete production lambdaRHSElemTy +top::LambdaRHSElem ::= '_' '::' t::TypeExpr +{ + top.unparse = "_::" ++ t.unparse; + + forwards to lambdaRHSElemIdTy ( + name("_G_" ++ toString(top.deterministicCount)), + '::', + t); +} + +concrete production lambdaRHSElemId +top::LambdaRHSElem ::= id::Name +{ + top.unparse = id.unparse; + + forwards to lambdaRHSElemIdTy ( + id, + '::', + typerepTypeExpr(freshType())); +} + +concrete production lambdaRHSElemUnderline +top::LambdaRHSElem ::= '_' +{ + top.unparse = "_"; + + forwards to lambdaRHSElemIdTy ( + name("_G_" ++ toString(top.deterministicCount)), + '::', + typerepTypeExpr(freshType())); +} + +--- Old concrete Syntax for lambdas +-------------------------------------------------------------------------------- + +terminal Lambda_kwd '\' lexer classes {KEYWORD,RESERVED}; +terminal Arrow_t '->' precedence = 0, lexer classes {SPECOP}; + +-- Using ProductionRHS here, it is basicly just a list of names with type expressions +-- It is also used for the parameter definitions in functions, so using it here for consistancy +concrete production lambda_c +top::Expr ::= '\' params::ProductionRHS '->' e::Expr +{ + forwards to lambda_c_new ('\', params.asLamRHS, '->', @e); +} + +abstract production lambdap +top::Expr ::= params::ProductionRHS e::Expr +{ + forwards to lambdap_new (params.asLamRHS, @e); +} + monoid attribute lambdaDefs::[Def]; monoid attribute lambdaBoundVars::[String]; attribute lambdaDefs, lambdaBoundVars occurs on ProductionRHS, ProductionRHSElem; @@ -58,20 +172,40 @@ inherited attribute givenLambdaId::Integer occurs on ProductionRHS, ProductionRH inherited attribute givenLambdaParamIndex::Integer occurs on ProductionRHS, ProductionRHSElem; propagate givenLambdaId on ProductionRHS, ProductionRHSElem; +synthesized attribute asLamRHS::LambdaRHS occurs on ProductionRHS; +synthesized attribute asLamRHSElem::LambdaRHSElem occurs on ProductionRHSElem; + aspect production productionRHSCons top::ProductionRHS ::= h::ProductionRHSElem t::ProductionRHS { - t.givenLambdaParamIndex = top.givenLambdaParamIndex + 1; - h.givenLambdaParamIndex = top.givenLambdaParamIndex; + --t.givenLambdaParamIndex = top.givenLambdaParamIndex + 1; + --h.givenLambdaParamIndex = top.givenLambdaParamIndex; + top.asLamRHS = lambdaRHSCons (h.asLamRHSElem, t.asLamRHS); +} + +aspect production productionRHSNil +top::ProductionRHS ::= +{ + top.asLamRHS = lambdaRHSNil (); } aspect production productionRHSElem top::ProductionRHSElem ::= id::Name '::' t::TypeExpr { - production fName :: String = toString(genInt()) ++ ":" ++ id.name; + {-production fName :: String = toString(genInt()) ++ ":" ++ id.name; -- production transName :: String = "lambda_param" ++ id.name ++ toString(genInt()); - top.lambdaDefs := [lambdaParamDef(top.grammarName, id.nameLoc, fName, t.typerep, top.givenLambdaId, top.givenLambdaParamIndex)]; - top.lambdaBoundVars := [id.name]; + top.lambdaDefs := [lambdaParamDef(top.grammarName, t.location, fName, t.typerep, top.givenLambdaId, top.givenLambdaParamIndex)]; + top.lambdaBoundVars := [id.name];-} + + top.asLamRHSElem = lambdaRHSElemIdTy(id, '::', t); +} + +aspect production productionRHSElemType +top::ProductionRHSElem ::= t::TypeExpr +{ + --forwards to productionRHSElem(name("_G_" ++ toString(top.deterministicCount), t.location), '::', t, location=top.location); + + top.asLamRHSElem = lambdaRHSElemTy('_', '::', t); } abstract production lambdaParamReference diff --git a/grammars/silver/compiler/modification/lambda_fn/Project.sv b/grammars/silver/compiler/modification/lambda_fn/Project.sv index 081dffb75..1c56671fc 100644 --- a/grammars/silver/compiler/modification/lambda_fn/Project.sv +++ b/grammars/silver/compiler/modification/lambda_fn/Project.sv @@ -6,6 +6,7 @@ imports silver:compiler:definition:type; imports silver:compiler:definition:type:syntax; imports silver:compiler:analysis:typechecking:core; imports silver:compiler:analysis:uniqueness; +imports silver:compiler:definition:flow:env; exports silver:compiler:modification:lambda_fn:java with silver:compiler:translation:java:core; exports silver:compiler:modification:lambda_fn:java with silver:compiler:translation:java:type; diff --git a/grammars/silver/compiler/modification/lambda_fn/java/Lambda.sv b/grammars/silver/compiler/modification/lambda_fn/java/Lambda.sv index 8a04c296b..fb69aaece 100644 --- a/grammars/silver/compiler/modification/lambda_fn/java/Lambda.sv +++ b/grammars/silver/compiler/modification/lambda_fn/java/Lambda.sv @@ -11,8 +11,8 @@ import silver:compiler:analysis:typechecking:core only finalType; import silver:compiler:translation:java:core; import silver:compiler:translation:java:type; -aspect production lambdap -top::Expr ::= params::ProductionRHS e::Expr +aspect production lambdap_new +top::Expr ::= params::LambdaRHS e::Expr { -- Attempt to solve a context `runtimeTypeable ${top.finalType)}`, from which the runtime TypeRep translation is computed. -- If the type somehow contains a skolem (e.g. through scoped type variables), From 8266c0de1633a75dbb881be2e23b68cdc39cb317 Mon Sep 17 00:00:00 2001 From: unironically Date: Mon, 2 Oct 2023 20:12:21 -0500 Subject: [PATCH 064/283] Changing explicit use of lambdap to lambdap_new --- .../compiler/extension/do_notation/Project.sv | 3 +- .../compiler/extension/do_notation/Syntax.sv | 23 +++++------ .../extension/implicit_monads/Expr.sv | 36 ++++++++--------- .../implicit_monads/PrimitiveMatch.sv | 14 +++---- .../extension/implicit_monads/Project.sv | 2 +- .../compiler/extension/rewriting/Expr.sv | 40 +++++++++---------- 6 files changed, 58 insertions(+), 60 deletions(-) diff --git a/grammars/silver/compiler/extension/do_notation/Project.sv b/grammars/silver/compiler/extension/do_notation/Project.sv index 0b51ef27d..0e847b0d1 100644 --- a/grammars/silver/compiler/extension/do_notation/Project.sv +++ b/grammars/silver/compiler/extension/do_notation/Project.sv @@ -11,5 +11,4 @@ imports silver:compiler:extension:convenience; imports silver:compiler:extension:tuple; imports silver:compiler:modification:lambda_fn; imports silver:compiler:modification:let_fix; -imports silver:compiler:metatranslation; - +imports silver:compiler:metatranslation; \ No newline at end of file diff --git a/grammars/silver/compiler/extension/do_notation/Syntax.sv b/grammars/silver/compiler/extension/do_notation/Syntax.sv index 0e51c0a98..22a73fe58 100644 --- a/grammars/silver/compiler/extension/do_notation/Syntax.sv +++ b/grammars/silver/compiler/extension/do_notation/Syntax.sv @@ -63,7 +63,7 @@ synthesized attribute bindingFreeVars::ts:Set; -- Can this do body be translated using ap/map instead of bind synthesized attribute isApplicative::Boolean; -- Parameter bindings that will be used in applicative translation -synthesized attribute appBindings::[ProductionRHSElem]; +synthesized attribute appBindings::[LambdaRHSElem]; -- Expressions that will be bound in applicative translation synthesized attribute appExprs::[Expr]; -- The final result in applicative translation @@ -124,10 +124,9 @@ top::DoBody ::= b::DoBinding rest::DoBody \ trans::Expr e::Expr -> mkStrFunctionInvocation("silver:core:ap", [trans, e]), mkStrFunctionInvocation("silver:core:map", [ foldr( - \ el::ProductionRHSElem trans::Expr -> - lambdap( - productionRHSCons(el, productionRHSNil()), - trans), + \ el::LambdaRHSElem trans::Expr -> + lambdap_new( + lambdaRHSCons(el, lambdaRHSNil(), location=top.location), trans), top.appResult, top.appBindings), head(top.appExprs)]), tail(top.appExprs)) @@ -230,14 +229,14 @@ top::DoBinding ::= n::Name DoDoubleColon_t t::TypeExpr '<-' e::Expr ';' top.unparse = s"${n.unparse}::${t.unparse} <- ${e.unparse};"; top.boundVars <- ts:fromList([n.name]); top.isApplicative = true; - top.appBindings = [productionRHSElem(n, terminal(ColonColon_t, "::"), t)]; + top.appBindings = [lambdaRHSElemIdTy(n, terminal(ColonColon_t, "::"), t)]; top.appExprs = [e]; local cont :: Expr = - lambdap( - productionRHSCons( - productionRHSElem(n, terminal(ColonColon_t, "::"), t), - productionRHSNil()), + lambdap_new( + lambdaRHSCons( + lambdaRHSElemIdTy(n, terminal(ColonColon_t, "::"), t), + lambdaRHSNil()), top.transformIn); top.transform = mkStrFunctionInvocation("silver:core:bind", [e, cont]); @@ -250,7 +249,7 @@ top::DoBinding ::= e::Expr ';' top.unparse = s"${e.unparse};"; top.isApplicative = true; top.appBindings = - [productionRHSElemType(typerepTypeExpr(freshType()))]; + [lambdaRHSElemTy('_', terminal(ColonColon_t, "::"), typerepTypeExpr(freshType()))]; top.appExprs = [e]; top.transform = mkStrFunctionInvocation("silver:core:applySecond", [e, top.transformIn]); @@ -272,4 +271,4 @@ top::DoBinding ::= 'let' n::Name '::' t::TypeExpr '=' e::Expr ';' top.transformIn); top.recBindings = [(n.name, t)]; -} +} \ No newline at end of file diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index 0b0a2b950..46cf7cde6 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -290,7 +290,7 @@ Expr ::= realtys::[Type] monadTysLocs::[Pair] monadAnns::[(Type, Q { local funargs::AppExprs = buildFunArgs(length(realtys)); local funannargs::AnnoAppExprs = buildFunAnnArgs(monadAnns, length(realtys) + 1); - local params::ProductionRHS = + local params::LambdaRHS = buildMonadApplicationParams(realtys ++ map(fst, monadAnns), 1, if bindFun then monadOfType(expectedMonad, funType) else funType); local actualMonadAnns::[(Type, Integer)] = @@ -301,18 +301,18 @@ Expr ::= realtys::[Type] monadTysLocs::[Pair] monadAnns::[(Type, Q ([], length(realtys) + length(monadAnns)), monadAnns).1; local body::Expr = buildMonadApplicationBody(monadTysLocs ++ actualMonadAnns, funargs, funannargs, head(monadTysLocs).fst, funType, bindFun, wrapReturn); - return lambdap(params, body); + return lambdap_new(params, body); } --build the parameters for the lambda applied to all the original arguments plus the function function buildMonadApplicationParams -ProductionRHS ::= realtys::[Type] currentLoc::Integer funType::Type +LambdaRHS ::= realtys::[Type] currentLoc::Integer funType::Type { return if null(realtys) - then productionRHSCons(productionRHSElem(name("f"), + then lambdaRHSCons(lambdaRHSElemIdTy(name("f"), '::', typerepTypeExpr(funType)), - productionRHSNil()) - else productionRHSCons(productionRHSElem(name("a"++toString(currentLoc)), + lambdaRHSNil()) + else lambdaRHSCons(lambdaRHSElemIdTy(name("a"++toString(currentLoc)), '::', typerepTypeExpr(dropDecorated(head(realtys)))), buildMonadApplicationParams(tail(realtys), currentLoc+1, funType)); @@ -350,17 +350,17 @@ Expr ::= monadTysLocs::[Pair] funargs::AppExprs annargs::AnnoAppEx monadType, funTy, bindFun, wrapReturn); local argty::Type = head(monadTysLocs).fst; local bind::Expr = monadBind(); - local binding::ProductionRHS = - productionRHSCons(productionRHSElem(name("a"++toString(head(monadTysLocs).snd)), + local binding::LambdaRHS = + lambdaRHSCons(lambdaRHSElemIdTy(name("a"++toString(head(monadTysLocs).snd)), '::', typerepTypeExpr(monadInnerType(argty))), - productionRHSNil()); + lambdaRHSNil()); local bindargs::AppExprs = snocAppExprs( oneAppExprs(presentAppExpr( baseExpr(qName("a"++toString(head(monadTysLocs).snd))))), ',', - presentAppExpr(lambdap(binding, sub))); + presentAppExpr(lambdap_new(binding, sub, location=loc))); local step::Expr = applicationExpr(bind, '(', bindargs, ')'); @@ -370,16 +370,16 @@ Expr ::= monadTysLocs::[Pair] funargs::AppExprs annargs::AnnoAppEx local funapp::Expr = if wrapReturn then Silver_Expr { $Expr {monadReturn()}($Expr {baseapp}) } else baseapp; - local funbinding::ProductionRHS = - productionRHSCons(productionRHSElem(name("f"), '::', + local funbinding::LambdaRHS = + lambdaRHSCons(lambdaRHSElemIdTy(name("f"), '::', typerepTypeExpr(funTy)), - productionRHSNil()); + lambdaRHSNil()); local funbindargs::AppExprs = snocAppExprs( oneAppExprs(presentAppExpr( baseExpr(qName("f")))), ',', - presentAppExpr(lambdap(funbinding, funapp))); + presentAppExpr(lambdap_new(funbinding, funapp))); local fullfun::Expr = if bindFun then applicationExpr(bind, '(', funbindargs, ')') @@ -1141,11 +1141,11 @@ top::Expr ::= 'decorate' e::Expr 'with' '{' inh::ExprInhs '}' else decoratedType(performSubstitution(e.mtyperep, e.mUpSubst), inhSetType(sort(nub(inh.suppliedInhs)))); local newname::String = "__sv_bind_" ++ toString(genInt()); - local params::ProductionRHS = - productionRHSCons(productionRHSElem(name(newname), + local params::LambdaRHS = + lambdaRHSCons(lambdaRHSElemIdTy(name(newname), '::', typerepTypeExpr(monadInnerType(e.mtyperep))), - productionRHSNil()); + lambdaRHSNil()); local eUnDec::Expr = if e.mtyperep.isDecorated then Silver_Expr {new($Expr {e.monadRewritten})} @@ -1155,7 +1155,7 @@ top::Expr ::= 'decorate' e::Expr 'with' '{' inh::ExprInhs '}' then Silver_Expr { $Expr{monadBind()} ($Expr{eUnDec}, - $Expr{lambdap(params, + $Expr{lambdap_new(params, Silver_Expr{ $Expr{monadReturn()} ($Expr{decorateExprWith('decorate', diff --git a/grammars/silver/compiler/extension/implicit_monads/PrimitiveMatch.sv b/grammars/silver/compiler/extension/implicit_monads/PrimitiveMatch.sv index f71143284..5f9c83bfb 100644 --- a/grammars/silver/compiler/extension/implicit_monads/PrimitiveMatch.sv +++ b/grammars/silver/compiler/extension/implicit_monads/PrimitiveMatch.sv @@ -65,10 +65,10 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr local freshname::String = "__sv_bindingInAMatchExpression_" ++ toString(genInt()); local eBind::Expr = monadBind(); local eInnerType::TypeExpr = typerepTypeExpr(monadInnerType(e.mtyperep)); - local binde_lambdaparams::ProductionRHS = - productionRHSCons(productionRHSElem(name(freshname), '::', + local binde_lambdaparams::LambdaRHS = + lambdaRHSCons(lambdaRHSElemIdTy(name(freshname), '::', eInnerType), - productionRHSNil()); + lambdaRHSNil()); --Since we sometimes need to just use pure() over the top of everything to get a -- monad out, we use a fresh type rather than the top.mtyperep local outty::TypeExpr = typerepTypeExpr(freshType()); @@ -98,13 +98,13 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr --bind e, just do the rest local justBind_e::Expr = buildApplication(eBind, - [e.monadRewritten, lambdap(binde_lambdaparams, + [e.monadRewritten, lambdap_new(binde_lambdaparams, matchPrimitiveReal(decName, outty, pr.monadRewritten, f.monadRewritten))]); --bind e, return f based on e's type local bind_e_return_f::Expr = buildApplication(eBind, - [e.monadRewritten, lambdap(binde_lambdaparams, + [e.monadRewritten, lambdap_new(binde_lambdaparams, matchPrimitiveReal(decName, outty, pr.monadRewritten, buildApplication(monadReturn(), @@ -117,14 +117,14 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr prReturnify.config = top.config; local bind_e_returnify_pr::Expr = buildApplication(eBind, - [e.monadRewritten, lambdap(binde_lambdaparams, + [e.monadRewritten, lambdap_new(binde_lambdaparams, matchPrimitiveReal(decName, outty, prReturnify.returnify, f.monadRewritten))]); --bind e, returnify pr, return f based on e's type local bind_e_returnify_pr_return_f::Expr = buildApplication(eBind, - [e.monadRewritten, lambdap(binde_lambdaparams, + [e.monadRewritten, lambdap_new(binde_lambdaparams, matchPrimitiveReal(decName, outty, prReturnify.returnify, buildApplication(monadReturn(), diff --git a/grammars/silver/compiler/extension/implicit_monads/Project.sv b/grammars/silver/compiler/extension/implicit_monads/Project.sv index b4fe84c12..c542f9274 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Project.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Project.sv @@ -20,4 +20,4 @@ imports silver:compiler:modification:list; imports silver:compiler:modification:lambda_fn; imports silver:compiler:modification:let_fix; imports silver:compiler:modification:primitivepattern; -imports silver:compiler:modification:copper; +imports silver:compiler:modification:copper; \ No newline at end of file diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index 969094b2b..116302bb0 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -264,9 +264,9 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur Silver_Expr { silver:rewrite:anyASTExpr( $Expr{ - lambdap( - productionRHSCons( - productionRHSElem( + lambdap_new( + lambdaRHSCons( + lambdaRHSElemIdTy( name("_e"), '::', typerepTypeExpr(eUndec.finalType)), inh.lambdaParams), @@ -401,9 +401,9 @@ top::Expr ::= 'decorate' e::Expr 'with' '{' inh::ExprInhs '}' Silver_Expr { silver:rewrite:anyASTExpr( $Expr{ - lambdap( - productionRHSCons( - productionRHSElem( + lambdap_new( + lambdaRHSCons( + lambdaRHSElemIdTy( name("_e"), '::', typerepTypeExpr(e.finalType)), inh.lambdaParams), @@ -416,7 +416,7 @@ top::Expr ::= 'decorate' e::Expr 'with' '{' inh::ExprInhs '}' } attribute transform occurs on ExprInhs; -synthesized attribute lambdaParams::ProductionRHS occurs on ExprInhs; +synthesized attribute lambdaParams::LambdaRHS occurs on ExprInhs; functor attribute bodyExprInhTransform occurs on ExprInhs, ExprInh; propagate bodyExprInhTransform on ExprInhs; @@ -424,7 +424,7 @@ aspect production exprInhsEmpty top::ExprInhs ::= { top.transform = nilASTExpr(); - top.lambdaParams = productionRHSNil(); + top.lambdaParams = lambdaRHSNil(); } aspect production exprInhsOne @@ -432,18 +432,18 @@ top::ExprInhs ::= lhs::ExprInh { top.transform = consASTExpr(lhs.transform, nilASTExpr()); top.lambdaParams = - productionRHSCons(lhs.lambdaParam, productionRHSNil()); + lambdaRHSCons(lhs.lambdaParam, lambdaRHSNil()); } aspect production exprInhsCons top::ExprInhs ::= lhs::ExprInh inh::ExprInhs { top.transform = consASTExpr(lhs.transform, inh.transform); - top.lambdaParams = productionRHSCons(lhs.lambdaParam, inh.lambdaParams); + top.lambdaParams = lambdaRHSCons(lhs.lambdaParam, inh.lambdaParams); } attribute transform occurs on ExprInh; -synthesized attribute lambdaParam::ProductionRHSElem occurs on ExprInh; +synthesized attribute lambdaParam::LambdaRHSElem occurs on ExprInh; aspect production exprInh top::ExprInh ::= lhs::ExprLHSExpr '=' e::Expr ';' @@ -452,8 +452,8 @@ top::ExprInh ::= lhs::ExprLHSExpr '=' e::Expr ';' local paramName::String = implode("_", explode(":", lhs.name)); top.lambdaParam = - productionRHSElem( - name(paramName), '::', + lambdaRHSElemIdTy( + name(paramName, builtin), '::', typerepTypeExpr(e.finalType)); top.bodyExprInhTransform = exprInh(lhs, '=', baseExpr(qName(paramName)), ';'); @@ -627,7 +627,7 @@ top::Expr ::= 'case' es::Exprs 'of' o::Opt_Vbar_t ml::MRuleList 'end' Silver_Expr { silver:rewrite:anyASTExpr( $Expr{ - lambdap( + lambdap_new( decEs.lambdaParams, caseExpr_c( 'case', decEs.lambdaParamRefs, 'of', @@ -694,7 +694,7 @@ aspect production exprsEmpty top::Exprs ::= { top.transform = nilASTExpr(); - top.lambdaParams = productionRHSNil(); + top.lambdaParams = lambdaRHSNil(); top.lambdaParamRefs = exprsEmpty(); } aspect production exprsSingle @@ -704,11 +704,11 @@ top::Exprs ::= e::Expr local lambdaParamName::String = "__exprs_param_" ++ toString(genInt()); top.lambdaParams = - productionRHSCons( - productionRHSElem( + lambdaRHSCons( + lambdaRHSElemIdTy( name(lambdaParamName), '::', typerepTypeExpr(e.finalType)), - productionRHSNil()); + lambdaRHSNil()); top.lambdaParamRefs = exprsSingle( baseExpr(qName(lambdaParamName))); @@ -720,8 +720,8 @@ top::Exprs ::= e1::Expr ',' e2::Exprs local lambdaParamName::String = "__exprs_param_" ++ toString(genInt()); top.lambdaParams = - productionRHSCons( - productionRHSElem( + lambdaRHSCons( + lambdaRHSElemIdTy( name(lambdaParamName), '::', typerepTypeExpr(e1.finalType)), e2.lambdaParams); From ada85927f613c8dcb7faba0ff77b171b95104f25 Mon Sep 17 00:00:00 2001 From: unironically Date: Mon, 2 Oct 2023 20:25:34 -0500 Subject: [PATCH 065/283] Switching lambda_c to abstract, lambda_c_new to concrete --- grammars/silver/compiler/modification/lambda_fn/Lambda.sv | 4 ++-- grammars/silver/core/List.sv | 2 +- grammars/silver/core/Maybe.sv | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv index 5f9a6bb97..dd0c07aac 100644 --- a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv +++ b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv @@ -4,7 +4,7 @@ import silver:util:treeset as ts; --- New concrete Syntax for lambdas -------------------------------------------------------------------------------- -abstract production lambda_c_new +concrete production lambda_c_new top::Expr ::= '\' params::LambdaRHS '->' e::Expr { top.unparse = "\\ " ++ params.unparse ++ " -> " ++ e.unparse; @@ -146,7 +146,7 @@ terminal Arrow_t '->' precedence = 0, lexer classes {SPECOP}; -- Using ProductionRHS here, it is basicly just a list of names with type expressions -- It is also used for the parameter definitions in functions, so using it here for consistancy -concrete production lambda_c +abstract production lambda_c top::Expr ::= '\' params::ProductionRHS '->' e::Expr { forwards to lambda_c_new ('\', params.asLamRHS, '->', @e); diff --git a/grammars/silver/core/List.sv b/grammars/silver/core/List.sv index f5fa65296..03f93e9a4 100644 --- a/grammars/silver/core/List.sv +++ b/grammars/silver/core/List.sv @@ -46,7 +46,7 @@ instance Bind [] { instance Monad [] {} instance MonadFail [] { - fail = \ String -> []; + fail = \ _::String -> []; } instance Alt [] { diff --git a/grammars/silver/core/Maybe.sv b/grammars/silver/core/Maybe.sv index 1bec6ed10..4d0f57f77 100644 --- a/grammars/silver/core/Maybe.sv +++ b/grammars/silver/core/Maybe.sv @@ -50,7 +50,7 @@ instance Bind Maybe { instance Monad Maybe {} instance MonadFail Maybe { - fail = \ String -> nothing(); + fail = \ _::String -> nothing(); } instance Alt Maybe { @@ -138,7 +138,7 @@ instance Monad m => Bind MaybeT { instance Monad m => Monad MaybeT {} instance Monad m => MonadFail MaybeT { - fail = \ String -> maybeT(pure(nothing())); + fail = \ _::String -> maybeT(pure(nothing())); } instance Monad m => Alt MaybeT { From c5d6d3b82d72a21e7ddd993026d47c238d61e9d1 Mon Sep 17 00:00:00 2001 From: unironically Date: Mon, 2 Oct 2023 20:37:52 -0500 Subject: [PATCH 066/283] Reverting to lambda_c as concrete, lambda_c_new as abstract --- grammars/silver/compiler/modification/lambda_fn/Lambda.sv | 4 ++-- grammars/silver/core/List.sv | 2 +- grammars/silver/core/Maybe.sv | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv index dd0c07aac..5f9a6bb97 100644 --- a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv +++ b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv @@ -4,7 +4,7 @@ import silver:util:treeset as ts; --- New concrete Syntax for lambdas -------------------------------------------------------------------------------- -concrete production lambda_c_new +abstract production lambda_c_new top::Expr ::= '\' params::LambdaRHS '->' e::Expr { top.unparse = "\\ " ++ params.unparse ++ " -> " ++ e.unparse; @@ -146,7 +146,7 @@ terminal Arrow_t '->' precedence = 0, lexer classes {SPECOP}; -- Using ProductionRHS here, it is basicly just a list of names with type expressions -- It is also used for the parameter definitions in functions, so using it here for consistancy -abstract production lambda_c +concrete production lambda_c top::Expr ::= '\' params::ProductionRHS '->' e::Expr { forwards to lambda_c_new ('\', params.asLamRHS, '->', @e); diff --git a/grammars/silver/core/List.sv b/grammars/silver/core/List.sv index 03f93e9a4..f5fa65296 100644 --- a/grammars/silver/core/List.sv +++ b/grammars/silver/core/List.sv @@ -46,7 +46,7 @@ instance Bind [] { instance Monad [] {} instance MonadFail [] { - fail = \ _::String -> []; + fail = \ String -> []; } instance Alt [] { diff --git a/grammars/silver/core/Maybe.sv b/grammars/silver/core/Maybe.sv index 4d0f57f77..1bec6ed10 100644 --- a/grammars/silver/core/Maybe.sv +++ b/grammars/silver/core/Maybe.sv @@ -50,7 +50,7 @@ instance Bind Maybe { instance Monad Maybe {} instance MonadFail Maybe { - fail = \ _::String -> nothing(); + fail = \ String -> nothing(); } instance Alt Maybe { @@ -138,7 +138,7 @@ instance Monad m => Bind MaybeT { instance Monad m => Monad MaybeT {} instance Monad m => MonadFail MaybeT { - fail = \ _::String -> maybeT(pure(nothing())); + fail = \ String -> maybeT(pure(nothing())); } instance Monad m => Alt MaybeT { From 94b1a5a0cd985bb01350b11a318950929136e44a Mon Sep 17 00:00:00 2001 From: unironically Date: Mon, 2 Oct 2023 20:44:35 -0500 Subject: [PATCH 067/283] Switching lambda_c to abstract, lambda_c_new to concrete --- grammars/silver/compiler/modification/lambda_fn/Lambda.sv | 4 ++-- grammars/silver/core/List.sv | 2 +- grammars/silver/core/Maybe.sv | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv index 5f9a6bb97..dd0c07aac 100644 --- a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv +++ b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv @@ -4,7 +4,7 @@ import silver:util:treeset as ts; --- New concrete Syntax for lambdas -------------------------------------------------------------------------------- -abstract production lambda_c_new +concrete production lambda_c_new top::Expr ::= '\' params::LambdaRHS '->' e::Expr { top.unparse = "\\ " ++ params.unparse ++ " -> " ++ e.unparse; @@ -146,7 +146,7 @@ terminal Arrow_t '->' precedence = 0, lexer classes {SPECOP}; -- Using ProductionRHS here, it is basicly just a list of names with type expressions -- It is also used for the parameter definitions in functions, so using it here for consistancy -concrete production lambda_c +abstract production lambda_c top::Expr ::= '\' params::ProductionRHS '->' e::Expr { forwards to lambda_c_new ('\', params.asLamRHS, '->', @e); diff --git a/grammars/silver/core/List.sv b/grammars/silver/core/List.sv index f5fa65296..cc38ce29a 100644 --- a/grammars/silver/core/List.sv +++ b/grammars/silver/core/List.sv @@ -46,7 +46,7 @@ instance Bind [] { instance Monad [] {} instance MonadFail [] { - fail = \ String -> []; + fail = \ dummy::String -> []; } instance Alt [] { diff --git a/grammars/silver/core/Maybe.sv b/grammars/silver/core/Maybe.sv index 1bec6ed10..61f8bb1f1 100644 --- a/grammars/silver/core/Maybe.sv +++ b/grammars/silver/core/Maybe.sv @@ -50,7 +50,7 @@ instance Bind Maybe { instance Monad Maybe {} instance MonadFail Maybe { - fail = \ String -> nothing(); + fail = \ dummy::String -> nothing(); } instance Alt Maybe { @@ -138,7 +138,7 @@ instance Monad m => Bind MaybeT { instance Monad m => Monad MaybeT {} instance Monad m => MonadFail MaybeT { - fail = \ String -> maybeT(pure(nothing())); + fail = \ dummy::String -> maybeT(pure(nothing())); } instance Monad m => Alt MaybeT { From 6fcfb510813a0dd3b1d6c698369fa2ea7282e142 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 3 Oct 2023 11:47:08 -0500 Subject: [PATCH 068/283] Avoid crash when appExprTyperep is demanded with the wrong number of arguments --- grammars/silver/compiler/definition/core/Expr.sv | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index 5043e3f21..88792873e 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -1026,9 +1026,13 @@ top::AppExprs ::= es::AppExprs ',' e::AppExpr top.appExprSize = es.appExprSize + 1; e.appExprIndex = es.appExprSize; - e.appExprTyperep = head(top.appExprTypereps); + e.appExprTyperep = + if null(top.appExprTypereps) + then errorType() + else head(top.appExprTypereps); - es.appExprTypereps = tail(top.appExprTypereps); + es.appExprTypereps = + if null(top.appExprTypereps) then [] else tail(top.appExprTypereps); } concrete production oneAppExprs top::AppExprs ::= e::AppExpr @@ -1043,9 +1047,10 @@ top::AppExprs ::= e::AppExpr top.appExprSize = 1; e.appExprIndex = 0; - e.appExprTyperep = if null(top.appExprTypereps) - then errorType() - else head(top.appExprTypereps); + e.appExprTyperep = + if null(top.appExprTypereps) + then errorType() + else head(top.appExprTypereps); } abstract production emptyAppExprs top::AppExprs ::= From 8a333c2bd884a8538942933229c24e8e19a25eb9 Mon Sep 17 00:00:00 2001 From: unironically Date: Tue, 3 Oct 2023 12:53:29 -0500 Subject: [PATCH 069/283] Fixed syntax errors --- .../silver/compiler/definition/env/Context.sv | 42 +++++++++---------- .../compiler/extension/do_notation/Syntax.sv | 2 +- .../extension/implicit_monads/Expr.sv | 2 +- .../compiler/extension/rewriting/Expr.sv | 2 +- .../compiler/extension/rewriting/Rewriting.sv | 2 +- .../compiler/modification/copper/DclInfo.sv | 6 +-- grammars/silver/langutil/pp/Show.sv | 2 +- grammars/silver/util/random/Arbitrary.sv | 6 +-- 8 files changed, 32 insertions(+), 32 deletions(-) diff --git a/grammars/silver/compiler/definition/env/Context.sv b/grammars/silver/compiler/definition/env/Context.sv index c6705909b..cd0f86303 100644 --- a/grammars/silver/compiler/definition/env/Context.sv +++ b/grammars/silver/compiler/definition/env/Context.sv @@ -57,9 +57,9 @@ top::Context ::= cls::String t::Type [tcInstDef(instConstraintDcl(cls, t, tvs, sourceGrammar=g, sourceLocation=l))]; -- Could be a different kind of def, but these are essentially the same as regular instance constraints top.contextSigDefs = \ ns::NamedSignature g::String l::Location -> [tcInstDef(sigConstraintDcl(cls, t, ns, sourceGrammar=g, sourceLocation=l))]; - top.contextSuperOccursDefs = \ InstDclInfo String Location -> []; - top.contextMemberOccursDefs = \ [TyVar] String Location -> []; - top.contextSigOccursDefs = \ NamedSignature String Location -> []; + top.contextSuperOccursDefs = \ dummy::InstDclInfo dummy::String dummy::Location -> []; + top.contextMemberOccursDefs = \ dummy::[TyVar] dummy::String dummy::Location -> []; + top.contextSigOccursDefs = \ dummy::NamedSignature dummy::String dummy::Location -> []; top.contextClassName = just(cls); -- Here possibly-decorated types that are still unspecialized at this point @@ -96,9 +96,9 @@ top::Context ::= cls::String t::Type aspect production inhOccursContext top::Context ::= attr::String args::[Type] atty::Type ntty::Type { - top.contextSuperDefs = \ InstDclInfo String Location -> []; - top.contextMemberDefs = \ [TyVar] String Location -> []; - top.contextSigDefs = \ NamedSignature String Location -> []; + top.contextSuperDefs = \ dummy::InstDclInfo dummy::String dummy::Location -> []; + top.contextMemberDefs = \ dummy::[TyVar] dummy::String dummy::Location -> []; + top.contextSigDefs = \ dummy::NamedSignature dummy::String dummy::Location -> []; top.contextSuperOccursDefs = \ d::InstDclInfo g::String l::Location -> [occursSuperDcl(attr, atty, d, sourceGrammar=g, sourceLocation=l)]; top.contextMemberOccursDefs = \ tvs::[TyVar] g::String l::Location -> @@ -124,9 +124,9 @@ top::Context ::= attr::String args::[Type] atty::Type ntty::Type aspect production synOccursContext top::Context ::= attr::String args::[Type] atty::Type inhs::Type ntty::Type { - top.contextSuperDefs = \ InstDclInfo String Location -> []; - top.contextMemberDefs = \ [TyVar] String Location -> []; - top.contextSigDefs = \ NamedSignature String Location -> []; + top.contextSuperDefs = \ dummy::InstDclInfo dummy::String dummy::Location -> []; + top.contextMemberDefs = \ dummy::[TyVar] dummy::String dummy::Location -> []; + top.contextSigDefs = \ dummy::NamedSignature dummy::String dummy::Location -> []; top.contextSuperOccursDefs = \ d::InstDclInfo g::String l::Location -> [occursSuperDcl(attr, atty, d, sourceGrammar=g, sourceLocation=l)]; top.contextMemberOccursDefs = \ tvs::[TyVar] g::String l::Location -> @@ -152,9 +152,9 @@ top::Context ::= attr::String args::[Type] atty::Type inhs::Type ntty::Type aspect production annoOccursContext top::Context ::= attr::String args::[Type] atty::Type ntty::Type { - top.contextSuperDefs = \ InstDclInfo String Location -> []; - top.contextMemberDefs = \ [TyVar] String Location -> []; - top.contextSigDefs = \ NamedSignature String Location -> []; + top.contextSuperDefs = \ dummy::InstDclInfo dummy::String dummy::Location -> []; + top.contextMemberDefs = \ dummy::[TyVar] dummy::String dummy::Location -> []; + top.contextSigDefs = \ dummy::NamedSignature dummy::String dummy::Location -> []; top.contextSuperOccursDefs = \ d::InstDclInfo g::String l::Location -> [annoSuperDcl(attr, atty, d, sourceGrammar=g, sourceLocation=l)]; top.contextMemberOccursDefs = \ tvs::[TyVar] g::String l::Location -> @@ -186,9 +186,9 @@ top::Context ::= t::Type [tcInstDef(typeableInstConstraintDcl(t, tvs, sourceGrammar=g, sourceLocation=l))]; -- Could be a different kind of def, but these are essentially the same as regular instance constraints top.contextSigDefs = \ ns::NamedSignature g::String l::Location -> [tcInstDef(typeableSigConstraintDcl(t, ns, sourceGrammar=g, sourceLocation=l))]; - top.contextSuperOccursDefs = \ InstDclInfo String Location -> []; - top.contextMemberOccursDefs = \ [TyVar] String Location -> []; - top.contextSigOccursDefs = \ NamedSignature String Location -> []; + top.contextSuperOccursDefs = \ dummy::InstDclInfo dummy::String dummy::Location -> []; + top.contextMemberOccursDefs = \ dummy::[TyVar] dummy::String dummy::Location -> []; + top.contextSigOccursDefs = \ dummy::NamedSignature dummy::String dummy::Location -> []; top.contextClassName = nothing(); top.resolved = @@ -223,9 +223,9 @@ top::Context ::= i1::Type i2::Type [tcInstDef(inhSubsetInstConstraintDcl(i1, i2, tvs, sourceGrammar=g, sourceLocation=l))]; -- Could be a different kind of def, but these are essentially the same as regular instance constraints top.contextSigDefs = \ ns::NamedSignature g::String l::Location -> [tcInstDef(inhSubsetSigConstraintDcl(i1, i2, ns, sourceGrammar=g, sourceLocation=l))]; - top.contextSuperOccursDefs = \ InstDclInfo String Location -> []; - top.contextMemberOccursDefs = \ [TyVar] String Location -> []; - top.contextSigOccursDefs = \ NamedSignature String Location -> []; + top.contextSuperOccursDefs = \ dummy::InstDclInfo dummy::String dummy::Location -> []; + top.contextMemberOccursDefs = \ dummy::[TyVar] dummy::String dummy::Location -> []; + top.contextSigOccursDefs = \ dummy::NamedSignature dummy::String dummy::Location -> []; top.contextClassName = nothing(); top.resolved = @@ -239,9 +239,9 @@ top::Context ::= i1::Type i2::Type aspect production typeErrorContext top::Context ::= msg::String { - top.contextSuperDefs = \ InstDclInfo String Location -> []; - top.contextMemberDefs = \ [TyVar] String Location -> []; - top.contextSigDefs = \ NamedSignature String Location -> []; + top.contextSuperDefs = \ dummy::InstDclInfo dummy::String dummy::Location -> []; + top.contextMemberDefs = \ dummy::[TyVar] dummy::String dummy::Location -> []; + top.contextSigDefs = \ dummy::NamedSignature dummy::String dummy::Location -> []; top.contextSuperOccursDefs = \ d::InstDclInfo g::String l::Location -> []; top.contextMemberOccursDefs = \ tvs::[TyVar] g::String l::Location -> []; top.contextSigOccursDefs = \ ns::NamedSignature g::String l::Location -> []; diff --git a/grammars/silver/compiler/extension/do_notation/Syntax.sv b/grammars/silver/compiler/extension/do_notation/Syntax.sv index 22a73fe58..cead6e9a9 100644 --- a/grammars/silver/compiler/extension/do_notation/Syntax.sv +++ b/grammars/silver/compiler/extension/do_notation/Syntax.sv @@ -126,7 +126,7 @@ top::DoBody ::= b::DoBinding rest::DoBody foldr( \ el::LambdaRHSElem trans::Expr -> lambdap_new( - lambdaRHSCons(el, lambdaRHSNil(), location=top.location), trans), + lambdaRHSCons(el, lambdaRHSNil()), trans), top.appResult, top.appBindings), head(top.appExprs)]), tail(top.appExprs)) diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index 46cf7cde6..40a478761 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -360,7 +360,7 @@ Expr ::= monadTysLocs::[Pair] funargs::AppExprs annargs::AnnoAppEx oneAppExprs(presentAppExpr( baseExpr(qName("a"++toString(head(monadTysLocs).snd))))), ',', - presentAppExpr(lambdap_new(binding, sub, location=loc))); + presentAppExpr(lambdap_new(binding, sub))); local step::Expr = applicationExpr(bind, '(', bindargs, ')'); diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index 116302bb0..cef7056d3 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -453,7 +453,7 @@ top::ExprInh ::= lhs::ExprLHSExpr '=' e::Expr ';' local paramName::String = implode("_", explode(":", lhs.name)); top.lambdaParam = lambdaRHSElemIdTy( - name(paramName, builtin), '::', + name(paramName), '::', typerepTypeExpr(e.finalType)); top.bodyExprInhTransform = exprInh(lhs, '=', baseExpr(qName(paramName)), ';'); diff --git a/grammars/silver/compiler/extension/rewriting/Rewriting.sv b/grammars/silver/compiler/extension/rewriting/Rewriting.sv index 8c1da9798..c4d6d8f7a 100644 --- a/grammars/silver/compiler/extension/rewriting/Rewriting.sv +++ b/grammars/silver/compiler/extension/rewriting/Rewriting.sv @@ -252,7 +252,7 @@ top::Expr ::= 'rule' 'on' ty::TypeExpr 'of' Opt_Vbar_t ml::MRuleList 'end' then requireType(antiquoteASTExpr( Silver_Expr { silver:rewrite:anyASTExpr( - \ $TypeExpr{typerepTypeExpr(finalRuleType)} -> unit()) + \ dummy::$TypeExpr{typerepTypeExpr(finalRuleType)} -> unit()) })) <* ml.transform else ml.transform; diff --git a/grammars/silver/compiler/modification/copper/DclInfo.sv b/grammars/silver/compiler/modification/copper/DclInfo.sv index 893785d69..fa6876981 100644 --- a/grammars/silver/compiler/modification/copper/DclInfo.sv +++ b/grammars/silver/compiler/modification/copper/DclInfo.sv @@ -22,7 +22,7 @@ top::ValueDclInfo ::= fn::String ty::Type top.refDispatcher = parserAttributeReference; top.defDispatcher = parserAttributeValueDef; top.defLHSDispatcher = parserAttributeDefLHS; - top.transDefLHSDispatcher = \ q::Decorated! QName Decorated! QNameAttrOccur -> + top.transDefLHSDispatcher = \ q::Decorated! QName dummy::Decorated! QNameAttrOccur -> parserAttributeDefLHS(q); } @@ -96,7 +96,7 @@ top::ValueDclInfo ::= fn::String ty::Type top.refDispatcher = actionChildReference; top.defDispatcher = errorValueDef; top.defLHSDispatcher = parserAttributeDefLHS; -- TODO: specialize this - top.transDefLHSDispatcher = \ q::Decorated! QName Decorated! QNameAttrOccur -> + top.transDefLHSDispatcher = \ q::Decorated! QName dummy::Decorated! QNameAttrOccur -> parserAttributeDefLHS(q); } @@ -115,6 +115,6 @@ top::ValueDclInfo ::= fn::String ty::Type top.refDispatcher = parserAttributeReference; top.defDispatcher = parserAttributeValueDef; top.defLHSDispatcher = parserAttributeDefLHS; - top.transDefLHSDispatcher = \ q::Decorated! QName Decorated! QNameAttrOccur -> + top.transDefLHSDispatcher = \ q::Decorated! QName dummy::Decorated! QNameAttrOccur -> parserAttributeDefLHS(q); } diff --git a/grammars/silver/langutil/pp/Show.sv b/grammars/silver/langutil/pp/Show.sv index 087de87d0..f0783594a 100644 --- a/grammars/silver/langutil/pp/Show.sv +++ b/grammars/silver/langutil/pp/Show.sv @@ -81,7 +81,7 @@ instance Show a => ShowTuple a { } instance Show () { - pp = \ () -> pp"()"; + pp = \ dummy::() -> pp"()"; } -- Other standard lib types. diff --git a/grammars/silver/util/random/Arbitrary.sv b/grammars/silver/util/random/Arbitrary.sv index 0559f7b6d..2b1c7986f 100644 --- a/grammars/silver/util/random/Arbitrary.sv +++ b/grammars/silver/util/random/Arbitrary.sv @@ -11,15 +11,15 @@ class Arbitrary a { } instance Arbitrary Integer { - genArb = \ Integer -> randomRange(-100, 100); -- TODO: Is this a reasonable default? Revisit. + genArb = \ dummy::Integer -> randomRange(-100, 100); -- TODO: Is this a reasonable default? Revisit. } instance Arbitrary Float { - genArb = \ Integer -> randomRange(-10.0, 10.0); -- TODO: Is this a reasonable default? Revisit. + genArb = \ dummy::Integer -> randomRange(-10.0, 10.0); -- TODO: Is this a reasonable default? Revisit. } instance Arbitrary Boolean { - genArb = \ Integer -> random; + genArb = \ dummy::Integer -> random; } instance Arbitrary String { From fea0ade73480648ee25bc10c08a729122e38c685 Mon Sep 17 00:00:00 2001 From: unironically Date: Tue, 3 Oct 2023 15:13:10 -0500 Subject: [PATCH 070/283] Use of _ over _::t, swapping lambdap_new/lambda_c_new and lambdap/lambda_c --- .../compiler/analysis/uniqueness/Expr.sv | 2 +- .../silver/compiler/definition/env/Context.sv | 42 ++++++------- .../compiler/definition/flow/env/Expr.sv | 2 +- .../extension/attrsection/AttrSection.sv.md | 6 +- .../extension/easyterminal/TerminalDcl.sv | 4 +- .../extension/implicit_monads/Lambda.sv | 4 +- .../extension/implicit_monads/Util.sv | 12 ++-- .../compiler/extension/rewriting/Rewriting.sv | 2 +- .../compiler/modification/lambda_fn/Lambda.sv | 61 +++++-------------- .../modification/lambda_fn/java/Lambda.sv | 2 +- grammars/silver/langutil/pp/Show.sv | 2 +- grammars/silver/util/random/Arbitrary.sv | 6 +- 12 files changed, 56 insertions(+), 89 deletions(-) diff --git a/grammars/silver/compiler/analysis/uniqueness/Expr.sv b/grammars/silver/compiler/analysis/uniqueness/Expr.sv index 70e767ba6..f0da8e02d 100644 --- a/grammars/silver/compiler/analysis/uniqueness/Expr.sv +++ b/grammars/silver/compiler/analysis/uniqueness/Expr.sv @@ -323,7 +323,7 @@ top::Expr ::= q::Decorated! QName top.accessUniqueRefs = []; } -aspect production lambdap_new +aspect production lambdap top::Expr ::= params::LambdaRHS e::Expr { top.uniqueRefs := filter(\ r::(String, UniqueRefSite) -> !contains(r.1, params.lambdaBoundVars), e.uniqueRefs); diff --git a/grammars/silver/compiler/definition/env/Context.sv b/grammars/silver/compiler/definition/env/Context.sv index cd0f86303..307276321 100644 --- a/grammars/silver/compiler/definition/env/Context.sv +++ b/grammars/silver/compiler/definition/env/Context.sv @@ -57,9 +57,9 @@ top::Context ::= cls::String t::Type [tcInstDef(instConstraintDcl(cls, t, tvs, sourceGrammar=g, sourceLocation=l))]; -- Could be a different kind of def, but these are essentially the same as regular instance constraints top.contextSigDefs = \ ns::NamedSignature g::String l::Location -> [tcInstDef(sigConstraintDcl(cls, t, ns, sourceGrammar=g, sourceLocation=l))]; - top.contextSuperOccursDefs = \ dummy::InstDclInfo dummy::String dummy::Location -> []; - top.contextMemberOccursDefs = \ dummy::[TyVar] dummy::String dummy::Location -> []; - top.contextSigOccursDefs = \ dummy::NamedSignature dummy::String dummy::Location -> []; + top.contextSuperOccursDefs = \ _ _ _ -> []; + top.contextMemberOccursDefs = \ _ _ _ -> []; + top.contextSigOccursDefs = \ _ _ _ -> []; top.contextClassName = just(cls); -- Here possibly-decorated types that are still unspecialized at this point @@ -96,9 +96,9 @@ top::Context ::= cls::String t::Type aspect production inhOccursContext top::Context ::= attr::String args::[Type] atty::Type ntty::Type { - top.contextSuperDefs = \ dummy::InstDclInfo dummy::String dummy::Location -> []; - top.contextMemberDefs = \ dummy::[TyVar] dummy::String dummy::Location -> []; - top.contextSigDefs = \ dummy::NamedSignature dummy::String dummy::Location -> []; + top.contextSuperDefs = \ _ _ _ -> []; + top.contextMemberDefs = \ _ _ _ -> []; + top.contextSigDefs = \ _ _ _ -> []; top.contextSuperOccursDefs = \ d::InstDclInfo g::String l::Location -> [occursSuperDcl(attr, atty, d, sourceGrammar=g, sourceLocation=l)]; top.contextMemberOccursDefs = \ tvs::[TyVar] g::String l::Location -> @@ -124,9 +124,9 @@ top::Context ::= attr::String args::[Type] atty::Type ntty::Type aspect production synOccursContext top::Context ::= attr::String args::[Type] atty::Type inhs::Type ntty::Type { - top.contextSuperDefs = \ dummy::InstDclInfo dummy::String dummy::Location -> []; - top.contextMemberDefs = \ dummy::[TyVar] dummy::String dummy::Location -> []; - top.contextSigDefs = \ dummy::NamedSignature dummy::String dummy::Location -> []; + top.contextSuperDefs = \ _ _ _ -> []; + top.contextMemberDefs = \ _ _ _ -> []; + top.contextSigDefs = \ _ _ _ -> []; top.contextSuperOccursDefs = \ d::InstDclInfo g::String l::Location -> [occursSuperDcl(attr, atty, d, sourceGrammar=g, sourceLocation=l)]; top.contextMemberOccursDefs = \ tvs::[TyVar] g::String l::Location -> @@ -152,9 +152,9 @@ top::Context ::= attr::String args::[Type] atty::Type inhs::Type ntty::Type aspect production annoOccursContext top::Context ::= attr::String args::[Type] atty::Type ntty::Type { - top.contextSuperDefs = \ dummy::InstDclInfo dummy::String dummy::Location -> []; - top.contextMemberDefs = \ dummy::[TyVar] dummy::String dummy::Location -> []; - top.contextSigDefs = \ dummy::NamedSignature dummy::String dummy::Location -> []; + top.contextSuperDefs = \ _ _ _ -> []; + top.contextMemberDefs = \ _ _ _ -> []; + top.contextSigDefs = \ _ _ _ -> []; top.contextSuperOccursDefs = \ d::InstDclInfo g::String l::Location -> [annoSuperDcl(attr, atty, d, sourceGrammar=g, sourceLocation=l)]; top.contextMemberOccursDefs = \ tvs::[TyVar] g::String l::Location -> @@ -186,9 +186,9 @@ top::Context ::= t::Type [tcInstDef(typeableInstConstraintDcl(t, tvs, sourceGrammar=g, sourceLocation=l))]; -- Could be a different kind of def, but these are essentially the same as regular instance constraints top.contextSigDefs = \ ns::NamedSignature g::String l::Location -> [tcInstDef(typeableSigConstraintDcl(t, ns, sourceGrammar=g, sourceLocation=l))]; - top.contextSuperOccursDefs = \ dummy::InstDclInfo dummy::String dummy::Location -> []; - top.contextMemberOccursDefs = \ dummy::[TyVar] dummy::String dummy::Location -> []; - top.contextSigOccursDefs = \ dummy::NamedSignature dummy::String dummy::Location -> []; + top.contextSuperOccursDefs = \ _ _ _ -> []; + top.contextMemberOccursDefs = \ _ _ _ -> []; + top.contextSigOccursDefs = \ _ _ _ -> []; top.contextClassName = nothing(); top.resolved = @@ -223,9 +223,9 @@ top::Context ::= i1::Type i2::Type [tcInstDef(inhSubsetInstConstraintDcl(i1, i2, tvs, sourceGrammar=g, sourceLocation=l))]; -- Could be a different kind of def, but these are essentially the same as regular instance constraints top.contextSigDefs = \ ns::NamedSignature g::String l::Location -> [tcInstDef(inhSubsetSigConstraintDcl(i1, i2, ns, sourceGrammar=g, sourceLocation=l))]; - top.contextSuperOccursDefs = \ dummy::InstDclInfo dummy::String dummy::Location -> []; - top.contextMemberOccursDefs = \ dummy::[TyVar] dummy::String dummy::Location -> []; - top.contextSigOccursDefs = \ dummy::NamedSignature dummy::String dummy::Location -> []; + top.contextSuperOccursDefs = \ _ _ _ -> []; + top.contextMemberOccursDefs = \ _ _ _ -> []; + top.contextSigOccursDefs = \ _ _ _ -> []; top.contextClassName = nothing(); top.resolved = @@ -239,9 +239,9 @@ top::Context ::= i1::Type i2::Type aspect production typeErrorContext top::Context ::= msg::String { - top.contextSuperDefs = \ dummy::InstDclInfo dummy::String dummy::Location -> []; - top.contextMemberDefs = \ dummy::[TyVar] dummy::String dummy::Location -> []; - top.contextSigDefs = \ dummy::NamedSignature dummy::String dummy::Location -> []; + top.contextSuperDefs = \ _ _ _ -> []; + top.contextMemberDefs = \ _ _ _ -> []; + top.contextSigDefs = \ _ _ _ -> []; top.contextSuperOccursDefs = \ d::InstDclInfo g::String l::Location -> []; top.contextMemberOccursDefs = \ tvs::[TyVar] g::String l::Location -> []; top.contextSigOccursDefs = \ ns::NamedSignature g::String l::Location -> []; diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index 127308520..373b807c6 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -541,7 +541,7 @@ top::Exprs ::= e1::Expr ',' e2::Exprs e1.alwaysDecorated = false; } -aspect production lambdap_new +aspect production lambdap top::Expr ::= params::LambdaRHS e::Expr { e.decSiteVertexInfo = nothing(); diff --git a/grammars/silver/compiler/extension/attrsection/AttrSection.sv.md b/grammars/silver/compiler/extension/attrsection/AttrSection.sv.md index 574c6e768..dbcc14a0f 100644 --- a/grammars/silver/compiler/extension/attrsection/AttrSection.sv.md +++ b/grammars/silver/compiler/extension/attrsection/AttrSection.sv.md @@ -87,9 +87,9 @@ The forward is just equivalent to `\ x::inputTy -> x.attr` ```silver forwards to lambdap( - productionRHSCons( - productionRHSElem(name("x"), '::', typerepTypeExpr(inputTy)), - productionRHSNil()), + lambdaRHSCons( + lambdaRHSElemIdTy(name("x"), '::', typerepTypeExpr(inputTy)), + lambdaRHSNil()), access(baseExpr(qName("x")), '.', q)); } ``` diff --git a/grammars/silver/compiler/extension/easyterminal/TerminalDcl.sv b/grammars/silver/compiler/extension/easyterminal/TerminalDcl.sv index 8f37b6664..c1c3f12cf 100644 --- a/grammars/silver/compiler/extension/easyterminal/TerminalDcl.sv +++ b/grammars/silver/compiler/extension/easyterminal/TerminalDcl.sv @@ -69,7 +69,7 @@ top::ProductionRHSElem ::= id::Name '::' reg::EasyTerminalRef propagate env; top.errors <- reg.errors; - top.lambdaBoundVars := [id.name]; -- Needed because we are forwrding based on env + --top.lambdaBoundVars := [id.name]; -- Needed because we are forwrding based on env forwards to productionRHSElem(id, $2, typerepTypeExpr(reg.typerep)); } @@ -81,7 +81,7 @@ top::ProductionRHSElem ::= reg::EasyTerminalRef propagate env; top.errors <- reg.errors; - top.lambdaBoundVars := []; -- Needed because we are forwrding based on env + --top.lambdaBoundVars := []; -- Needed because we are forwrding based on env forwards to productionRHSElemType(typerepTypeExpr(reg.typerep)); } diff --git a/grammars/silver/compiler/extension/implicit_monads/Lambda.sv b/grammars/silver/compiler/extension/implicit_monads/Lambda.sv index 3fae077eb..36e1ee24a 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Lambda.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Lambda.sv @@ -1,6 +1,6 @@ grammar silver:compiler:extension:implicit_monads; -aspect production lambdap_new +aspect production lambdap top::Expr ::= params::LambdaRHS e::Expr { top.merrors := e.merrors; @@ -11,7 +11,7 @@ top::Expr ::= params::LambdaRHS e::Expr e.monadicallyUsed = false; top.monadicNames = e.monadicNames; - top.monadRewritten = lambdap_new(params, e.monadRewritten); + top.monadRewritten = lambdap(params, e.monadRewritten); } diff --git a/grammars/silver/compiler/extension/implicit_monads/Util.sv b/grammars/silver/compiler/extension/implicit_monads/Util.sv index 4172e77e5..2c1d7ba27 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Util.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Util.sv @@ -223,10 +223,10 @@ Expr ::= n::String ty::Type body::Expr { -- \ n::ty -> body return lambdap( - productionRHSCons(productionRHSElem(name(n), + lambdaRHSCons(lambdaRHSElemIdTy(name(n), '::', typerepTypeExpr(ty)), - productionRHSNil()), + lambdaRHSNil()), body); } @@ -234,15 +234,15 @@ Expr ::= n::String ty::Type body::Expr function buildMultiLambda Expr ::= names::[Pair] body::Expr { - local sig::ProductionRHS = - foldr(\ pr::Pair p::ProductionRHS -> + local sig::LambdaRHS = + foldr(\ pr::Pair p::LambdaRHS -> case pr of | (n, ty) -> - productionRHSCons(productionRHSElem(name(n), '::', + lambdaRHSCons(lambdaRHSElemIdTy(name(n), '::', typerepTypeExpr(ty)), p) end, - productionRHSNil(), names); + lambdaRHSNil(), names); return lambdap(sig, body); } diff --git a/grammars/silver/compiler/extension/rewriting/Rewriting.sv b/grammars/silver/compiler/extension/rewriting/Rewriting.sv index c4d6d8f7a..6bd7e85d2 100644 --- a/grammars/silver/compiler/extension/rewriting/Rewriting.sv +++ b/grammars/silver/compiler/extension/rewriting/Rewriting.sv @@ -252,7 +252,7 @@ top::Expr ::= 'rule' 'on' ty::TypeExpr 'of' Opt_Vbar_t ml::MRuleList 'end' then requireType(antiquoteASTExpr( Silver_Expr { silver:rewrite:anyASTExpr( - \ dummy::$TypeExpr{typerepTypeExpr(finalRuleType)} -> unit()) + \ _ -> unit()) })) <* ml.transform else ml.transform; diff --git a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv index dd0c07aac..30ea56434 100644 --- a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv +++ b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv @@ -4,7 +4,7 @@ import silver:util:treeset as ts; --- New concrete Syntax for lambdas -------------------------------------------------------------------------------- -concrete production lambda_c_new +concrete production lambda_c top::Expr ::= '\' params::LambdaRHS '->' e::Expr { top.unparse = "\\ " ++ params.unparse ++ " -> " ++ e.unparse; @@ -12,7 +12,7 @@ top::Expr ::= '\' params::LambdaRHS '->' e::Expr forwards to lambdap_new(params, e); } -abstract production lambdap_new +abstract production lambdap top::Expr ::= params::LambdaRHS e::Expr { top.unparse = "\\ " ++ params.unparse ++ " -> " ++ e.unparse; @@ -146,68 +146,35 @@ terminal Arrow_t '->' precedence = 0, lexer classes {SPECOP}; -- Using ProductionRHS here, it is basicly just a list of names with type expressions -- It is also used for the parameter definitions in functions, so using it here for consistancy -abstract production lambda_c -top::Expr ::= '\' params::ProductionRHS '->' e::Expr +abstract production lambda_c_new +top::Expr ::= '\' params::LambdaRHS '->' e::Expr { - forwards to lambda_c_new ('\', params.asLamRHS, '->', @e); + forwards to lambda_c ('\', @params, '->', @e); } -abstract production lambdap -top::Expr ::= params::ProductionRHS e::Expr +abstract production lambdap_new +top::Expr ::= params::LambdaRHS e::Expr { - forwards to lambdap_new (params.asLamRHS, @e); + forwards to lambdap (@params, @e); } monoid attribute lambdaDefs::[Def]; monoid attribute lambdaBoundVars::[String]; -attribute lambdaDefs, lambdaBoundVars occurs on ProductionRHS, ProductionRHSElem; +--attribute lambdaDefs, lambdaBoundVars occurs on ProductionRHS, ProductionRHSElem; -flowtype lambdaDefs {decorate, givenLambdaId, givenLambdaParamIndex} on ProductionRHS, ProductionRHSElem; -flowtype lambdaBoundVars {} on ProductionRHS; -flowtype lambdaBoundVars {deterministicCount} on ProductionRHSElem; +--flowtype lambdaDefs {decorate, givenLambdaId, givenLambdaParamIndex} on ProductionRHS, ProductionRHSElem; +--flowtype lambdaBoundVars {} on ProductionRHS; +--flowtype lambdaBoundVars {deterministicCount} on ProductionRHSElem; -propagate lambdaDefs, lambdaBoundVars on ProductionRHS; +--propagate lambdaDefs, lambdaBoundVars on ProductionRHS; inherited attribute givenLambdaId::Integer occurs on ProductionRHS, ProductionRHSElem; inherited attribute givenLambdaParamIndex::Integer occurs on ProductionRHS, ProductionRHSElem; -propagate givenLambdaId on ProductionRHS, ProductionRHSElem; +--propagate givenLambdaId on ProductionRHS, ProductionRHSElem; synthesized attribute asLamRHS::LambdaRHS occurs on ProductionRHS; synthesized attribute asLamRHSElem::LambdaRHSElem occurs on ProductionRHSElem; -aspect production productionRHSCons -top::ProductionRHS ::= h::ProductionRHSElem t::ProductionRHS -{ - --t.givenLambdaParamIndex = top.givenLambdaParamIndex + 1; - --h.givenLambdaParamIndex = top.givenLambdaParamIndex; - top.asLamRHS = lambdaRHSCons (h.asLamRHSElem, t.asLamRHS); -} - -aspect production productionRHSNil -top::ProductionRHS ::= -{ - top.asLamRHS = lambdaRHSNil (); -} - -aspect production productionRHSElem -top::ProductionRHSElem ::= id::Name '::' t::TypeExpr -{ - {-production fName :: String = toString(genInt()) ++ ":" ++ id.name; --- production transName :: String = "lambda_param" ++ id.name ++ toString(genInt()); - top.lambdaDefs := [lambdaParamDef(top.grammarName, t.location, fName, t.typerep, top.givenLambdaId, top.givenLambdaParamIndex)]; - top.lambdaBoundVars := [id.name];-} - - top.asLamRHSElem = lambdaRHSElemIdTy(id, '::', t); -} - -aspect production productionRHSElemType -top::ProductionRHSElem ::= t::TypeExpr -{ - --forwards to productionRHSElem(name("_G_" ++ toString(top.deterministicCount), t.location), '::', t, location=top.location); - - top.asLamRHSElem = lambdaRHSElemTy('_', '::', t); -} - abstract production lambdaParamReference top::Expr ::= q::Decorated! QName { diff --git a/grammars/silver/compiler/modification/lambda_fn/java/Lambda.sv b/grammars/silver/compiler/modification/lambda_fn/java/Lambda.sv index fb69aaece..459e87d0e 100644 --- a/grammars/silver/compiler/modification/lambda_fn/java/Lambda.sv +++ b/grammars/silver/compiler/modification/lambda_fn/java/Lambda.sv @@ -11,7 +11,7 @@ import silver:compiler:analysis:typechecking:core only finalType; import silver:compiler:translation:java:core; import silver:compiler:translation:java:type; -aspect production lambdap_new +aspect production lambdap top::Expr ::= params::LambdaRHS e::Expr { -- Attempt to solve a context `runtimeTypeable ${top.finalType)}`, from which the runtime TypeRep translation is computed. diff --git a/grammars/silver/langutil/pp/Show.sv b/grammars/silver/langutil/pp/Show.sv index f0783594a..a8c476ae4 100644 --- a/grammars/silver/langutil/pp/Show.sv +++ b/grammars/silver/langutil/pp/Show.sv @@ -81,7 +81,7 @@ instance Show a => ShowTuple a { } instance Show () { - pp = \ dummy::() -> pp"()"; + pp = \ _ -> pp"()"; } -- Other standard lib types. diff --git a/grammars/silver/util/random/Arbitrary.sv b/grammars/silver/util/random/Arbitrary.sv index 2b1c7986f..a16a05bd0 100644 --- a/grammars/silver/util/random/Arbitrary.sv +++ b/grammars/silver/util/random/Arbitrary.sv @@ -11,15 +11,15 @@ class Arbitrary a { } instance Arbitrary Integer { - genArb = \ dummy::Integer -> randomRange(-100, 100); -- TODO: Is this a reasonable default? Revisit. + genArb = \ _ -> randomRange(-100, 100); -- TODO: Is this a reasonable default? Revisit. } instance Arbitrary Float { - genArb = \ dummy::Integer -> randomRange(-10.0, 10.0); -- TODO: Is this a reasonable default? Revisit. + genArb = \ _ -> randomRange(-10.0, 10.0); -- TODO: Is this a reasonable default? Revisit. } instance Arbitrary Boolean { - genArb = \ dummy::Integer -> random; + genArb = \ _ -> random; } instance Arbitrary String { From d9e081ef505d339d299c8216fb72dd16b7d9e570 Mon Sep 17 00:00:00 2001 From: unironically Date: Tue, 3 Oct 2023 15:59:13 -0500 Subject: [PATCH 071/283] Removing lambdap_new/lambda_c_new, new syntax defined for lambdap/lambda_c --- .../compiler/analysis/uniqueness/Expr.sv | 2 +- .../compiler/extension/do_notation/Syntax.sv | 4 +- .../extension/implicit_monads/Expr.sv | 8 ++-- .../implicit_monads/PrimitiveMatch.sv | 8 ++-- .../compiler/extension/rewriting/Expr.sv | 6 +-- .../compiler/modification/lambda_fn/Lambda.sv | 48 ++++--------------- 6 files changed, 24 insertions(+), 52 deletions(-) diff --git a/grammars/silver/compiler/analysis/uniqueness/Expr.sv b/grammars/silver/compiler/analysis/uniqueness/Expr.sv index f0da8e02d..b46a86bee 100644 --- a/grammars/silver/compiler/analysis/uniqueness/Expr.sv +++ b/grammars/silver/compiler/analysis/uniqueness/Expr.sv @@ -8,7 +8,7 @@ propagate uniqueRefs on Expr, Exprs, AppExprs, AppExpr, PrimPatterns, PrimPatter transDecoratedAccessHandler, annoAccessHandler, synDataAccessHandler, unknownDclAccessHandler, inhUndecoratedAccessErrorHandler, transUndecoratedAccessErrorHandler, - ifThenElse, lambdap, lambdap_new, letp, matchPrimitiveReal, consPattern; + ifThenElse, lambdap, letp, matchPrimitiveReal, consPattern; -- Unique references taken when this expression is wrapped in an attribute access synthesized attribute accessUniqueRefs::[(String, UniqueRefSite)] occurs on Expr; diff --git a/grammars/silver/compiler/extension/do_notation/Syntax.sv b/grammars/silver/compiler/extension/do_notation/Syntax.sv index cead6e9a9..b9078f8fd 100644 --- a/grammars/silver/compiler/extension/do_notation/Syntax.sv +++ b/grammars/silver/compiler/extension/do_notation/Syntax.sv @@ -125,7 +125,7 @@ top::DoBody ::= b::DoBinding rest::DoBody mkStrFunctionInvocation("silver:core:map", [ foldr( \ el::LambdaRHSElem trans::Expr -> - lambdap_new( + lambdap( lambdaRHSCons(el, lambdaRHSNil()), trans), top.appResult, top.appBindings), head(top.appExprs)]), @@ -233,7 +233,7 @@ top::DoBinding ::= n::Name DoDoubleColon_t t::TypeExpr '<-' e::Expr ';' top.appExprs = [e]; local cont :: Expr = - lambdap_new( + lambdap( lambdaRHSCons( lambdaRHSElemIdTy(n, terminal(ColonColon_t, "::"), t), lambdaRHSNil()), diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index 40a478761..4d2fa1b57 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -301,7 +301,7 @@ Expr ::= realtys::[Type] monadTysLocs::[Pair] monadAnns::[(Type, Q ([], length(realtys) + length(monadAnns)), monadAnns).1; local body::Expr = buildMonadApplicationBody(monadTysLocs ++ actualMonadAnns, funargs, funannargs, head(monadTysLocs).fst, funType, bindFun, wrapReturn); - return lambdap_new(params, body); + return lambdap(params, body); } --build the parameters for the lambda applied to all the original arguments plus the function function buildMonadApplicationParams @@ -360,7 +360,7 @@ Expr ::= monadTysLocs::[Pair] funargs::AppExprs annargs::AnnoAppEx oneAppExprs(presentAppExpr( baseExpr(qName("a"++toString(head(monadTysLocs).snd))))), ',', - presentAppExpr(lambdap_new(binding, sub))); + presentAppExpr(lambdap(binding, sub))); local step::Expr = applicationExpr(bind, '(', bindargs, ')'); @@ -379,7 +379,7 @@ Expr ::= monadTysLocs::[Pair] funargs::AppExprs annargs::AnnoAppEx oneAppExprs(presentAppExpr( baseExpr(qName("f")))), ',', - presentAppExpr(lambdap_new(funbinding, funapp))); + presentAppExpr(lambdap(funbinding, funapp))); local fullfun::Expr = if bindFun then applicationExpr(bind, '(', funbindargs, ')') @@ -1155,7 +1155,7 @@ top::Expr ::= 'decorate' e::Expr 'with' '{' inh::ExprInhs '}' then Silver_Expr { $Expr{monadBind()} ($Expr{eUnDec}, - $Expr{lambdap_new(params, + $Expr{lambdap(params, Silver_Expr{ $Expr{monadReturn()} ($Expr{decorateExprWith('decorate', diff --git a/grammars/silver/compiler/extension/implicit_monads/PrimitiveMatch.sv b/grammars/silver/compiler/extension/implicit_monads/PrimitiveMatch.sv index 5f9c83bfb..b32fb3ac9 100644 --- a/grammars/silver/compiler/extension/implicit_monads/PrimitiveMatch.sv +++ b/grammars/silver/compiler/extension/implicit_monads/PrimitiveMatch.sv @@ -98,13 +98,13 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr --bind e, just do the rest local justBind_e::Expr = buildApplication(eBind, - [e.monadRewritten, lambdap_new(binde_lambdaparams, + [e.monadRewritten, lambdap(binde_lambdaparams, matchPrimitiveReal(decName, outty, pr.monadRewritten, f.monadRewritten))]); --bind e, return f based on e's type local bind_e_return_f::Expr = buildApplication(eBind, - [e.monadRewritten, lambdap_new(binde_lambdaparams, + [e.monadRewritten, lambdap(binde_lambdaparams, matchPrimitiveReal(decName, outty, pr.monadRewritten, buildApplication(monadReturn(), @@ -117,14 +117,14 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr prReturnify.config = top.config; local bind_e_returnify_pr::Expr = buildApplication(eBind, - [e.monadRewritten, lambdap_new(binde_lambdaparams, + [e.monadRewritten, lambdap(binde_lambdaparams, matchPrimitiveReal(decName, outty, prReturnify.returnify, f.monadRewritten))]); --bind e, returnify pr, return f based on e's type local bind_e_returnify_pr_return_f::Expr = buildApplication(eBind, - [e.monadRewritten, lambdap_new(binde_lambdaparams, + [e.monadRewritten, lambdap(binde_lambdaparams, matchPrimitiveReal(decName, outty, prReturnify.returnify, buildApplication(monadReturn(), diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index cef7056d3..a0394e764 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -264,7 +264,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur Silver_Expr { silver:rewrite:anyASTExpr( $Expr{ - lambdap_new( + lambdap( lambdaRHSCons( lambdaRHSElemIdTy( name("_e"), '::', @@ -401,7 +401,7 @@ top::Expr ::= 'decorate' e::Expr 'with' '{' inh::ExprInhs '}' Silver_Expr { silver:rewrite:anyASTExpr( $Expr{ - lambdap_new( + lambdap( lambdaRHSCons( lambdaRHSElemIdTy( name("_e"), '::', @@ -627,7 +627,7 @@ top::Expr ::= 'case' es::Exprs 'of' o::Opt_Vbar_t ml::MRuleList 'end' Silver_Expr { silver:rewrite:anyASTExpr( $Expr{ - lambdap_new( + lambdap( decEs.lambdaParams, caseExpr_c( 'case', decEs.lambdaParamRefs, 'of', diff --git a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv index 30ea56434..d2b307777 100644 --- a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv +++ b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv @@ -4,12 +4,15 @@ import silver:util:treeset as ts; --- New concrete Syntax for lambdas -------------------------------------------------------------------------------- +terminal Lambda_kwd '\' lexer classes {KEYWORD,RESERVED}; +terminal Arrow_t '->' precedence = 0, lexer classes {SPECOP}; + concrete production lambda_c top::Expr ::= '\' params::LambdaRHS '->' e::Expr { top.unparse = "\\ " ++ params.unparse ++ " -> " ++ e.unparse; - forwards to lambdap_new(params, e); + forwards to lambdap(@params, @e); } abstract production lambdap @@ -53,6 +56,12 @@ nonterminal LambdaRHSElem with {- How much of the below belongs in other grammars? -} +monoid attribute lambdaDefs::[Def]; +monoid attribute lambdaBoundVars::[String]; + +inherited attribute givenLambdaId::Integer; +inherited attribute givenLambdaParamIndex::Integer; + flowtype decorate {forward, grammarName, flowEnv} on LambdaRHS, LambdaRHSElem; flowtype forward {env} on LambdaRHS; flowtype forward {deterministicCount, env} on LambdaRHSElem; @@ -138,43 +147,6 @@ top::LambdaRHSElem ::= '_' typerepTypeExpr(freshType())); } ---- Old concrete Syntax for lambdas --------------------------------------------------------------------------------- - -terminal Lambda_kwd '\' lexer classes {KEYWORD,RESERVED}; -terminal Arrow_t '->' precedence = 0, lexer classes {SPECOP}; - --- Using ProductionRHS here, it is basicly just a list of names with type expressions --- It is also used for the parameter definitions in functions, so using it here for consistancy -abstract production lambda_c_new -top::Expr ::= '\' params::LambdaRHS '->' e::Expr -{ - forwards to lambda_c ('\', @params, '->', @e); -} - -abstract production lambdap_new -top::Expr ::= params::LambdaRHS e::Expr -{ - forwards to lambdap (@params, @e); -} - -monoid attribute lambdaDefs::[Def]; -monoid attribute lambdaBoundVars::[String]; ---attribute lambdaDefs, lambdaBoundVars occurs on ProductionRHS, ProductionRHSElem; - ---flowtype lambdaDefs {decorate, givenLambdaId, givenLambdaParamIndex} on ProductionRHS, ProductionRHSElem; ---flowtype lambdaBoundVars {} on ProductionRHS; ---flowtype lambdaBoundVars {deterministicCount} on ProductionRHSElem; - ---propagate lambdaDefs, lambdaBoundVars on ProductionRHS; - -inherited attribute givenLambdaId::Integer occurs on ProductionRHS, ProductionRHSElem; -inherited attribute givenLambdaParamIndex::Integer occurs on ProductionRHS, ProductionRHSElem; ---propagate givenLambdaId on ProductionRHS, ProductionRHSElem; - -synthesized attribute asLamRHS::LambdaRHS occurs on ProductionRHS; -synthesized attribute asLamRHSElem::LambdaRHSElem occurs on ProductionRHSElem; - abstract production lambdaParamReference top::Expr ::= q::Decorated! QName { From 8a2a5e4f8c054be3b96ffede32bdce90e6724399 Mon Sep 17 00:00:00 2001 From: unironically Date: Tue, 3 Oct 2023 19:43:32 -0500 Subject: [PATCH 072/283] Fixed lambda syntax in silver_features test --- test/silver_features/DoNotation.sv | 2 +- test/silver_features/TypeClasses.sv | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/silver_features/DoNotation.sv b/test/silver_features/DoNotation.sv index eb2a25815..af48bf49d 100644 --- a/test/silver_features/DoNotation.sv +++ b/test/silver_features/DoNotation.sv @@ -85,7 +85,7 @@ global mutualMDo::Maybe<(Boolean ::= Integer)> = mdo { pure(123); even :: (Boolean ::= Integer) <- pure(\ x::Integer -> if x == 0 then true else odd(x - 1, ())); pure(456); - let odd :: (Boolean ::= Integer ()) = \ x::Integer () -> if x == 0 then false else even(x - 1); + let odd :: (Boolean ::= Integer ()) = \ x::Integer _ -> if x == 0 then false else even(x - 1); res::Boolean <- just(even(43)); return even; }; diff --git a/test/silver_features/TypeClasses.sv b/test/silver_features/TypeClasses.sv index 0fef0284a..a5433872d 100644 --- a/test/silver_features/TypeClasses.sv +++ b/test/silver_features/TypeClasses.sv @@ -14,7 +14,7 @@ class CFoo a => CBar a class CBaz a { cy :: a; - bazFromInt :: (a ::= Integer) = \ Integer -> cy; + bazFromInt :: (a ::= Integer) = \ _ -> cy; bazEq :: MyEq a => (Boolean ::= a) = \ x::a -> myeq(x, cy); } From b6a2bd50efa00bef4adcd8ad3667c57ecc6245e0 Mon Sep 17 00:00:00 2001 From: unironically Date: Tue, 3 Oct 2023 20:42:49 -0500 Subject: [PATCH 073/283] Fixed lambda syntax in implicit_monads test - use of tree sharing in lambda modification in lambda type parameter forwarding --- grammars/silver/compiler/modification/lambda_fn/Lambda.sv | 4 ++-- test/implicit_monads/MonadTest.sv | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv index d2b307777..3e03815b0 100644 --- a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv +++ b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv @@ -122,7 +122,7 @@ top::LambdaRHSElem ::= '_' '::' t::TypeExpr forwards to lambdaRHSElemIdTy ( name("_G_" ++ toString(top.deterministicCount)), '::', - t); + @t); } concrete production lambdaRHSElemId @@ -131,7 +131,7 @@ top::LambdaRHSElem ::= id::Name top.unparse = id.unparse; forwards to lambdaRHSElemIdTy ( - id, + @id, '::', typerepTypeExpr(freshType())); } diff --git a/test/implicit_monads/MonadTest.sv b/test/implicit_monads/MonadTest.sv index 50454701a..b19e7072f 100644 --- a/test/implicit_monads/MonadTest.sv +++ b/test/implicit_monads/MonadTest.sv @@ -98,10 +98,10 @@ instance Bind Unit { instance Monad Unit {} instance MonadFail Unit { - fail = \ String -> unitA(); + fail = \ _ -> unitA(); } instance Eq Unit { - eq = \ Unit Unit -> true; + eq = \ _ _ -> true; } From c570ecf5be91fe171159dcea53787ba01a078d93 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 4 Oct 2023 13:19:09 -0500 Subject: [PATCH 074/283] Add back the type signature somewhere where it was needed --- grammars/silver/compiler/extension/rewriting/Rewriting.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/compiler/extension/rewriting/Rewriting.sv b/grammars/silver/compiler/extension/rewriting/Rewriting.sv index 6bd7e85d2..7cb32fdea 100644 --- a/grammars/silver/compiler/extension/rewriting/Rewriting.sv +++ b/grammars/silver/compiler/extension/rewriting/Rewriting.sv @@ -252,7 +252,7 @@ top::Expr ::= 'rule' 'on' ty::TypeExpr 'of' Opt_Vbar_t ml::MRuleList 'end' then requireType(antiquoteASTExpr( Silver_Expr { silver:rewrite:anyASTExpr( - \ _ -> unit()) + \ _::$TypeExpr{typerepTypeExpr(finalRuleType, location=builtin)} -> unit()) })) <* ml.transform else ml.transform; From 5d25f955c7c289b1dd0da2288b17255eb2b8add5 Mon Sep 17 00:00:00 2001 From: unironically Date: Mon, 9 Oct 2023 14:51:49 -0500 Subject: [PATCH 075/283] Removed instance of location annotation --- grammars/silver/compiler/extension/rewriting/Rewriting.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/compiler/extension/rewriting/Rewriting.sv b/grammars/silver/compiler/extension/rewriting/Rewriting.sv index 7cb32fdea..a7b659794 100644 --- a/grammars/silver/compiler/extension/rewriting/Rewriting.sv +++ b/grammars/silver/compiler/extension/rewriting/Rewriting.sv @@ -252,7 +252,7 @@ top::Expr ::= 'rule' 'on' ty::TypeExpr 'of' Opt_Vbar_t ml::MRuleList 'end' then requireType(antiquoteASTExpr( Silver_Expr { silver:rewrite:anyASTExpr( - \ _::$TypeExpr{typerepTypeExpr(finalRuleType, location=builtin)} -> unit()) + \ _::$TypeExpr{typerepTypeExpr(finalRuleType)} -> unit()) })) <* ml.transform else ml.transform; From b8853383fd43308608de45df63ac42e576ff1143 Mon Sep 17 00:00:00 2001 From: unironically Date: Mon, 9 Oct 2023 19:32:13 -0500 Subject: [PATCH 076/283] Documentation added to new lambda productions. --- .../compiler/modification/lambda_fn/Lambda.sv | 60 ++++++++++++++----- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv index 3e03815b0..0904b7a10 100644 --- a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv +++ b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv @@ -1,12 +1,17 @@ import silver:compiler:definition:env; import silver:util:treeset as ts; ---- New concrete Syntax for lambdas +--- Concrete Syntax for lambdas -------------------------------------------------------------------------------- terminal Lambda_kwd '\' lexer classes {KEYWORD,RESERVED}; terminal Arrow_t '->' precedence = 0, lexer classes {SPECOP}; +{-- + - Concrete syntax for lambda expressions + - @param params Parameter name and signature declarations for this lambda + - @param e Body of the lambda + -} concrete production lambda_c top::Expr ::= '\' params::LambdaRHS '->' e::Expr { @@ -15,6 +20,11 @@ top::Expr ::= '\' params::LambdaRHS '->' e::Expr forwards to lambdap(@params, @e); } +{-- + - Abstract syntax for lambda expressions + - @param params Parameter name and signature declarations for this lambda + - @param e Body of the lambda + -} abstract production lambdap top::Expr ::= params::LambdaRHS e::Expr { @@ -23,7 +33,8 @@ top::Expr ::= params::LambdaRHS e::Expr propagate config, grammarName, compiledGrammars, errors, originRules; - top.typerep = appTypes(functionType(length(params.inputElements), []), map((.typerep), params.inputElements) ++ [e.typerep]); + top.typerep = appTypes(functionType(length(params.inputElements), []), + map((.typerep), params.inputElements) ++ [e.typerep]); production attribute sigDefs::[Def] with ++; sigDefs := params.lambdaDefs; @@ -44,18 +55,16 @@ top::Expr ::= params::LambdaRHS e::Expr nonterminal LambdaRHS with - --location, - givenLambdaParamIndex, givenLambdaId, env, grammarName, flowEnv, - lambdaBoundVars, lambdaDefs, lexicalTypeVariables, lexicalTyVarKinds, inputElements, unparse, elementCount; + givenLambdaParamIndex, givenLambdaId, env, grammarName, flowEnv, + lambdaBoundVars, lambdaDefs, lexicalTypeVariables, lexicalTyVarKinds, + inputElements, unparse, elementCount; nonterminal LambdaRHSElem with - --location, - givenLambdaParamIndex, givenLambdaId, grammarName, deterministicCount, env, flowEnv, - lambdaBoundVars, lambdaDefs, unparse, lexicalTypeVariables, inputElements, lexicalTyVarKinds; + givenLambdaParamIndex, givenLambdaId, grammarName, deterministicCount, env, + flowEnv, lambdaBoundVars, lambdaDefs, unparse, lexicalTypeVariables, + inputElements, lexicalTyVarKinds; -{- How much of the below belongs in other grammars? -} - monoid attribute lambdaDefs::[Def]; monoid attribute lambdaBoundVars::[String]; @@ -75,8 +84,11 @@ propagate flowEnv, env, grammarName, givenLambdaId, lexicalTyVarKinds on LambdaR propagate lexicalTypeVariables on LambdaRHS, LambdaRHSElem excluding lambdaRHSCons; -{- LambdaRHS productions -} - +{-- + - Cons production for the lambda parameter signature list NT + - @param h The head parameter signature + - @param t The rest of the parameter signature list + -} concrete production lambdaRHSCons top::LambdaRHS ::= h::LambdaRHSElem t::LambdaRHS { @@ -92,6 +104,9 @@ top::LambdaRHS ::= h::LambdaRHSElem t::LambdaRHS top.elementCount = 1 + t.elementCount; } +{-- + - Nil production for lambda parameter signature list NT + -} concrete production lambdaRHSNil top::LambdaRHS ::= { @@ -100,13 +115,18 @@ top::LambdaRHS ::= top.elementCount = 0; } -{- LambdaRHSElem productions -} +{-- + - Lambda parameter declarations with explicit name and type + - @param id The parameter name + - @param t The parameter type declaration + -} concrete production lambdaRHSElemIdTy top::LambdaRHSElem ::= id::Name '::' t::TypeExpr { production fName :: String = toString(genInt()) ++ ":" ++ id.name; - top.lambdaDefs := [lambdaParamDef(top.grammarName, id.nameLoc, fName, t.typerep, top.givenLambdaId, top.givenLambdaParamIndex)]; + top.lambdaDefs := [lambdaParamDef(top.grammarName, id.nameLoc, fName, t.typerep, + top.givenLambdaId, top.givenLambdaParamIndex)]; top.lambdaBoundVars := [id.name]; top.inputElements = [namedSignatureElement(id.name, t.typerep)]; @@ -114,6 +134,10 @@ top::LambdaRHSElem ::= id::Name '::' t::TypeExpr top.unparse = id.unparse ++ "::" ++ t.unparse; } +{-- + - Lambda parameter declarations with explicit type but no name + - @param t The parameter type declaration + -} concrete production lambdaRHSElemTy top::LambdaRHSElem ::= '_' '::' t::TypeExpr { @@ -125,6 +149,10 @@ top::LambdaRHSElem ::= '_' '::' t::TypeExpr @t); } +{-- + - Lambda parameter declarations with explicit name but no type + - @param id The parameter name + -} concrete production lambdaRHSElemId top::LambdaRHSElem ::= id::Name { @@ -136,6 +164,9 @@ top::LambdaRHSElem ::= id::Name typerepTypeExpr(freshType())); } +{-- + - Lambda parameter declarations with neither an explicit name nor type + -} concrete production lambdaRHSElemUnderline top::LambdaRHSElem ::= '_' { @@ -147,6 +178,7 @@ top::LambdaRHSElem ::= '_' typerepTypeExpr(freshType())); } + abstract production lambdaParamReference top::Expr ::= q::Decorated! QName { From ccc798cf29c839b0f82d9a7c3609fdbf241a40a9 Mon Sep 17 00:00:00 2001 From: unironically Date: Tue, 10 Oct 2023 00:15:43 -0500 Subject: [PATCH 077/283] Removed redundancies --- .../silver/compiler/extension/easyterminal/TerminalDcl.sv | 4 ---- grammars/silver/compiler/modification/copper/DclInfo.sv | 6 +++--- grammars/silver/core/List.sv | 2 +- grammars/silver/core/Maybe.sv | 4 ++-- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/grammars/silver/compiler/extension/easyterminal/TerminalDcl.sv b/grammars/silver/compiler/extension/easyterminal/TerminalDcl.sv index c1c3f12cf..609867b0f 100644 --- a/grammars/silver/compiler/extension/easyterminal/TerminalDcl.sv +++ b/grammars/silver/compiler/extension/easyterminal/TerminalDcl.sv @@ -69,8 +69,6 @@ top::ProductionRHSElem ::= id::Name '::' reg::EasyTerminalRef propagate env; top.errors <- reg.errors; - --top.lambdaBoundVars := [id.name]; -- Needed because we are forwrding based on env - forwards to productionRHSElem(id, $2, typerepTypeExpr(reg.typerep)); } @@ -81,8 +79,6 @@ top::ProductionRHSElem ::= reg::EasyTerminalRef propagate env; top.errors <- reg.errors; - --top.lambdaBoundVars := []; -- Needed because we are forwrding based on env - forwards to productionRHSElemType(typerepTypeExpr(reg.typerep)); } diff --git a/grammars/silver/compiler/modification/copper/DclInfo.sv b/grammars/silver/compiler/modification/copper/DclInfo.sv index fa6876981..2a36574ab 100644 --- a/grammars/silver/compiler/modification/copper/DclInfo.sv +++ b/grammars/silver/compiler/modification/copper/DclInfo.sv @@ -22,7 +22,7 @@ top::ValueDclInfo ::= fn::String ty::Type top.refDispatcher = parserAttributeReference; top.defDispatcher = parserAttributeValueDef; top.defLHSDispatcher = parserAttributeDefLHS; - top.transDefLHSDispatcher = \ q::Decorated! QName dummy::Decorated! QNameAttrOccur -> + top.transDefLHSDispatcher = \ q::Decorated! QName _ -> parserAttributeDefLHS(q); } @@ -96,7 +96,7 @@ top::ValueDclInfo ::= fn::String ty::Type top.refDispatcher = actionChildReference; top.defDispatcher = errorValueDef; top.defLHSDispatcher = parserAttributeDefLHS; -- TODO: specialize this - top.transDefLHSDispatcher = \ q::Decorated! QName dummy::Decorated! QNameAttrOccur -> + top.transDefLHSDispatcher = \ q::Decorated! QName _ -> parserAttributeDefLHS(q); } @@ -115,6 +115,6 @@ top::ValueDclInfo ::= fn::String ty::Type top.refDispatcher = parserAttributeReference; top.defDispatcher = parserAttributeValueDef; top.defLHSDispatcher = parserAttributeDefLHS; - top.transDefLHSDispatcher = \ q::Decorated! QName dummy::Decorated! QNameAttrOccur -> + top.transDefLHSDispatcher = \ q::Decorated! QName _ -> parserAttributeDefLHS(q); } diff --git a/grammars/silver/core/List.sv b/grammars/silver/core/List.sv index cc38ce29a..0ce9fe788 100644 --- a/grammars/silver/core/List.sv +++ b/grammars/silver/core/List.sv @@ -46,7 +46,7 @@ instance Bind [] { instance Monad [] {} instance MonadFail [] { - fail = \ dummy::String -> []; + fail = \ _ -> []; } instance Alt [] { diff --git a/grammars/silver/core/Maybe.sv b/grammars/silver/core/Maybe.sv index 61f8bb1f1..5403458d3 100644 --- a/grammars/silver/core/Maybe.sv +++ b/grammars/silver/core/Maybe.sv @@ -50,7 +50,7 @@ instance Bind Maybe { instance Monad Maybe {} instance MonadFail Maybe { - fail = \ dummy::String -> nothing(); + fail = \ _ -> nothing(); } instance Alt Maybe { @@ -138,7 +138,7 @@ instance Monad m => Bind MaybeT { instance Monad m => Monad MaybeT {} instance Monad m => MonadFail MaybeT { - fail = \ dummy::String -> maybeT(pure(nothing())); + fail = \ _ -> maybeT(pure(nothing())); } instance Monad m => Alt MaybeT { From 22aece3bd4477bd904e8b0c28e63f8aa8517eb3f Mon Sep 17 00:00:00 2001 From: unironically Date: Wed, 11 Oct 2023 16:29:44 -0500 Subject: [PATCH 078/283] Concise function syntax added as an extension --- .../extension/concisefunctions/Project.sv | 7 ++ .../extension/concisefunctions/Syntax.sv | 71 +++++++++++++++++++ grammars/silver/compiler/host/Project.sv | 1 + 3 files changed, 79 insertions(+) create mode 100644 grammars/silver/compiler/extension/concisefunctions/Project.sv create mode 100644 grammars/silver/compiler/extension/concisefunctions/Syntax.sv diff --git a/grammars/silver/compiler/extension/concisefunctions/Project.sv b/grammars/silver/compiler/extension/concisefunctions/Project.sv new file mode 100644 index 000000000..3596732f5 --- /dev/null +++ b/grammars/silver/compiler/extension/concisefunctions/Project.sv @@ -0,0 +1,7 @@ +grammar silver:compiler:extension:concisefunctions; + +imports silver:compiler:definition:core; +imports silver:compiler:modification:lambda_fn; +imports silver:compiler:definition:type:syntax hiding Arrow_t; -- We use lambda_fn:Arrow_t +imports silver:compiler:definition:type; +imports silver:compiler:definition:env; \ No newline at end of file diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv new file mode 100644 index 000000000..964ed7a90 --- /dev/null +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -0,0 +1,71 @@ +grammar silver:compiler:extension:concisefunctions; + +terminal Fun_kwd 'fun'; + +concrete production shortFunctionDcl +top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' +{ + forwards to + globalValueDclConcrete ( + 'global', id, '::', ns.cl, '=>', typerepTypeExpr(ns.namedSignature.typerep), '=', + lambda_c('\', ns.rhs.toLamRHS, '->', e),';' + ); +} + +synthesized attribute cl::ConstraintList occurs on FunctionSignature; +synthesized attribute lhs::FunctionLHS occurs on FunctionSignature; +synthesized attribute rhs::ProductionRHS occurs on FunctionSignature; + +aspect production functionSignature +top::FunctionSignature ::= cl::ConstraintList '=>' lhs::FunctionLHS '::=' rhs::ProductionRHS +{ + top.cl = cl; + top.lhs = lhs; + top.rhs = rhs; + top.t = lhs.t; +} + +aspect production functionSignatureNoCL +top::FunctionSignature ::= lhs::FunctionLHS '::=' rhs::ProductionRHS +{ + top.cl = nilConstraint(); + top.lhs = lhs; + top.rhs = rhs; + top.t = lhs.t; +} + +synthesized attribute t::TypeExpr occurs on FunctionLHS, FunctionSignature; + +aspect production functionLHS +top::FunctionLHS ::= t::TypeExpr +{ + top.t = t; +} + +synthesized attribute toLamRHS::LambdaRHS occurs on ProductionRHS; + +aspect production productionRHSNil +top::ProductionRHS ::= +{ + top.toLamRHS = lambdaRHSNil(); +} + +aspect production productionRHSCons +top::ProductionRHS ::= h::ProductionRHSElem t::ProductionRHS +{ + top.toLamRHS = lambdaRHSCons(h.toLamRHSElem, t.toLamRHS); +} + +synthesized attribute toLamRHSElem::LambdaRHSElem occurs on ProductionRHSElem; + +aspect production productionRHSElem +top::ProductionRHSElem ::= id::Name '::' t::TypeExpr +{ + top.toLamRHSElem = lambdaRHSElemIdTy(id, '::', t); +} + +aspect production productionRHSElemType +top::ProductionRHSElem ::= t::TypeExpr +{ + top.toLamRHSElem = lambdaRHSElemTy('_', '::', t); +} \ No newline at end of file diff --git a/grammars/silver/compiler/host/Project.sv b/grammars/silver/compiler/host/Project.sv index e6f6d3751..68cc8f8ca 100644 --- a/grammars/silver/compiler/host/Project.sv +++ b/grammars/silver/compiler/host/Project.sv @@ -50,6 +50,7 @@ exports silver:compiler:extension:attrsection; exports silver:compiler:extension:implicit_monads; exports silver:compiler:extension:data; exports silver:compiler:extension:deriving; +exports silver:compiler:extension:concisefunctions; -- Other generally useful stuff: exports silver:compiler:translation:java; From 2eb434ae66a66595d0ea7d8351c90c2cbe7453c7 Mon Sep 17 00:00:00 2001 From: unironically Date: Wed, 11 Oct 2023 17:14:17 -0500 Subject: [PATCH 079/283] Addressing MWDA issues --- .../silver/compiler/extension/concisefunctions/Project.sv | 3 ++- .../silver/compiler/extension/concisefunctions/Syntax.sv | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/grammars/silver/compiler/extension/concisefunctions/Project.sv b/grammars/silver/compiler/extension/concisefunctions/Project.sv index 3596732f5..ee259e8ad 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Project.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Project.sv @@ -4,4 +4,5 @@ imports silver:compiler:definition:core; imports silver:compiler:modification:lambda_fn; imports silver:compiler:definition:type:syntax hiding Arrow_t; -- We use lambda_fn:Arrow_t imports silver:compiler:definition:type; -imports silver:compiler:definition:env; \ No newline at end of file +imports silver:compiler:definition:env; +imports silver:compiler:definition:flow:env; \ No newline at end of file diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv index 964ed7a90..00217b29e 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -5,7 +5,12 @@ terminal Fun_kwd 'fun'; concrete production shortFunctionDcl top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' { - forwards to + propagate flowEnv, grammarName; + + ns.signatureName = top.grammarName ++ ":" ++ id.name; + ns.env = newScopeEnv(ns.defs, top.env); + + forwards to globalValueDclConcrete ( 'global', id, '::', ns.cl, '=>', typerepTypeExpr(ns.namedSignature.typerep), '=', lambda_c('\', ns.rhs.toLamRHS, '->', e),';' From d87c50c687fa7d83495d532ab1e95c31a70df9d7 Mon Sep 17 00:00:00 2001 From: unironically Date: Wed, 11 Oct 2023 17:59:00 -0500 Subject: [PATCH 080/283] Addressing MWDA issues - episode 2 --- .../compiler/extension/concisefunctions/Syntax.sv | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv index 00217b29e..ce6050d98 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -5,15 +5,20 @@ terminal Fun_kwd 'fun'; concrete production shortFunctionDcl top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' { - propagate flowEnv, grammarName; - + propagate flowEnv, grammarName, moduleNames; + + top.unparse = "fun " ++ id.unparse ++ "::" ++ ns.unparse ++ " = " ++ e.unparse ++ ";"; + ns.signatureName = top.grammarName ++ ":" ++ id.name; ns.env = newScopeEnv(ns.defs, top.env); + local prodRHS::ProductionRHS = ns.rhs; + prodRHS.env = ns.env; + forwards to globalValueDclConcrete ( - 'global', id, '::', ns.cl, '=>', typerepTypeExpr(ns.namedSignature.typerep), '=', - lambda_c('\', ns.rhs.toLamRHS, '->', e),';' + 'global', @id, '::', ns.cl, '=>', typerepTypeExpr(ns.namedSignature.typerep), '=', + lambda_c('\', prodRHS.toLamRHS, '->', @e),';' ); } From 1b301840b0f080b5613f496106963be83413f59d Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 22 Aug 2023 17:38:09 -0500 Subject: [PATCH 081/283] Fix bugs with kind error handling for occurs-on constraints --- .../definition/type/syntax/Constraint.sv | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/grammars/silver/compiler/definition/type/syntax/Constraint.sv b/grammars/silver/compiler/definition/type/syntax/Constraint.sv index d9a82d2f8..22acc6fc5 100644 --- a/grammars/silver/compiler/definition/type/syntax/Constraint.sv +++ b/grammars/silver/compiler/definition/type/syntax/Constraint.sv @@ -118,14 +118,17 @@ top::Constraint ::= 'attribute' at::QName attl::BracketedOptTypeExprs 'occurs' ' else if map((.kindrep), atTypeScheme.boundVars) != map((.kindrep), attl.types) then [errFromOrigin(at, at.name ++ " has kind " ++ prettyKind(foldr(arrowKind, starKind(), map((.kindrep), atTypeScheme.boundVars))) ++ - "but type variable(s) have kind(s) " ++ implode(", ", map(compose(prettyKind, (.kindrep)), attl.types)) ++ ".")] + " but type variable(s) have kind(s) " ++ implode(", ", map(compose(prettyKind, (.kindrep)), attl.types)) ++ ".")] else []; top.errors <- t.errorsKindStar; local atTypeScheme::PolyType = at.lookupAttribute.typeScheme; local rewrite :: Substitution = zipVarsAndTypesIntoSubstitution(atTypeScheme.boundVars, attl.types); - production attrTy::Type = performRenaming(atTypeScheme.typerep, rewrite); + production attrTy::Type = + if map((.kindrep), atTypeScheme.boundVars) == map((.kindrep), attl.types) + then performRenaming(atTypeScheme.typerep, rewrite) + else errorType(); local instDcl::OccursDclInfo = top.constraintPos.occursInstDcl(fName, t.typerep, attrTy); top.occursDefs <- [instDcl]; @@ -160,7 +163,7 @@ top::Constraint ::= 'attribute' at::QName attl::BracketedOptTypeExprs i::TypeExp else if map((.kindrep), atTypeScheme.boundVars) != map((.kindrep), attl.types) then [errFromOrigin(at, at.name ++ " has kind " ++ prettyKind(foldr(arrowKind, starKind(), map((.kindrep), atTypeScheme.boundVars))) ++ - "but type variable(s) have kind(s) " ++ implode(", ", map(compose(prettyKind, (.kindrep)), attl.types)) ++ ".")] + " but type variable(s) have kind(s) " ++ implode(", ", map(compose(prettyKind, (.kindrep)), attl.types)) ++ ".")] else []; top.errors <- @@ -172,7 +175,10 @@ top::Constraint ::= 'attribute' at::QName attl::BracketedOptTypeExprs i::TypeExp local atTypeScheme::PolyType = at.lookupAttribute.typeScheme; local rewrite :: Substitution = zipVarsAndTypesIntoSubstitution(atTypeScheme.boundVars, attl.types); - production attrTy::Type = performRenaming(atTypeScheme.typerep, rewrite); + production attrTy::Type = + if map((.kindrep), atTypeScheme.boundVars) == map((.kindrep), attl.types) + then performRenaming(atTypeScheme.typerep, rewrite) + else errorType(); local instDcl::OccursDclInfo = top.constraintPos.occursInstDcl(fName, t.typerep, attrTy); top.occursDefs <- [instDcl]; @@ -213,14 +219,17 @@ top::Constraint ::= 'annotation' at::QName attl::BracketedOptTypeExprs 'occurs' else if map((.kindrep), atTypeScheme.boundVars) != map((.kindrep), attl.types) then [errFromOrigin(at, at.name ++ " has kind " ++ prettyKind(foldr(arrowKind, starKind(), map((.kindrep), atTypeScheme.boundVars))) ++ - "but type variable(s) have kind(s) " ++ implode(", ", map(compose(prettyKind, (.kindrep)), attl.types)) ++ ".")] + " but type variable(s) have kind(s) " ++ implode(", ", map(compose(prettyKind, (.kindrep)), attl.types)) ++ ".")] else []; top.errors <- t.errorsKindStar; local atTypeScheme::PolyType = at.lookupAttribute.typeScheme; local rewrite :: Substitution = zipVarsAndTypesIntoSubstitution(atTypeScheme.boundVars, attl.types); - production attrTy::Type = performRenaming(atTypeScheme.typerep, rewrite); + production attrTy::Type = + if map((.kindrep), atTypeScheme.boundVars) == map((.kindrep), attl.types) + then performRenaming(atTypeScheme.typerep, rewrite) + else errorType(); local instDcl::OccursDclInfo = top.constraintPos.occursInstDcl(fName, t.typerep, attrTy); top.occursDefs <- [instDcl]; From b9b5869d38073bafe33af942101115d4f38d2b60 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 11 Sep 2023 13:38:46 -0500 Subject: [PATCH 082/283] Make TyVar and BuildEnv be data nonterminals --- .../compiler/definition/core/ClassDcl.sv | 2 +- .../compiler/definition/core/OccursDcl.sv | 6 +- .../definition/core/ProductionBody.sv | 4 +- .../silver/compiler/definition/env/DclInfo.sv | 8 ++- .../silver/compiler/definition/env/Type.sv | 6 +- .../definition/flow/syntax/FlowSpec.sv | 2 +- .../silver/compiler/definition/type/Kind.sv | 4 +- .../definition/type/PrettyPrinting.sv | 8 +-- .../compiler/definition/type/Substitutions.sv | 14 ++--- .../silver/compiler/definition/type/Type.sv | 55 +++++++------------ .../compiler/definition/type/Unification.sv | 22 ++++---- .../definition/type/syntax/AspectDcl.sv | 2 +- .../definition/type/syntax/Constraint.sv | 18 +++--- .../definition/type/syntax/KindExpr.sv | 2 +- .../definition/type/syntax/TypeExpr.sv | 2 +- grammars/silver/compiler/driver/Command.sv | 24 ++++---- .../silver/compiler/driver/util/BuildEnv.sv | 27 +++++---- .../extension/astconstruction/Syntax.sv | 2 +- .../compiler/extension/deriving/Derive.sv | 4 +- .../extension/doc/core/DocumentedAGDcl.sv | 2 +- .../extension/doc/driver/BuildProcess.sv | 8 +-- .../modification/copper/BuildProcess.sv | 4 +- .../modification/primitivepattern/Types.sv | 8 +-- .../translation/java/core/NamedSignature.sv | 2 +- .../translation/java/driver/BuildProcess.sv | 10 ++-- .../compiler/translation/java/type/Context.sv | 2 +- .../compiler/translation/java/type/Type.sv | 4 +- .../silver/langserver/SilverCompiler.java | 4 +- test/stdlib/cmdargs/TestCmdArgs.sv | 8 +-- 29 files changed, 124 insertions(+), 140 deletions(-) diff --git a/grammars/silver/compiler/definition/core/ClassDcl.sv b/grammars/silver/compiler/definition/core/ClassDcl.sv index 648e90968..c67aa974e 100644 --- a/grammars/silver/compiler/definition/core/ClassDcl.sv +++ b/grammars/silver/compiler/definition/core/ClassDcl.sv @@ -103,7 +103,7 @@ top::ClassBody ::= concrete production classBodyItem top::ClassBodyItem ::= id::Name '::' ty::TypeExpr ';' { - forwards to constraintClassBodyItem(id, $2, nilConstraint(), '=>', ty, $4); + forwards to constraintClassBodyItem(id, $2, nilConstraint(), '=>', @ty, $4); } action { insert semantic token IdTypeClassMemberDcl_t at id.nameLoc; } diff --git a/grammars/silver/compiler/definition/core/OccursDcl.sv b/grammars/silver/compiler/definition/core/OccursDcl.sv index 086fa8433..a66c176f9 100644 --- a/grammars/silver/compiler/definition/core/OccursDcl.sv +++ b/grammars/silver/compiler/definition/core/OccursDcl.sv @@ -15,7 +15,7 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: (if !at.lookupAttribute.dcl.isAnnotation then occursDcl else annoInstanceDcl)( nt.lookupType.fullName, at.lookupAttribute.fullName, protontty, - if ntParamKinds == map((.kindrep), nttl.types) && map((.kindrep), atTypeScheme.boundVars) == map((.kindrep), attl.types) + if ntParamKinds == map((.kindrep), nttl.types) && map((.kind), atTypeScheme.boundVars) == map((.kindrep), attl.types) then protoatty else errorType(), sourceGrammar=top.grammarName, sourceLocation=at.nameLoc)]; @@ -64,9 +64,9 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: then [errFromOrigin(at, at.name ++ " expects " ++ toString(length(atTypeScheme.boundVars)) ++ " type variables, but " ++ toString(length(attl.types)) ++ " were provided.")] - else if map((.kindrep), atTypeScheme.boundVars) != map((.kindrep), attl.types) + else if map((.kind), atTypeScheme.boundVars) != map((.kindrep), attl.types) then [errFromOrigin(at, - at.name ++ " has kind " ++ prettyKind(foldr(arrowKind, starKind(), map((.kindrep), atTypeScheme.boundVars))) ++ + at.name ++ " has kind " ++ prettyKind(foldr(arrowKind, starKind(), map((.kind), atTypeScheme.boundVars))) ++ " but type variable(s) have kind(s) " ++ implode(", ", map(compose(prettyKind, (.kindrep)), attl.types)) ++ ".")] else []; diff --git a/grammars/silver/compiler/definition/core/ProductionBody.sv b/grammars/silver/compiler/definition/core/ProductionBody.sv index 2a227a1e6..cf81be33b 100644 --- a/grammars/silver/compiler/definition/core/ProductionBody.sv +++ b/grammars/silver/compiler/definition/core/ProductionBody.sv @@ -529,7 +529,7 @@ top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur local ty::Type = q.lookupValue.typeScheme.monoType; top.errors <- if attr.found && !ty.isNonterminal && !ty.isUniqueDecorated - then [errFromOrigin(q, s"Inherited equations on translation attributes on child ${q.name} of type ${prettyType(ty)} are not supported")] + then [errFromOrigin(q, s"Inherited equations on translation attributes on child ${q.name} of type ${prettyType(new(ty))} are not supported")] else []; top.typerep = attr.typerep; @@ -554,7 +554,7 @@ top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur local ty::Type = q.lookupValue.typeScheme.monoType; top.errors <- if attr.found && !ty.isNonterminal && !ty.isUniqueDecorated - then [errFromOrigin(q, s"Inherited equations on translation attributes on local ${q.name} of type ${prettyType(ty)} are not supported")] + then [errFromOrigin(q, s"Inherited equations on translation attributes on local ${q.name} of type ${prettyType(new(ty))} are not supported")] else []; top.typerep = attr.typerep; diff --git a/grammars/silver/compiler/definition/env/DclInfo.sv b/grammars/silver/compiler/definition/env/DclInfo.sv index da9d7ab0f..f0d16cdbe 100644 --- a/grammars/silver/compiler/definition/env/DclInfo.sv +++ b/grammars/silver/compiler/definition/env/DclInfo.sv @@ -195,7 +195,7 @@ top::TypeDclInfo ::= fn::String isAspect::Boolean tv::TyVar -- Lexical type vars in aspects aren't skolemized, since they unify with the real (skolem) types. -- See comment in silver:compiler:definition:type:syntax:AspectDcl.sv top.typeScheme = monoType(if isAspect then varType(tv) else skolemType(tv)); - top.kindrep = tv.kindrep; + top.kindrep = tv.kind; top.isType = true; } abstract production typeAliasDcl @@ -213,7 +213,7 @@ top::TypeDclInfo ::= fn::String mentionedAliases::[String] bound::[TyVar] ty::Ty top.isTypeAlias = true; top.mentionedAliases := mentionedAliases; top.typeScheme = if null(bound) then monoType(ty) else polyType(bound, ty); - top.kindrep = foldr(arrowKind, ty.kindrep, map((.kindrep), bound)); + top.kindrep = foldr(arrowKind, ty.kindrep, map((.kind), bound)); } abstract production clsDcl top::TypeDclInfo ::= fn::String supers::[Context] tv::TyVar k::Kind members::[Pair] @@ -222,7 +222,9 @@ top::TypeDclInfo ::= fn::String supers::[Context] tv::TyVar k::Kind members::[Pa top.isEqual = case top.compareTo of | clsDcl(fn2, s2, tv2, k2, m2) -> - fn == fn2 && k == k2 && supers == map(performContextRenaming(_, subst(tv2, skolemType(tv))), s2) && members == m2 + fn == fn2 && new(k) == new(k2) && + supers == map(performContextRenaming(_, subst(tv2, skolemType(tv))), s2) && + members == m2 | _ -> false end; diff --git a/grammars/silver/compiler/definition/env/Type.sv b/grammars/silver/compiler/definition/env/Type.sv index ae884881f..a4e1589ac 100644 --- a/grammars/silver/compiler/definition/env/Type.sv +++ b/grammars/silver/compiler/definition/env/Type.sv @@ -78,13 +78,13 @@ top::Type ::= tv::TyVar attribute typeName occurs on TyVar; aspect production tyVar -top::TyVar ::= k::Kind i::Integer +top::TyVar ::= { - top.typeName = "_a" ++ toString(i); + top.typeName = "_a" ++ toString(top.varId); } aspect production tyVarNamed -top::TyVar ::= k::Kind i::Integer n::String +top::TyVar ::= n::String { top.typeName = n; } diff --git a/grammars/silver/compiler/definition/flow/syntax/FlowSpec.sv b/grammars/silver/compiler/definition/flow/syntax/FlowSpec.sv index a724d277c..6d1450963 100644 --- a/grammars/silver/compiler/definition/flow/syntax/FlowSpec.sv +++ b/grammars/silver/compiler/definition/flow/syntax/FlowSpec.sv @@ -42,7 +42,7 @@ top::AGDcl ::= 'flowtype' attr::FlowSpec 'on' nts::NtList ';' top.errors := nts.errors; top.specDefs := nts.specDefs; - nts.flowSpecSpec = attr; + nts.flowSpecSpec = new(attr); } diff --git a/grammars/silver/compiler/definition/type/Kind.sv b/grammars/silver/compiler/definition/type/Kind.sv index 91af94dad..16f2701e4 100644 --- a/grammars/silver/compiler/definition/type/Kind.sv +++ b/grammars/silver/compiler/definition/type/Kind.sv @@ -9,7 +9,7 @@ propagate compareTo, isEqual on Kind; aspect default production top::Kind ::= { - top.baseKind = top; + top.baseKind = new(top); top.argKinds = []; } @@ -25,7 +25,7 @@ abstract production arrowKind top::Kind ::= k1::Kind k2::Kind { top.baseKind = k2.baseKind; - top.argKinds = k1 :: k2.argKinds; + top.argKinds = new(k1) :: k2.argKinds; } global constructorKind::(Kind ::= Integer) = \ arity::Integer -> diff --git a/grammars/silver/compiler/definition/type/PrettyPrinting.sv b/grammars/silver/compiler/definition/type/PrettyPrinting.sv index f329ba256..b067560d6 100644 --- a/grammars/silver/compiler/definition/type/PrettyPrinting.sv +++ b/grammars/silver/compiler/definition/type/PrettyPrinting.sv @@ -261,8 +261,8 @@ top::Kind ::= k1::Kind k2::Kind function findAbbrevFor String ::= tv::TyVar bv::[TyVar] { - local named::[TyVar] = filter(\ tv::TyVar -> case tv of tyVarNamed(_, _, _) -> true | _ -> false end, bv); - local anon::[TyVar] = filter(\ tv::TyVar -> case tv of tyVarNamed(_, _, _) -> false | _ -> true end, bv); + local named::[TyVar] = filter(\ tv::TyVar -> case tv of tyVarNamed(_) -> true | _ -> false end, bv); + local anon::[TyVar] = filter(\ tv::TyVar -> case tv of tyVarNamed(_) -> false | _ -> true end, bv); return findAbbrevHelp(tv, named ++ anon, ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], []); } @@ -271,7 +271,7 @@ String ::= tv::TyVar bv::[TyVar] vn::[String] assigned::[String] { return case bv, vn of - | tyVarNamed(_, _, n) :: tbv, _ when !contains(n, assigned) -> + | tyVarNamed(n) :: tbv, _ when !contains(n, assigned) -> if tv == head(bv) then n else findAbbrevHelp(tv, tbv, vn, n :: assigned) | hbv :: tbv, hvn :: tvn -> if contains(hvn, assigned) @@ -280,7 +280,7 @@ String ::= tv::TyVar bv::[TyVar] vn::[String] assigned::[String] | _, _ -> case positionOf(tv, bv) of | i when i > 0 && !contains("a" ++ toString(i), assigned) -> "a" ++ toString(i) - | _ -> "V_" ++ toString(tv.extractTyVarRep) + | _ -> "V_" ++ toString(tv.varId) end end; } diff --git a/grammars/silver/compiler/definition/type/Substitutions.sv b/grammars/silver/compiler/definition/type/Substitutions.sv index 1db91d057..8496f02be 100644 --- a/grammars/silver/compiler/definition/type/Substitutions.sv +++ b/grammars/silver/compiler/definition/type/Substitutions.sv @@ -119,7 +119,7 @@ top::Type ::= tv::TyVar -- Perform one iteration of substitution local partialsubst :: Maybe = case findSubst(tv, top.substitution) of - | just(s) when s.kindrep != tv.kindrep -> error("Kind mismatch in applying substitution!") + | just(s) when s.kindrep != tv.kind -> error("Kind mismatch in applying substitution!") | ps -> ps end; @@ -127,11 +127,11 @@ top::Type ::= tv::TyVar top.substituted = if partialsubst.isJust then performSubstitution(partialsubst.fromJust, top.substitution) - else top; + else new(top); top.flatRenamed = if partialsubst.isJust then partialsubst.fromJust - else top; + else new(top); } aspect production skolemType @@ -153,7 +153,7 @@ top::Type ::= tv::TyVar local partialsubst :: Maybe = case findSubst(tv, top.substitution) of - | just(s) when s.kindrep != tv.kindrep -> nothing() + | just(s) when s.kindrep != tv.kind -> nothing() | ps -> ps end; @@ -161,11 +161,11 @@ top::Type ::= tv::TyVar top.substituted = if partialsubst.isJust then performSubstitution(partialsubst.fromJust, top.substitution) - else top; + else new(top); top.flatRenamed = if partialsubst.isJust then partialsubst.fromJust - else top; + else new(top); } aspect production ntOrDecType @@ -232,7 +232,7 @@ function mapRenameSubst function freshTyVars [TyVar] ::= tvs::[TyVar] { - return map(freshTyVar, map((.kindrep), tvs)); + return map(freshTyVar, map((.kind), tvs)); } function zipVarsIntoSubstitution diff --git a/grammars/silver/compiler/definition/type/Type.sv b/grammars/silver/compiler/definition/type/Type.sv index 979f0ea0e..cf8a8ad71 100644 --- a/grammars/silver/compiler/definition/type/Type.sv +++ b/grammars/silver/compiler/definition/type/Type.sv @@ -22,8 +22,8 @@ top::PolyType ::= ty::Type { top.boundVars = []; top.contexts = []; - top.typerep = ty; - top.monoType = ty; + top.typerep = new(ty); + top.monoType = new(ty); } abstract production polyType @@ -31,7 +31,7 @@ top::PolyType ::= bound::[TyVar] ty::Type { top.boundVars = freshTyVars(bound); top.contexts = []; - top.typerep = freshenTypeWith(ty, bound, top.boundVars); + top.typerep = freshenTypeWith(new(ty), bound, top.boundVars); top.monoType = error("Expected a mono type but found a poly type!"); } @@ -40,7 +40,7 @@ top::PolyType ::= bound::[TyVar] contexts::[Context] ty::Type { top.boundVars = freshTyVars(bound); top.contexts = map(freshenContextWith(_, bound, top.boundVars), contexts); - top.typerep = freshenTypeWith(ty, bound, top.boundVars); + top.typerep = freshenTypeWith(new(ty), bound, top.boundVars); top.monoType = error("Expected a mono type but found a (constraint) poly type!"); } @@ -59,19 +59,19 @@ top::Context ::= cls::String t::Type abstract production inhOccursContext top::Context ::= attr::String args::[Type] atty::Type ntty::Type { - top.freeVariables = setUnionTyVarsAll(map((.freeVariables), args ++ [ntty])); + top.freeVariables = setUnionTyVarsAll(map((.freeVariables), args) ++ [ntty.freeVariables]); } abstract production synOccursContext top::Context ::= attr::String args::[Type] atty::Type inhs::Type ntty::Type { - top.freeVariables = setUnionTyVarsAll(map((.freeVariables), args ++ [inhs, ntty])); + top.freeVariables = setUnionTyVarsAll(map((.freeVariables), args) ++ [inhs.freeVariables, ntty.freeVariables]); } abstract production annoOccursContext top::Context ::= attr::String args::[Type] atty::Type ntty::Type { - top.freeVariables = setUnionTyVarsAll(map((.freeVariables), args ++ [ntty])); + top.freeVariables = setUnionTyVarsAll(map((.freeVariables), args) ++ [ntty.freeVariables]); } abstract production typeableContext @@ -105,7 +105,7 @@ flowtype Type = decorate {}, forward {}; abstract production varType top::Type ::= tv::TyVar { - top.kindrep = tv.kindrep; + top.kindrep = tv.kind; top.freeVariables = [tv]; } @@ -116,7 +116,7 @@ top::Type ::= tv::TyVar abstract production skolemType top::Type ::= tv::TyVar { - top.kindrep = tv.kindrep; + top.kindrep = tv.kind; top.freeVariables = [tv]; } @@ -128,7 +128,7 @@ top::Type ::= c::Type a::Type { top.kindrep = case c.kindrep of - | arrowKind(_, k) -> k + | arrowKind(_, k) -> new(k) | _ -> starKind() end; top.freeVariables = setUnionTyVars(c.freeVariables, a.freeVariables); @@ -337,36 +337,19 @@ top::Type ::= params::Integer namedParams::[String] -------------------------------------------------------------------------------- -tracked nonterminal TyVar with kindrep, compareTo, isEqual; -propagate compareTo, isEqual on TyVar; +annotation varId :: Integer; +annotation kind :: Kind; --- In essence, this should be 'private' to this file. -synthesized attribute extractTyVarRep :: Integer occurs on TyVar; +data TyVar = tyVar | tyVarNamed n::String + with varId, kind; -abstract production tyVar -top::TyVar ::= k::Kind i::Integer -{ - top.kindrep = k; - top.extractTyVarRep = i; +instance Eq TyVar { + -- Shouldn't need to compare kinds here, since all type vars have a unique id. + eq = \ x::TyVar y::TyVar -> x.varId == y.varId; --&& x.kind == y.kind; } -abstract production tyVarNamed -top::TyVar ::= k::Kind i::Integer n::String -{ - forwards to tyVar(k, i); -} - -function freshTyVar -TyVar ::= k::Kind -{ - return tyVar(k, genInt()); -} - -function freshTyVarNamed -TyVar ::= k::Kind n::String -{ - return tyVarNamed(k, genInt(), n); -} +global freshTyVar::(TyVar ::= Kind) = \ k::Kind -> tyVar(kind=k, varId=genInt()); +global freshTyVarNamed::(TyVar ::= String Kind) = \ n::String k::Kind -> tyVarNamed(n, kind=k, varId=genInt()); function freshType Type ::= diff --git a/grammars/silver/compiler/definition/type/Unification.sv b/grammars/silver/compiler/definition/type/Unification.sv index 78a058464..946167bd1 100644 --- a/grammars/silver/compiler/definition/type/Unification.sv +++ b/grammars/silver/compiler/definition/type/Unification.sv @@ -9,11 +9,11 @@ top::Type ::= tv::TyVar { top.unify = case top.unifyWith of - | varType(j) when j.kindrep == tv.kindrep -> + | varType(j) when j.kind == tv.kind -> if tv == j then emptySubst() else subst(tv, top.unifyWith) - | t when t.kindrep == tv.kindrep -> + | t when t.kindrep == tv.kind -> if contains(tv, top.unifyWith.freeVariables) then errorSubst("Infinite type! Tried to unify with " ++ prettyType(top.unifyWith)) else subst(tv, top.unifyWith) @@ -26,7 +26,7 @@ top::Type ::= tv::TyVar { top.unify = case top.unifyWith of - | skolemType(otv) when tv.kindrep == otv.kindrep -> + | skolemType(otv) when tv.kind == otv.kind -> if tv == otv then emptySubst() else errorSubst("Tried to unify skolem constant with incompatible skolem constant") @@ -40,10 +40,10 @@ top::Type ::= c::Type a::Type top.unify = case top.unifyWith of | appType(c1, a1) -> - let unifyC :: Substitution = unify(c, c1) - in composeSubst(unifyC, unify(performSubstitution(a, unifyC), performSubstitution(a1, unifyC))) + let unifyC :: Substitution = unify(new(c), new(c1)) + in composeSubst(unifyC, unify(performSubstitution(new(a), unifyC), performSubstitution(new(a1), unifyC))) end - | _ -> errorSubst("Tried to unify application of " ++ prettyType(c) ++ " with " ++ prettyType(top.unifyWith)) + | _ -> errorSubst("Tried to unify application of " ++ prettyType(new(c)) ++ " with " ++ prettyType(top.unifyWith)) end; } @@ -112,7 +112,7 @@ top::Type ::= fn::String ks::[Kind] data::Boolean tracked::Boolean if fn == ofn --&& data == odata && tracked == otracked -- Mismatched data/tractness can happen when comparing interface files then if ks == oks then emptySubst() - else error("kind mismatch during unification for " ++ prettyType(top) ++ " and " ++ prettyType(top.unifyWith)) -- Should be impossible + else error("kind mismatch during unification for " ++ prettyType(new(top)) ++ " and " ++ prettyType(top.unifyWith)) -- Should be impossible else errorSubst("Tried to unify conflicting nonterminal types " ++ fn ++ " and " ++ ofn) | ntOrDecType(_, _, _) -> errorSubst("nte-nodte: try again") | _ -> errorSubst("Tried to unify nonterminal type " ++ fn ++ " with " ++ prettyType(top.unifyWith)) @@ -138,7 +138,7 @@ top::Type ::= inhs::[String] top.unify = case top.unifyWith of | inhSetType(oinhs) when inhs == oinhs -> emptySubst() - | _ -> errorSubst("Tried to unify inh set type " ++ prettyType(top) ++ " with " ++ prettyType(top.unifyWith)) + | _ -> errorSubst("Tried to unify inh set type " ++ prettyType(new(top)) ++ " with " ++ prettyType(top.unifyWith)) end; } @@ -202,7 +202,7 @@ top::Type ::= params::Integer namedParams::[String] top.unify = case top.unifyWith of | functionType(op, onp) when params == op && namedParams == onp -> emptySubst() - | _ -> errorSubst("Tried to unify conflicting function types " ++ prettyType(top) ++ " and " ++ prettyType(top.unifyWith)) + | _ -> errorSubst("Tried to unify conflicting function types " ++ prettyType(new(top)) ++ " and " ++ prettyType(top.unifyWith)) end; } @@ -212,10 +212,10 @@ function unify Substitution ::= te1::Type te2::Type { local leftward :: Substitution = te1.unify; - te1.unifyWith = te2; + te1.unifyWith = new(te2); local rightward :: Substitution = te2.unify; - te2.unifyWith = te1; + te2.unifyWith = new(te1); return if null(leftward.substErrors) then leftward -- arbitrary choice if both work, but if they are confluent, it's okay diff --git a/grammars/silver/compiler/definition/type/syntax/AspectDcl.sv b/grammars/silver/compiler/definition/type/syntax/AspectDcl.sv index a144019c2..dbf0a0f77 100644 --- a/grammars/silver/compiler/definition/type/syntax/AspectDcl.sv +++ b/grammars/silver/compiler/definition/type/syntax/AspectDcl.sv @@ -9,7 +9,7 @@ flowtype lexicalTypeVariables {realSignature, env, flowEnv, grammarName, determi function addNewLexicalTyVars_ActuallyVariables [Def] ::= gn::String sl::Location lk::[Pair] l::[String] { - return map(\ n::String -> aspectLexTyVarDef(gn, sl, n, freshTyVarNamed(fromMaybe(starKind(), lookup(n, lk)), n)), l); + return map(\ n::String -> aspectLexTyVarDef(gn, sl, n, freshTyVarNamed(n, fromMaybe(starKind(), lookup(n, lk)))), l); } -- This binds variables that appear in the signature to type variables, rather than skolem constants diff --git a/grammars/silver/compiler/definition/type/syntax/Constraint.sv b/grammars/silver/compiler/definition/type/syntax/Constraint.sv index 22acc6fc5..21c0735d4 100644 --- a/grammars/silver/compiler/definition/type/syntax/Constraint.sv +++ b/grammars/silver/compiler/definition/type/syntax/Constraint.sv @@ -115,9 +115,9 @@ top::Constraint ::= 'attribute' at::QName attl::BracketedOptTypeExprs 'occurs' ' then [errFromOrigin(at, at.name ++ " expects " ++ toString(length(atTypeScheme.boundVars)) ++ " type variables, but " ++ toString(length(attl.types)) ++ " were provided.")] - else if map((.kindrep), atTypeScheme.boundVars) != map((.kindrep), attl.types) + else if map((.kind), atTypeScheme.boundVars) != map((.kindrep), attl.types) then [errFromOrigin(at, - at.name ++ " has kind " ++ prettyKind(foldr(arrowKind, starKind(), map((.kindrep), atTypeScheme.boundVars))) ++ + at.name ++ " has kind " ++ prettyKind(foldr(arrowKind, starKind(), map((.kind), atTypeScheme.boundVars))) ++ " but type variable(s) have kind(s) " ++ implode(", ", map(compose(prettyKind, (.kindrep)), attl.types)) ++ ".")] else []; @@ -126,7 +126,7 @@ top::Constraint ::= 'attribute' at::QName attl::BracketedOptTypeExprs 'occurs' ' local atTypeScheme::PolyType = at.lookupAttribute.typeScheme; local rewrite :: Substitution = zipVarsAndTypesIntoSubstitution(atTypeScheme.boundVars, attl.types); production attrTy::Type = - if map((.kindrep), atTypeScheme.boundVars) == map((.kindrep), attl.types) + if map((.kind), atTypeScheme.boundVars) == map((.kindrep), attl.types) then performRenaming(atTypeScheme.typerep, rewrite) else errorType(); @@ -160,9 +160,9 @@ top::Constraint ::= 'attribute' at::QName attl::BracketedOptTypeExprs i::TypeExp then [errFromOrigin(at, at.name ++ " expects " ++ toString(length(atTypeScheme.boundVars)) ++ " type variables, but " ++ toString(length(attl.types)) ++ " were provided.")] - else if map((.kindrep), atTypeScheme.boundVars) != map((.kindrep), attl.types) + else if map((.kind), atTypeScheme.boundVars) != map((.kindrep), attl.types) then [errFromOrigin(at, - at.name ++ " has kind " ++ prettyKind(foldr(arrowKind, starKind(), map((.kindrep), atTypeScheme.boundVars))) ++ + at.name ++ " has kind " ++ prettyKind(foldr(arrowKind, starKind(), map((.kind), atTypeScheme.boundVars))) ++ " but type variable(s) have kind(s) " ++ implode(", ", map(compose(prettyKind, (.kindrep)), attl.types)) ++ ".")] else []; @@ -176,7 +176,7 @@ top::Constraint ::= 'attribute' at::QName attl::BracketedOptTypeExprs i::TypeExp local atTypeScheme::PolyType = at.lookupAttribute.typeScheme; local rewrite :: Substitution = zipVarsAndTypesIntoSubstitution(atTypeScheme.boundVars, attl.types); production attrTy::Type = - if map((.kindrep), atTypeScheme.boundVars) == map((.kindrep), attl.types) + if map((.kind), atTypeScheme.boundVars) == map((.kindrep), attl.types) then performRenaming(atTypeScheme.typerep, rewrite) else errorType(); @@ -216,9 +216,9 @@ top::Constraint ::= 'annotation' at::QName attl::BracketedOptTypeExprs 'occurs' then [errFromOrigin(at, at.name ++ " expects " ++ toString(length(atTypeScheme.boundVars)) ++ " type variables, but " ++ toString(length(attl.types)) ++ " were provided.")] - else if map((.kindrep), atTypeScheme.boundVars) != map((.kindrep), attl.types) + else if map((.kind), atTypeScheme.boundVars) != map((.kindrep), attl.types) then [errFromOrigin(at, - at.name ++ " has kind " ++ prettyKind(foldr(arrowKind, starKind(), map((.kindrep), atTypeScheme.boundVars))) ++ + at.name ++ " has kind " ++ prettyKind(foldr(arrowKind, starKind(), map((.kind), atTypeScheme.boundVars))) ++ " but type variable(s) have kind(s) " ++ implode(", ", map(compose(prettyKind, (.kindrep)), attl.types)) ++ ".")] else []; @@ -227,7 +227,7 @@ top::Constraint ::= 'annotation' at::QName attl::BracketedOptTypeExprs 'occurs' local atTypeScheme::PolyType = at.lookupAttribute.typeScheme; local rewrite :: Substitution = zipVarsAndTypesIntoSubstitution(atTypeScheme.boundVars, attl.types); production attrTy::Type = - if map((.kindrep), atTypeScheme.boundVars) == map((.kindrep), attl.types) + if map((.kind), atTypeScheme.boundVars) == map((.kindrep), attl.types) then performRenaming(atTypeScheme.typerep, rewrite) else errorType(); diff --git a/grammars/silver/compiler/definition/type/syntax/KindExpr.sv b/grammars/silver/compiler/definition/type/syntax/KindExpr.sv index 613d61eac..ce2748195 100644 --- a/grammars/silver/compiler/definition/type/syntax/KindExpr.sv +++ b/grammars/silver/compiler/definition/type/syntax/KindExpr.sv @@ -29,5 +29,5 @@ concrete production parenKindExpr top::KindExpr ::= '(' k::KindExpr ')' { top.unparse = s"(${k.unparse})"; - forwards to k; + forwards to @k; } diff --git a/grammars/silver/compiler/definition/type/syntax/TypeExpr.sv b/grammars/silver/compiler/definition/type/syntax/TypeExpr.sv index 8c4950bb5..8682a87b4 100644 --- a/grammars/silver/compiler/definition/type/syntax/TypeExpr.sv +++ b/grammars/silver/compiler/definition/type/syntax/TypeExpr.sv @@ -71,7 +71,7 @@ function addNewLexicalTyVars [Def] ::= gn::String lk::[Pair] l::[String] { local loc::Location = getParsedOriginLocationOrFallback(ambientOrigin()); - return map(\ n::String -> lexTyVarDef(gn, loc, n, freshTyVarNamed(fromMaybe(starKind(), lookup(n, lk)), n)), l); + return map(\ n::String -> lexTyVarDef(gn, loc, n, freshTyVarNamed(n, fromMaybe(starKind(), lookup(n, lk)))), l); } aspect default production diff --git a/grammars/silver/compiler/driver/Command.sv b/grammars/silver/compiler/driver/Command.sv index 367c8bce8..4a126e5a0 100644 --- a/grammars/silver/compiler/driver/Command.sv +++ b/grammars/silver/compiler/driver/Command.sv @@ -40,73 +40,73 @@ abstract production versionFlag top::CmdArgs ::= rest::CmdArgs { top.displayVersion = true; - forwards to rest; + forwards to @rest; } abstract production cleanFlag top::CmdArgs ::= rest::CmdArgs { top.doClean = true; - forwards to rest; + forwards to @rest; } abstract production warnErrorFlag top::CmdArgs ::= rest::CmdArgs { top.warnError = true; - forwards to rest; + forwards to @rest; } abstract production forceOriginsFlag top::CmdArgs ::= rest::CmdArgs { top.forceOrigins = true; - forwards to rest; + forwards to @rest; } abstract production noOriginsFlag top::CmdArgs ::= rest::CmdArgs { top.noOrigins = true; - forwards to rest; + forwards to @rest; } abstract production tracingOriginsFlag top::CmdArgs ::= rest::CmdArgs { top.tracingOrigins = true; - forwards to rest; + forwards to @rest; } abstract production noRedexFlag top::CmdArgs ::= rest::CmdArgs { top.noRedex = true; - forwards to rest; + forwards to @rest; } abstract production outFlag top::CmdArgs ::= s::String rest::CmdArgs { top.outName = s :: forward.outName; - forwards to rest; + forwards to @rest; } abstract production includeFlag top::CmdArgs ::= s::String rest::CmdArgs { top.searchPath = s :: forward.searchPath; - forwards to rest; + forwards to @rest; } abstract production genFlag top::CmdArgs ::= s::String rest::CmdArgs { top.genLocation = s :: forward.genLocation; - forwards to rest; + forwards to @rest; } abstract production homeFlag top::CmdArgs ::= s::String rest::CmdArgs { top.silverHomeOption = s :: forward.silverHomeOption; - forwards to rest; + forwards to @rest; } abstract production nobindingFlag top::CmdArgs ::= rest::CmdArgs { top.noBindingChecking = true; - forwards to rest; + forwards to @rest; } function parseArgs diff --git a/grammars/silver/compiler/driver/util/BuildEnv.sv b/grammars/silver/compiler/driver/util/BuildEnv.sv index 396f1272b..7c4f5e808 100644 --- a/grammars/silver/compiler/driver/util/BuildEnv.sv +++ b/grammars/silver/compiler/driver/util/BuildEnv.sv @@ -1,15 +1,15 @@ grammar silver:compiler:driver:util; -nonterminal BuildEnv with silverHome, silverGen, grammarPath, silverHostGen, defaultSilverGen, defaultGrammarPath; +data nonterminal BuildEnv with silverHome, silverGen, grammarPath, silverHostGen, defaultSilverGen, defaultGrammarPath; {-- Find jars, standard library -} -synthesized attribute silverHome :: String; +annotation silverHome :: String; {-- Write files, look for already built grammars -} -synthesized attribute silverGen :: String; +annotation silverGen :: String; {-- Search for source files -} -synthesized attribute grammarPath :: [String]; +annotation grammarPath :: [String]; {-- Search for already built grammars. **Always includes silverGen!** -} -synthesized attribute silverHostGen :: [String]; +annotation silverHostGen :: [String]; synthesized attribute defaultSilverGen :: String; synthesized attribute defaultGrammarPath :: String; -- Just the stdlib, so not actually just the default value @@ -21,16 +21,11 @@ synthesized attribute defaultGrammarPath :: String; -- Just the stdlib, so not a - maybe also buildGrammar? -} abstract production buildEnv -top::BuildEnv ::= silverHome::String silverGen::String grammarPath::[String] silverHostGen::[String] +top::BuildEnv ::= { - top.silverHome = silverHome; - top.silverGen = silverGen; - top.grammarPath = grammarPath; - top.silverHostGen = silverHostGen; - -- So that this exists in exactly one location: - top.defaultSilverGen = silverHome ++ "generated/"; - top.defaultGrammarPath = silverHome ++ "grammars/"; + top.defaultSilverGen = top.silverHome ++ "generated/"; + top.defaultGrammarPath = top.silverHome ++ "grammars/"; } -- Takes environment and values from args and determines buildEnv according to correct priorities. @@ -64,7 +59,11 @@ BuildEnv ::= local silverHostGen :: [String] = silverGen :: map(endWithSlash, SILVER_HOST_GEN); - local benv :: BuildEnv = buildEnv(silverHome, silverGen, grammarPath, silverHostGen); + local benv :: BuildEnv = buildEnv( + silverHome=silverHome, + silverGen=silverGen, + grammarPath=grammarPath, + silverHostGen=silverHostGen); return benv; } diff --git a/grammars/silver/compiler/extension/astconstruction/Syntax.sv b/grammars/silver/compiler/extension/astconstruction/Syntax.sv index 24b24786b..7b0e553eb 100644 --- a/grammars/silver/compiler/extension/astconstruction/Syntax.sv +++ b/grammars/silver/compiler/extension/astconstruction/Syntax.sv @@ -31,7 +31,7 @@ top::AST_c ::= '$' '{' e::Expr '}' layout {silver:compiler:definition:core:WhiteSpace} { top.unparse = s"$${${e.unparse}}"; - top.ast = antiquoteAST(e); + top.ast = antiquoteAST(new(e)); top.errors := []; } diff --git a/grammars/silver/compiler/extension/deriving/Derive.sv b/grammars/silver/compiler/extension/deriving/Derive.sv index 7c9803ff8..80fe2dca6 100644 --- a/grammars/silver/compiler/extension/deriving/Derive.sv +++ b/grammars/silver/compiler/extension/deriving/Derive.sv @@ -92,7 +92,7 @@ top::AGDcl ::= nt::Decorated! QName nilConstraint(), filterMap( \ tv::TyVar -> - if tv.kindrep == starKind() + if tv.kind == starKind() then just( classConstraint( qName("silver:core:Eq").qNameType, @@ -207,7 +207,7 @@ top::AGDcl ::= nt::Decorated! QName nilConstraint(), filterMap( \ tv::TyVar -> - if tv.kindrep == starKind() + if tv.kind == starKind() then just( classConstraint( qName("silver:core:Ord").qNameType, diff --git a/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv b/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv index e6bb9a099..548074061 100644 --- a/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv +++ b/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv @@ -26,7 +26,7 @@ function getFreeTypeNames [String] ::= l::[TyVar] { return case l of - | tyVarNamed(_, _, s)::xs -> s :: getFreeTypeNames(xs) + | tyVarNamed(s)::xs -> s :: getFreeTypeNames(xs) | _::xs -> getFreeTypeNames(xs) | [] -> [] end; diff --git a/grammars/silver/compiler/extension/doc/driver/BuildProcess.sv b/grammars/silver/compiler/extension/doc/driver/BuildProcess.sv index cd3e89127..8a9f7cb2c 100644 --- a/grammars/silver/compiler/extension/doc/driver/BuildProcess.sv +++ b/grammars/silver/compiler/extension/doc/driver/BuildProcess.sv @@ -29,7 +29,7 @@ top::CmdArgs ::= rest::CmdArgs { top.docGeneration = true; top.parseDocs = true; - forwards to rest; + forwards to @rest; } abstract production printUndocFlag @@ -37,7 +37,7 @@ top::CmdArgs ::= rest::CmdArgs { top.printUndoc = true; top.parseDocs = true; - forwards to rest; + forwards to @rest; } abstract production countUndocFlag @@ -45,7 +45,7 @@ top::CmdArgs ::= rest::CmdArgs { top.countUndoc = true; top.parseDocs = true; - forwards to rest; + forwards to @rest; } abstract production docOutFlag @@ -55,7 +55,7 @@ top::CmdArgs ::= loc::String rest::CmdArgs | nothing() -> just(loc) | _ -> error("Duplicate arguments for docOutOption") end; - forwards to rest; + forwards to @rest; } aspect function parseArgs diff --git a/grammars/silver/compiler/modification/copper/BuildProcess.sv b/grammars/silver/compiler/modification/copper/BuildProcess.sv index a45ed09fc..7e18b3f12 100644 --- a/grammars/silver/compiler/modification/copper/BuildProcess.sv +++ b/grammars/silver/compiler/modification/copper/BuildProcess.sv @@ -22,7 +22,7 @@ abstract production copperdumpFlag top::CmdArgs ::= rest::CmdArgs { top.forceCopperDump = true; - forwards to rest; + forwards to @rest; } aspect function parseArgs @@ -48,7 +48,7 @@ production copperXmlDumpFlag top::CmdArgs ::= rest::CmdArgs { top.copperXmlDump = true; - forwards to rest; + forwards to @rest; } aspect function parseArgs diff --git a/grammars/silver/compiler/modification/primitivepattern/Types.sv b/grammars/silver/compiler/modification/primitivepattern/Types.sv index 7173d3976..0e42b1fa2 100644 --- a/grammars/silver/compiler/modification/primitivepattern/Types.sv +++ b/grammars/silver/compiler/modification/primitivepattern/Types.sv @@ -76,11 +76,11 @@ top::Type ::= tv::TyVar { top.refine = case top.refineWith of - | varType(j) when j.kindrep == tv.kindrep -> + | varType(j) when j.kind == tv.kind -> if tv == j then emptySubst() else subst(tv, top.refineWith) - | t when t.kindrep == tv.kindrep -> + | t when t.kindrep == tv.kind -> if contains(tv, t.freeVariables) then errorSubst("Infinite type! Tried to refine with " ++ prettyType(t)) else subst(tv, t) @@ -93,11 +93,11 @@ top::Type ::= tv::TyVar { top.refine = case top.refineWith of - | skolemType(j) when j.kindrep == tv.kindrep -> + | skolemType(j) when j.kind == tv.kind -> if tv == j then emptySubst() else subst(tv, top.refineWith) - | t when t.kindrep == tv.kindrep -> + | t when t.kindrep == tv.kind -> if contains(tv, t.freeVariables) then errorSubst("Infinite type! Tried to refine with " ++ prettyType(t)) else subst(tv, t) diff --git a/grammars/silver/compiler/translation/java/core/NamedSignature.sv b/grammars/silver/compiler/translation/java/core/NamedSignature.sv index 3c3d708db..4cfe96307 100644 --- a/grammars/silver/compiler/translation/java/core/NamedSignature.sv +++ b/grammars/silver/compiler/translation/java/core/NamedSignature.sv @@ -396,7 +396,7 @@ String ::= indent::Integer vars::[TyVar] "\n", map( \ tv::TyVar -> - s"${concat(repeat("\t", indent))}common.VarTypeRep freshTypeVar_${toString(tv.extractTyVarRep)} = new common.VarTypeRep();", + s"${concat(repeat("\t", indent))}common.VarTypeRep freshTypeVar_${toString(tv.varId)} = new common.VarTypeRep();", vars)); } diff --git a/grammars/silver/compiler/translation/java/driver/BuildProcess.sv b/grammars/silver/compiler/translation/java/driver/BuildProcess.sv index 84d18af73..11e06ecd0 100644 --- a/grammars/silver/compiler/translation/java/driver/BuildProcess.sv +++ b/grammars/silver/compiler/translation/java/driver/BuildProcess.sv @@ -30,31 +30,31 @@ abstract production dontTranslateFlag top::CmdArgs ::= rest::CmdArgs { top.noJavaGeneration = true; - forwards to rest; + forwards to @rest; } abstract production onejarFlag top::CmdArgs ::= rest::CmdArgs { top.buildSingleJar = true; - forwards to rest; + forwards to @rest; } abstract production relativejarFlag top::CmdArgs ::= rest::CmdArgs { top.relativeJar = true; - forwards to rest; + forwards to @rest; } abstract production includeRTJarFlag top::CmdArgs ::= s::String rest::CmdArgs { top.includeRTJars = s :: forward.includeRTJars; - forwards to rest; + forwards to @rest; } abstract production buildXmlFlag top::CmdArgs ::= s::String rest::CmdArgs { top.buildXmlLocation = s :: forward.buildXmlLocation; - forwards to rest; + forwards to @rest; } aspect function parseArgs diff --git a/grammars/silver/compiler/translation/java/type/Context.sv b/grammars/silver/compiler/translation/java/type/Context.sv index 66ac2dc5f..95d954a6a 100644 --- a/grammars/silver/compiler/translation/java/type/Context.sv +++ b/grammars/silver/compiler/translation/java/type/Context.sv @@ -118,7 +118,7 @@ top::Context ::= t::Type case top.resolved, t of -- We might need translate this context even when resolution fails; -- in that case fall back to a rigid skolem constant. - | [], skolemType(tv) -> s"new common.BaseTypeRep(\"b${toString(tv.extractTyVarRep)}\")" + | [], skolemType(tv) -> s"new common.BaseTypeRep(\"b${toString(tv.varId)}\")" | [], _ -> t.transTypeRep | _, _ -> resolvedDcl.transContext end; diff --git a/grammars/silver/compiler/translation/java/type/Type.sv b/grammars/silver/compiler/translation/java/type/Type.sv index 4ec134ad5..80e79d566 100644 --- a/grammars/silver/compiler/translation/java/type/Type.sv +++ b/grammars/silver/compiler/translation/java/type/Type.sv @@ -22,7 +22,7 @@ synthesized attribute transTypeName :: String; function transFreshTypeRep String ::= t::Type { - t.skolemTypeReps = map(\ tv::TyVar -> (tv, s"freshTypeVar_${toString(tv.extractTyVarRep)}"), t.freeSkolemVars); + t.skolemTypeReps = map(\ tv::TyVar -> (tv, s"freshTypeVar_${toString(tv.varId)}"), t.freeSkolemVars); return t.transTypeRep; } @@ -62,7 +62,7 @@ top::Type ::= tv::TyVar { top.transCovariantType = "? extends Object"; top.transClassType = "Object"; - top.transTypeRep = s"freshTypeVar_${toString(tv.extractTyVarRep)}"; + top.transTypeRep = s"freshTypeVar_${toString(tv.varId)}"; top.transTypeName = "a" ++ toString(positionOf(tv, top.boundVariables)); } diff --git a/language-server/langserver/src/main/java/edu/umn/cs/melt/silver/langserver/SilverCompiler.java b/language-server/langserver/src/main/java/edu/umn/cs/melt/silver/langserver/SilverCompiler.java index 2ed6a4325..f06177b1c 100644 --- a/language-server/langserver/src/main/java/edu/umn/cs/melt/silver/langserver/SilverCompiler.java +++ b/language-server/langserver/src/main/java/edu/umn/cs/melt/silver/langserver/SilverCompiler.java @@ -90,9 +90,9 @@ public void build( // Set up the build environment NBuildEnv benv = new PbuildEnv( - new StringCatter(silverHome), - new StringCatter(silverGen), ConsCellCollection.fromStringList(grammarPath), + new StringCatter(silverGen), + new StringCatter(silverHome), ConsCellCollection.fromStringList(silverHostGen) ); DecoratedNode a = PparseArgsOrError.invoke(OriginContext.FFI_CONTEXT, ConsCellCollection.fromStringList(args)); diff --git a/test/stdlib/cmdargs/TestCmdArgs.sv b/test/stdlib/cmdargs/TestCmdArgs.sv index 8a9aed012..8a264e7b8 100644 --- a/test/stdlib/cmdargs/TestCmdArgs.sv +++ b/test/stdlib/cmdargs/TestCmdArgs.sv @@ -17,19 +17,19 @@ abstract production verboseFlag top::CmdArgs ::= rest::CmdArgs { top.isVerbose = true; - forwards to rest; + forwards to @rest; } abstract production sillyFlag top::CmdArgs ::= rest::CmdArgs { top.isSilly = true; - forwards to rest; + forwards to @rest; } abstract production noSillyFlag top::CmdArgs ::= rest::CmdArgs { top.isSilly = false; - forwards to rest; + forwards to @rest; } @@ -97,7 +97,7 @@ abstract production includeFlag top::CmdArgs ::= p::String rest::CmdArgs { top.includePaths = p :: forward.includePaths; - forwards to rest; + forwards to @rest; } -- Stil don't parse anything unrecognized. From 09571c312daf751aa3753eac67940552677907a7 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 27 Oct 2023 14:01:10 +0200 Subject: [PATCH 083/283] Add missing algebra type class instances, using foreign functions --- grammars/silver/core/BooleanAlgebra.sv | 2 + grammars/silver/core/CommutativeRing.sv | 1 + grammars/silver/core/DivisionRing.sv | 8 ++++ grammars/silver/core/EuclideanRing.sv | 44 ++++++++++++++++++++-- grammars/silver/core/Field.sv | 3 ++ grammars/silver/core/HeytingAlgebra.sv | 33 ++++++++++++++++ grammars/silver/core/Ring.sv | 40 +++++++++++++++++++- grammars/silver/core/Semiring.sv | 50 ++++++++++++++++++++++++- 8 files changed, 175 insertions(+), 6 deletions(-) diff --git a/grammars/silver/core/BooleanAlgebra.sv b/grammars/silver/core/BooleanAlgebra.sv index 509f7b221..235063be8 100644 --- a/grammars/silver/core/BooleanAlgebra.sv +++ b/grammars/silver/core/BooleanAlgebra.sv @@ -10,3 +10,5 @@ grammar silver:core; - * Double Negation Elimination: `not(not(x)) = x` -} class HeytingAlgebra a => BooleanAlgebra a {} + +instance BooleanAlgebra Boolean {} diff --git a/grammars/silver/core/CommutativeRing.sv b/grammars/silver/core/CommutativeRing.sv index e6b8af88f..2aa6dca13 100644 --- a/grammars/silver/core/CommutativeRing.sv +++ b/grammars/silver/core/CommutativeRing.sv @@ -9,3 +9,4 @@ grammar silver:core; class Ring a => CommutativeRing a {} instance CommutativeRing Integer {} +instance CommutativeRing Float {} diff --git a/grammars/silver/core/DivisionRing.sv b/grammars/silver/core/DivisionRing.sv index 9ae4e0f35..515046e20 100644 --- a/grammars/silver/core/DivisionRing.sv +++ b/grammars/silver/core/DivisionRing.sv @@ -14,6 +14,14 @@ class Ring a => DivisionRing a { recip :: (a ::= a); } +instance DivisionRing Integer { + recip = \ a -> 1/a; +} + +instance DivisionRing Float { + recip = \ a -> 1.0 / a; +} + @{- Division implemented as `(1/r) * l`. - - Iff the type is a commutative ring, this is equivalent to `rightDiv`. diff --git a/grammars/silver/core/EuclideanRing.sv b/grammars/silver/core/EuclideanRing.sv index c508fb4e9..76ed387df 100644 --- a/grammars/silver/core/EuclideanRing.sv +++ b/grammars/silver/core/EuclideanRing.sv @@ -19,9 +19,47 @@ class CommutativeRing a => EuclideanRing a { } instance EuclideanRing Integer { - degree = \n::Integer -> if n < 0 then -n else n; - div = \a::Integer b::Integer -> a / b; - mod = \a::Integer b::Integer -> a % b; + degree = \n -> if n < 0 then -n else n; + div = divInteger; + mod = modInteger; +} + +function divInteger +Integer ::= a::Integer b::Integer +{ + return error("Foreign function"); +} foreign { + "java": return "(%a% / (int)%b%)"; +} + +function modInteger +Integer ::= a::Integer b::Integer +{ + return error("Foreign function"); +} foreign { + "java": return "(%a% % (int)%b%)"; +} + +instance EuclideanRing Float { + degree = \n -> if n < 0.0 then toInteger(-n) else toInteger(n); + div = divFloat; + mod = modFloat; +} + +function divFloat +Float ::= a::Float b::Float +{ + return error("Foreign function"); +} foreign { + "java": return "(%a% / (float)%b%)"; +} + +function modFloat +Float ::= a::Float b::Float +{ + return error("Foreign function"); +} foreign { + "java": return "(%a% % (float)%b%)"; } @{- Computes the greatest common divisor of two numbers. -} diff --git a/grammars/silver/core/Field.sv b/grammars/silver/core/Field.sv index 10e54576a..ce1dfe2d4 100644 --- a/grammars/silver/core/Field.sv +++ b/grammars/silver/core/Field.sv @@ -12,3 +12,6 @@ grammar silver:core; - * Non-Zero Multiplicative Inverse: `mod(a, b) = zero` -} class DivisionRing a, EuclideanRing a => Field a {} + +instance Field Integer {} +instance Field Float {} \ No newline at end of file diff --git a/grammars/silver/core/HeytingAlgebra.sv b/grammars/silver/core/HeytingAlgebra.sv index eee0b4a9b..72a1c768b 100644 --- a/grammars/silver/core/HeytingAlgebra.sv +++ b/grammars/silver/core/HeytingAlgebra.sv @@ -52,3 +52,36 @@ class HeytingAlgebra a { -} not :: (a ::= a); } + +instance HeytingAlgebra Boolean { + ff = false; + tt = true; + implies = \ p q -> disj(not(p), q); + conj = conjBoolean; + disj = disjBoolean; + not = notBoolean; +} + +function conjBoolean +Boolean ::= a::Boolean b::Boolean +{ + return error("Foreign function"); +} foreign { + "java": return "(%a% && (boolean)%b%)"; +} + +function disjBoolean +Boolean ::= a::Boolean b::Boolean +{ + return error("Foreign function"); +} foreign { + "java": return "(%a% || (boolean)%b%)"; +} + +function notBoolean +Boolean ::= a::Boolean +{ + return error("Foreign function"); +} foreign { + "java": return "(!(boolean)%a%)"; +} diff --git a/grammars/silver/core/Ring.sv b/grammars/silver/core/Ring.sv index a29923919..f878d0a18 100644 --- a/grammars/silver/core/Ring.sv +++ b/grammars/silver/core/Ring.sv @@ -17,7 +17,45 @@ class Semiring a => Ring a { } instance Ring Integer { - sub = \a::Integer b::Integer -> a - b; + sub = subInteger; + negate = negateInteger; +} + +function subInteger +Integer ::= a::Integer b::Integer +{ + return error("Foreign function"); +} foreign { + "java": return "(%a% - (int)%b%)"; +} + +function negateInteger +Integer ::= a::Integer +{ + return error("Foreign function"); +} foreign { + "java": return "(-(int)%a%)"; +} + +instance Ring Float { + sub = subFloat; + negate = negateFloat; +} + +function subFloat +Float ::= a::Float b::Float +{ + return error("Foreign function"); +} foreign { + "java": return "(%a% - (float)%b%)"; +} + +function negateFloat +Float ::= a::Float +{ + return error("Foreign function"); +} foreign { + "java": return "(-(float)%a%)"; } @{- Converts an integer into an arbitrary ring. -} diff --git a/grammars/silver/core/Semiring.sv b/grammars/silver/core/Semiring.sv index 0e938c637..2b5bcaefe 100644 --- a/grammars/silver/core/Semiring.sv +++ b/grammars/silver/core/Semiring.sv @@ -31,12 +31,58 @@ class Semiring a { } instance Semiring Integer { - add = \a::Integer b::Integer -> a + b; + add = addInteger; zero = 0; - mul = \a::Integer b::Integer -> a * b; + mul = mulInteger; one = 1; } +function addInteger +Integer ::= a::Integer b::Integer +{ + return error("Foreign function"); +} foreign { + "java": return "(%a% + (int)%b%)"; +} + +function mulInteger +Integer ::= a::Integer b::Integer +{ + return error("Foreign function"); +} foreign { + "java": return "(%a% * (int)%b%)"; +} + +instance Semiring Float { + add = addFloat; + zero = 0.0; + mul = mulFloat; + one = 1.0; +} + +function addFloat +Float ::= a::Float b::Float +{ + return error("Foreign function"); +} foreign { + "java": return "(%a% + (float)%b%)"; +} + +function mulFloat +Float ::= a::Float b::Float +{ + return error("Foreign function"); +} foreign { + "java": return "(%a% * (float)%b%)"; +} + +instance Semiring Boolean { + add = disj; + zero = false; + mul = conj; + one = true; +} + @{- Converts a non-negative integer into an arbitrary semiring. -} function fromNonnegativeInteger Semiring a => a ::= n::Integer From dd0ea55eb7fe622c3d8a29ddfd761457fee7239d Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 27 Oct 2023 16:28:16 +0200 Subject: [PATCH 084/283] FIx bug with location of terminals in metatranslated ASTs --- .../compiler/metatranslation/Translation.sv | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/grammars/silver/compiler/metatranslation/Translation.sv b/grammars/silver/compiler/metatranslation/Translation.sv index 00814a727..471618a8b 100644 --- a/grammars/silver/compiler/metatranslation/Translation.sv +++ b/grammars/silver/compiler/metatranslation/Translation.sv @@ -182,15 +182,12 @@ top::AST ::= terminalName::String lexeme::String location::Location local locationAST::AST = reflect(location); locationAST.givenLocation = top.givenLocation; - top.translation = - terminalConstructor( - 'terminal', '(', - nominalTypeExpr(makeQNameType(terminalName, top.givenLocation)), - ',', - stringConst(terminal(String_t, s"\"${escapeString(lexeme)}\"", top.givenLocation)), - ',', - locationAST.translation, - ')'); + top.translation = Silver_Expr { + terminal( + $TypeExpr{nominalTypeExpr(makeQNameType(terminalName, top.givenLocation))}, + $Expr{stringConst(terminal(String_t, s"\"${escapeString(lexeme)}\"", top.givenLocation))}, + silver:core:fromMaybe($Expr{locationAST.translation}, silver:core:getParsedOriginLocation(silver:core:ambientOrigin()))) + }; -- TODO: What to do here- warn about this maybe? -- Shouldn't really be an issue unless matching against concrete syntax containing non-fixed terminals From 9254830054c4f00f7a80a12ecb0da1b6bf88bbf0 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 27 Oct 2023 16:41:23 +0200 Subject: [PATCH 085/283] Add comments --- grammars/silver/compiler/metatranslation/Translation.sv | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/grammars/silver/compiler/metatranslation/Translation.sv b/grammars/silver/compiler/metatranslation/Translation.sv index 471618a8b..7dfff33d4 100644 --- a/grammars/silver/compiler/metatranslation/Translation.sv +++ b/grammars/silver/compiler/metatranslation/Translation.sv @@ -184,8 +184,12 @@ top::AST ::= terminalName::String lexeme::String location::Location top.translation = Silver_Expr { terminal( + -- The type expression from the name of the terminal $TypeExpr{nominalTypeExpr(makeQNameType(terminalName, top.givenLocation))}, + -- The quoted lexeme $Expr{stringConst(terminal(String_t, s"\"${escapeString(lexeme)}\"", top.givenLocation))}, + -- Try to get the location dynamically from the parsed origin location if tracking is available, + -- or else fall back to the compile-time AST location. silver:core:fromMaybe($Expr{locationAST.translation}, silver:core:getParsedOriginLocation(silver:core:ambientOrigin()))) }; From a4898f4299b0ac3302d8e6fc6c5f03f76385cfab Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Sun, 29 Oct 2023 17:33:26 -0500 Subject: [PATCH 086/283] Change remaining operators to forward to algebra type class method calls --- .../analysis/typechecking/core/Expr.sv | 158 +--- .../silver/compiler/definition/core/Expr.sv | 57 +- .../compiler/definition/flow/env/Expr.sv | 70 -- .../extension/doc/driver/BuildProcess.sv | 2 +- .../extension/implicit_monads/Expr.sv | 682 ------------------ .../compiler/extension/rewriting/Expr.sv | 54 -- .../compiler/translation/java/core/Expr.sv | 10 +- 7 files changed, 24 insertions(+), 1009 deletions(-) diff --git a/grammars/silver/compiler/analysis/typechecking/core/Expr.sv b/grammars/silver/compiler/analysis/typechecking/core/Expr.sv index c72217f52..0d2ab5545 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/Expr.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/Expr.sv @@ -7,8 +7,7 @@ attribute upSubst, downSubst, finalSubst occurs on Expr, ExprInhs, ExprInh, Expr propagate upSubst, downSubst on Expr, ExprInhs, ExprInh, Exprs, AppExprs, AppExpr, AnnoExpr, AnnoAppExprs excluding - undecoratedAccessHandler, forwardAccess, decoratedAccessHandler, - and, or, notOp, ifThenElse, plus, minus, multiply, divide, modulus, + undecoratedAccessHandler, forwardAccess, decoratedAccessHandler, ifThenElse, decorateExprWith, exprInh, presentAppExpr, decorationSiteExpr, terminalConstructor, noteAttachment; propagate finalSubst on Expr, ExprInhs, ExprInh, Exprs, AppExprs, AppExpr, AnnoExpr, AnnoAppExprs; @@ -155,60 +154,6 @@ top::Expr ::= 'attachNote' note::Expr 'on' e::Expr 'end' else []; } -aspect production and -top::Expr ::= e1::Expr '&&' e2::Expr -{ - local attribute errCheck1 :: TypeCheck; errCheck1.finalSubst = top.finalSubst; - local attribute errCheck2 :: TypeCheck; errCheck2.finalSubst = top.finalSubst; - - thread downSubst, upSubst on top, e1, e2, errCheck1, errCheck2, top; - - errCheck1 = check(e1.typerep, boolType()); - errCheck2 = check(e2.typerep, boolType()); - top.errors <- - if errCheck1.typeerror - then [errFromOrigin(e1, "First operand to && must be type bool. Got instead type " ++ errCheck1.leftpp)] - else []; - top.errors <- - if errCheck2.typeerror - then [errFromOrigin(e2, "First operand to && must be type bool. Got instead type " ++ errCheck2.leftpp)] - else []; -} - -aspect production or -top::Expr ::= e1::Expr '||' e2::Expr -{ - local attribute errCheck1 :: TypeCheck; errCheck1.finalSubst = top.finalSubst; - local attribute errCheck2 :: TypeCheck; errCheck2.finalSubst = top.finalSubst; - - thread downSubst, upSubst on top, e1, e2, errCheck1, errCheck2, top; - - errCheck1 = check(e1.typerep, boolType()); - errCheck2 = check(e2.typerep, boolType()); - top.errors <- - if errCheck1.typeerror - then [errFromOrigin(e1, "First operand to || must be type bool. Got instead type " ++ errCheck1.leftpp)] - else []; - top.errors <- - if errCheck2.typeerror - then [errFromOrigin(e2, "First operand to || must be type bool. Got instead type " ++ errCheck2.leftpp)] - else []; -} - -aspect production notOp -top::Expr ::= '!' e1::Expr -{ - local attribute errCheck1 :: TypeCheck; errCheck1.finalSubst = top.finalSubst; - - thread downSubst, upSubst on top, e1, errCheck1, top; - - errCheck1 = check(e1.typerep, boolType()); - top.errors <- - if errCheck1.typeerror - then [errFromOrigin(e1, "Operand to ! must be type bool. Got instead type " ++ errCheck1.leftpp)] - else []; -} - aspect production ifThenElse top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'else' e3::Expr { @@ -229,107 +174,6 @@ top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'else' e3::Expr else []; } -aspect production plus -top::Expr ::= e1::Expr '+' e2::Expr -{ - local attribute errCheck1 :: TypeCheck; errCheck1.finalSubst = top.finalSubst; - - thread downSubst, upSubst on top, e1, e2, errCheck1, top; - - errCheck1 = check(e1.typerep, e2.typerep); - top.errors <- - if errCheck1.typeerror - then [errFromOrigin(top, "Operands to + must be the same type. Instead they are " ++ errCheck1.leftpp ++ " and " ++ errCheck1.rightpp)] - else []; - - top.errors <- - if e1.finalType.instanceNum - then [] - else [errFromOrigin(top, "Operands to + must be concrete types Integer or Float. Instead they are of type " ++ prettyType(e1.finalType))]; -} - -aspect production minus -top::Expr ::= e1::Expr '-' e2::Expr -{ - local attribute errCheck1 :: TypeCheck; errCheck1.finalSubst = top.finalSubst; - - thread downSubst, upSubst on top, e1, e2, errCheck1, top; - - errCheck1 = check(e1.typerep, e2.typerep); - top.errors <- - if errCheck1.typeerror - then [errFromOrigin(top, "Operands to - must be the same type. Instead they are " ++ errCheck1.leftpp ++ " and " ++ errCheck1.rightpp)] - else []; - - top.errors <- - if e1.finalType.instanceNum - then [] - else [errFromOrigin(top, "Operands to - must be concrete types Integer or Float. Instead they are of type " ++ prettyType(e1.finalType))]; -} -aspect production multiply -top::Expr ::= e1::Expr '*' e2::Expr -{ - local attribute errCheck1 :: TypeCheck; errCheck1.finalSubst = top.finalSubst; - - thread downSubst, upSubst on top, e1, e2, errCheck1, top; - - errCheck1 = check(e1.typerep, e2.typerep); - top.errors <- - if errCheck1.typeerror - then [errFromOrigin(top, "Operands to * must be the same type. Instead they are " ++ errCheck1.leftpp ++ " and " ++ errCheck1.rightpp)] - else []; - - top.errors <- - if e1.finalType.instanceNum - then [] - else [errFromOrigin(top, "Operands to * must be concrete types Integer or Float. Instead they are of type " ++ prettyType(e1.finalType))]; -} -aspect production divide -top::Expr ::= e1::Expr '/' e2::Expr -{ - local attribute errCheck1 :: TypeCheck; errCheck1.finalSubst = top.finalSubst; - - thread downSubst, upSubst on top, e1, e2, errCheck1, top; - - errCheck1 = check(e1.typerep, e2.typerep); - top.errors <- - if errCheck1.typeerror - then [errFromOrigin(top, "Operands to / must be the same type. Instead they are " ++ errCheck1.leftpp ++ " and " ++ errCheck1.rightpp)] - else []; - - top.errors <- - if e1.finalType.instanceNum - then [] - else [errFromOrigin(top, "Operands to / must be concrete types Integer or Float. Instead they are of type " ++ prettyType(e1.finalType))]; -} -aspect production modulus -top::Expr ::= e1::Expr '%' e2::Expr -{ - local attribute errCheck1 :: TypeCheck; errCheck1.finalSubst = top.finalSubst; - - thread downSubst, upSubst on top, e1, e2, errCheck1, top; - - errCheck1 = check(e1.typerep, e2.typerep); - top.errors <- - if errCheck1.typeerror - then [errFromOrigin(top, "Operands to % must be the same type. Instead they are " ++ errCheck1.leftpp ++ " and " ++ errCheck1.rightpp)] - else []; - - top.errors <- - if e1.finalType.instanceNum - then [] - else [errFromOrigin(top, "Operands to % must be concrete types Integer or Float. Instead they are of type " ++ prettyType(e1.finalType))]; -} -aspect production neg -top::Expr ::= '-' e1::Expr -{ - - top.errors <- - if e1.finalType.instanceNum - then [] - else [errFromOrigin(top, "Operand to unary - must be concrete types Integer or Float. Instead it is of type " ++ prettyType(e1.finalType))]; -} - aspect production terminalConstructor top::Expr ::= 'terminal' '(' t::TypeExpr ',' es::Expr ',' el::Expr ')' { diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index 88792873e..cb22e6a47 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -714,10 +714,7 @@ top::Expr ::= e1::Expr '&&' e2::Expr { top.unparse = e1.unparse ++ " && " ++ e2.unparse; - top.typerep = boolType(); - - e1.isRoot = false; - e2.isRoot = false; + forwards to Silver_Expr { silver:core:conj($Expr{@e1}, $Expr{@e2}) }; } concrete production or @@ -725,10 +722,7 @@ top::Expr ::= e1::Expr '||' e2::Expr { top.unparse = e1.unparse ++ " || " ++ e2.unparse; - top.typerep = boolType(); - - e1.isRoot = false; - e2.isRoot = false; + forwards to Silver_Expr { silver:core:disj($Expr{@e1}, $Expr{@e2}) }; } concrete production notOp @@ -736,9 +730,7 @@ top::Expr ::= '!' e::Expr { top.unparse = "! " ++ e.unparse; - top.typerep = boolType(); - - e.isRoot = false; + forwards to Silver_Expr { silver:core:not($Expr{@e}) }; } concrete production gtOp @@ -746,7 +738,7 @@ top::Expr ::= e1::Expr op::'>' e2::Expr { top.unparse = e1.unparse ++ " > " ++ e2.unparse; - forwards to Silver_Expr { silver:core:gt($Expr{e1}, $Expr{e2}) }; + forwards to Silver_Expr { silver:core:gt($Expr{@e1}, $Expr{@e2}) }; } concrete production ltOp @@ -754,7 +746,7 @@ top::Expr ::= e1::Expr op::'<' e2::Expr { top.unparse = e1.unparse ++ " < " ++ e2.unparse; - forwards to Silver_Expr { silver:core:lt($Expr{e1}, $Expr{e2}) }; + forwards to Silver_Expr { silver:core:lt($Expr{@e1}, $Expr{@e2}) }; } concrete production gteOp @@ -762,7 +754,7 @@ top::Expr ::= e1::Expr op::'>=' e2::Expr { top.unparse = e1.unparse ++ " >= " ++ e2.unparse; - forwards to Silver_Expr { silver:core:gte($Expr{e1}, $Expr{e2}) }; + forwards to Silver_Expr { silver:core:gte($Expr{@e1}, $Expr{@e2}) }; } concrete production lteOp @@ -770,7 +762,7 @@ top::Expr ::= e1::Expr op::'<=' e2::Expr { top.unparse = e1.unparse ++ " <= " ++ e2.unparse; - forwards to Silver_Expr { silver:core:lte($Expr{e1}, $Expr{e2}) }; + forwards to Silver_Expr { silver:core:lte($Expr{@e1}, $Expr{@e2}) }; } concrete production eqOp @@ -778,7 +770,7 @@ top::Expr ::= e1::Expr op::'==' e2::Expr { top.unparse = e1.unparse ++ " == " ++ e2.unparse; - forwards to Silver_Expr { silver:core:eq($Expr{e1}, $Expr{e2}) }; + forwards to Silver_Expr { silver:core:eq($Expr{@e1}, $Expr{@e2}) }; } concrete production neqOp @@ -786,7 +778,7 @@ top::Expr ::= e1::Expr op::'!=' e2::Expr { top.unparse = e1.unparse ++ " != " ++ e2.unparse; - forwards to Silver_Expr { silver:core:neq($Expr{e1}, $Expr{e2}) }; + forwards to Silver_Expr { silver:core:neq($Expr{@e1}, $Expr{@e2}) }; } concrete production ifThenElse @@ -823,10 +815,7 @@ top::Expr ::= e1::Expr '+' e2::Expr { top.unparse = e1.unparse ++ " + " ++ e2.unparse; - top.typerep = e1.typerep; - - e1.isRoot=false; - e2.isRoot=false; + forwards to Silver_Expr { silver:core:add($Expr{@e1}, $Expr{@e2}) }; } concrete production minus @@ -834,10 +823,7 @@ top::Expr ::= e1::Expr '-' e2::Expr { top.unparse = e1.unparse ++ " - " ++ e2.unparse; - top.typerep = e1.typerep; - - e1.isRoot=false; - e2.isRoot=false; + forwards to Silver_Expr { silver:core:sub($Expr{@e1}, $Expr{@e2}) }; } concrete production multiply @@ -845,10 +831,7 @@ top::Expr ::= e1::Expr '*' e2::Expr { top.unparse = e1.unparse ++ " * " ++ e2.unparse; - top.typerep = e1.typerep; - - e1.isRoot=false; - e2.isRoot=false; + forwards to Silver_Expr { silver:core:mul($Expr{@e1}, $Expr{@e2}) }; } concrete production divide @@ -856,10 +839,7 @@ top::Expr ::= e1::Expr '/' e2::Expr { top.unparse = e1.unparse ++ " / " ++ e2.unparse; - top.typerep = e1.typerep; - - e1.isRoot=false; - e2.isRoot=false; + forwards to Silver_Expr { silver:core:div($Expr{@e1}, $Expr{@e2}) }; } concrete production modulus @@ -867,10 +847,7 @@ top::Expr ::= e1::Expr '%' e2::Expr { top.unparse = e1.unparse ++ " % " ++ e2.unparse; - top.typerep = e1.typerep; - - e1.isRoot=false; - e2.isRoot=false; + forwards to Silver_Expr { silver:core:mod($Expr{@e1}, $Expr{@e2}) }; } concrete production neg @@ -879,9 +856,7 @@ precedence = 13 { top.unparse = "- " ++ e.unparse; - top.typerep = e.typerep; - - e.isRoot=false; + forwards to Silver_Expr { silver:core:negate($Expr{@e}) }; } concrete production stringConst @@ -897,7 +872,7 @@ top::Expr ::= e1::Expr op::'++' e2::Expr { top.unparse = e1.unparse ++ " ++ " ++ e2.unparse; - forwards to Silver_Expr { silver:core:append($Expr{e1}, $Expr{e2}) }; + forwards to Silver_Expr { silver:core:append($Expr{@e1}, $Expr{@e2}) }; } concrete production terminalConstructor diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index 373b807c6..e09c2ad76 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -438,29 +438,6 @@ top::Expr ::= '@' e::Expr e.alwaysDecorated = top.alwaysDecorated; } -aspect production and -top::Expr ::= e1::Expr '&&' e2::Expr -{ - e1.decSiteVertexInfo = nothing(); - e2.decSiteVertexInfo = nothing(); - e1.alwaysDecorated = false; - e2.alwaysDecorated = false; -} -aspect production or -top::Expr ::= e1::Expr '||' e2::Expr -{ - e1.decSiteVertexInfo = nothing(); - e2.decSiteVertexInfo = nothing(); - e1.alwaysDecorated = false; - e2.alwaysDecorated = false; -} -aspect production notOp -top::Expr ::= '!' e::Expr -{ - e.decSiteVertexInfo = nothing(); - e.alwaysDecorated = false; -} - aspect production ifThenElse top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'else' e3::Expr { @@ -472,53 +449,6 @@ top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'else' e3::Expr e3.alwaysDecorated = false; } -aspect production plus -top::Expr ::= e1::Expr '+' e2::Expr -{ - e1.decSiteVertexInfo = nothing(); - e2.decSiteVertexInfo = nothing(); - e1.alwaysDecorated = false; - e2.alwaysDecorated = false; -} -aspect production minus -top::Expr ::= e1::Expr '-' e2::Expr -{ - e1.decSiteVertexInfo = nothing(); - e2.decSiteVertexInfo = nothing(); - e1.alwaysDecorated = false; - e2.alwaysDecorated = false; -} -aspect production multiply -top::Expr ::= e1::Expr '*' e2::Expr -{ - e1.decSiteVertexInfo = nothing(); - e2.decSiteVertexInfo = nothing(); - e1.alwaysDecorated = false; - e2.alwaysDecorated = false; -} -aspect production divide -top::Expr ::= e1::Expr _ e2::Expr -{ - e1.decSiteVertexInfo = nothing(); - e2.decSiteVertexInfo = nothing(); - e1.alwaysDecorated = false; - e2.alwaysDecorated = false; -} -aspect production modulus -top::Expr ::= e1::Expr '%' e2::Expr -{ - e1.decSiteVertexInfo = nothing(); - e2.decSiteVertexInfo = nothing(); - e1.alwaysDecorated = false; - e2.alwaysDecorated = false; -} -aspect production neg -top::Expr ::= '-' e::Expr -{ - e.decSiteVertexInfo = nothing(); - e.alwaysDecorated = false; -} - aspect production terminalConstructor top::Expr ::= 'terminal' '(' t::TypeExpr ',' es::Expr ',' el::Expr ')' { diff --git a/grammars/silver/compiler/extension/doc/driver/BuildProcess.sv b/grammars/silver/compiler/extension/doc/driver/BuildProcess.sv index cd3e89127..e656ad596 100644 --- a/grammars/silver/compiler/extension/doc/driver/BuildProcess.sv +++ b/grammars/silver/compiler/extension/doc/driver/BuildProcess.sv @@ -95,7 +95,7 @@ top::DriverAction ::= a::Decorated CmdArgs specs::[Decorated RootSpec] | grammarRootSpec(g, _, _, _, _, _) -> if (length(g.documentedNamed)+length(g.undocumentedNamed))!=0 then [s" - [${g.grammarName}]: ${toString(length(g.documentedNamed))}" ++ - s"/${toString(toInteger(length(g.undocumentedNamed)+length(g.documentedNamed)))} " ++ + s"/${toString(length(g.undocumentedNamed)+length(g.documentedNamed))} " ++ s"(${toString((toFloat(length(g.documentedNamed))/toFloat(length(g.undocumentedNamed)+length(g.documentedNamed)))*toFloat(100))}%) items documented" ++ (if a.printUndoc && (length(g.undocumentedNamed)!=0) then ", missing: " ++ implode(", ", g.undocumentedNamed) diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index 4d2fa1b57..b737dfe9e 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -1254,211 +1254,6 @@ top::Expr ::= 'false' top.monadRewritten = falseConst('false'); } -aspect production and -top::Expr ::= e1::Expr '&&' e2::Expr -{ - top.merrors := e1.merrors ++ e2.merrors; - top.merrors <- - if isMonad(e1.mtyperep, top.env) - then if monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then [] - else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ - " implicitly in this '&&', not " ++ monadToString(e1.mtyperep))] - else []; - top.merrors <- - if isMonad(e2.mtyperep, top.env) - then if monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then [] - else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ - " implicitly in this '&&', not " ++ monadToString(e2.mtyperep))] - else []; - - local ec1::TypeCheck = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then check(monadInnerType(e1.mtyperep), boolType()) - else check(e1.mtyperep, boolType()); - local ec2::TypeCheck = if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then check(monadInnerType(e2.mtyperep), boolType()) - else check(e2.mtyperep, boolType()); - ec1.finalSubst = top.finalSubst; - ec2.finalSubst = top.finalSubst; - e1.mDownSubst = top.mDownSubst; - e2.mDownSubst = e1.mUpSubst; - ec1.downSubst = e2.mUpSubst; - ec2.downSubst = ec1.upSubst; - top.mUpSubst = ec2.upSubst; - top.mtyperep = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then e1.mtyperep --assume it will be well-typed - else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then e2.mtyperep - else boolType(); - - e1.monadicallyUsed = isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst; - e2.monadicallyUsed = isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst; - top.monadicNames = e1.monadicNames ++ e2.monadicNames; - - local e1UnDec::Expr = - if e1.mtyperep.isDecorated - then Silver_Expr {silver:core:new( $Expr {e1.monadRewritten})} - else e1.monadRewritten; - local e2UnDec::Expr = - if e2.mtyperep.isDecorated - then Silver_Expr {silver:core:new( $Expr {e2.monadRewritten})} - else e2.monadRewritten; - --e1 >>= ( (\x y -> if x then y else Return(false))(_, e2) ) - local bindBoth::Expr = - Silver_Expr { - $Expr {monadBind()} - ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - if x then y else $Expr {monadReturn()}(false)) (_, $Expr {e2UnDec})) - }; - --e1 >>= ( (\x y -> Return(x && y))(_, e2) ) - local bind1::Expr = - Silver_Expr { - $Expr {monadBind()} - ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep))} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadReturn()} - (x && y))(_, $Expr {e2UnDec})) - }; - --if e1 then e2 else Return(false) - local bind2::Expr = - Silver_Expr { - if $Expr {e1UnDec} then $Expr {e2UnDec} else $Expr {monadReturn()}(false) - }; - top.monadRewritten = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then bindBoth - else bind1 - else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then bind2 - else and(e1.monadRewritten, '&&', e2.monadRewritten); -} - -aspect production or -top::Expr ::= e1::Expr '||' e2::Expr -{ - top.merrors := e1.merrors ++ e2.merrors; - top.merrors <- - if isMonad(e1.mtyperep, top.env) - then if monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then [] - else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ - " implicitly in this '||', not " ++ monadToString(e1.mtyperep))] - else []; - top.merrors <- - if isMonad(e2.mtyperep, top.env) - then if monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then [] - else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ - " implicitly in this '||', not " ++ monadToString(e2.mtyperep))] - else []; - - local ec1::TypeCheck = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then check(monadInnerType(e1.mtyperep), boolType()) - else check(e1.mtyperep, boolType()); - local ec2::TypeCheck = if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then check(monadInnerType(e2.mtyperep), boolType()) - else check(e2.mtyperep, boolType()); - ec1.finalSubst = top.finalSubst; - ec2.finalSubst = top.finalSubst; - e1.mDownSubst = top.mDownSubst; - e2.mDownSubst = e1.mUpSubst; - ec1.downSubst = e2.mUpSubst; - ec2.downSubst = ec1.upSubst; - top.mUpSubst = ec2.upSubst; - top.mtyperep = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then e1.mtyperep --assume it will be well-typed - else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then e2.mtyperep - else boolType(); - - e1.monadicallyUsed = isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst; - e2.monadicallyUsed = isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst; - top.monadicNames = e1.monadicNames ++ e2.monadicNames; - - local e1UnDec::Expr = - if e1.mtyperep.isDecorated - then Silver_Expr {silver:core:new( $Expr {e1.monadRewritten})} - else e1.monadRewritten; - local e2UnDec::Expr = - if e2.mtyperep.isDecorated - then Silver_Expr {silver:core:new( $Expr {e2.monadRewritten})} - else e2.monadRewritten; - --e1 >>= ( (\x y -> if x then Return(true) else y)(_, e2) ) - local bindBoth::Expr = - Silver_Expr { - $Expr {monadBind()} - ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - if x then $Expr {monadReturn()}(true) else y) (_, $Expr {e2UnDec})) - }; - --e1 >>= ( (\x y -> Return(x || y))(_, e2) ) - local bind1::Expr = - Silver_Expr { - $Expr {monadBind()} - ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep))} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadReturn()} - (x || y))(_, $Expr {e2UnDec})) - }; - --if e1 then Return(true) else e2 - local bind2::Expr = - Silver_Expr { - if $Expr {e1UnDec} then $Expr {monadReturn()}(true) else $Expr {e2UnDec} - }; - top.monadRewritten = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then bindBoth - else bind1 - else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then bind2 - else or(e1.monadRewritten, '||', e2.monadRewritten); -} - -aspect production notOp -top::Expr ::= '!' e::Expr -{ - top.merrors := e.merrors; - top.merrors <- - if isMonad(e.mtyperep, top.env) && monadsMatch(top.expectedMonad, e.mtyperep, top.mDownSubst).fst - then if monadsMatch(top.expectedMonad, e.mtyperep, top.mDownSubst).fst - then [] - else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ - " implicitly in this '!', not " ++ monadToString(e.mtyperep))] - else []; - - local ec::TypeCheck = if isMonad(e.mtyperep, top.env) - then check(monadInnerType(e.mtyperep), boolType()) - else check(e.mtyperep, boolType()); - e.mDownSubst = top.mDownSubst; - ec.downSubst = e.mUpSubst; - top.mUpSubst = ec.upSubst; - ec.finalSubst = top.finalSubst; - top.mtyperep = e.mtyperep; --assume it will be well-typed - - e.monadicallyUsed = isMonad(e.mtyperep, top.env) && monadsMatch(top.expectedMonad, e.mtyperep, top.mDownSubst).fst; - top.monadicNames = e.monadicNames; - - local eUnDec::Expr = - if e.mtyperep.isDecorated - then Silver_Expr {silver:core:new($Expr {e.monadRewritten})} - else e.monadRewritten; - top.monadRewritten = - if isMonad(e.mtyperep, top.env) && monadsMatch(top.expectedMonad, e.mtyperep, top.mDownSubst).fst - then Silver_Expr { - $Expr {monadBind()} - ($Expr {eUnDec}, - \x::Boolean -> - $Expr {monadReturn()}(!x)) - } - else notOp('!', e.monadRewritten); -} - concrete production ifThen top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'end' --this is easier than anything else to do { @@ -1628,483 +1423,6 @@ top::Expr ::= f::Float_t top.monadRewritten = floatConst(f); } -aspect production plus -top::Expr ::= e1::Expr '+' e2::Expr -{ - top.merrors := e1.merrors ++ e2.merrors; - top.merrors <- - if isMonad(e1.mtyperep, top.env) - then if monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then [] - else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ - " implicitly in this '+', not " ++ monadToString(e1.mtyperep))] - else []; - top.merrors <- - if isMonad(e2.mtyperep, top.env) - then if monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then [] - else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ - " implicitly in this '+', not " ++ monadToString(e2.mtyperep))] - else []; - - e1.mDownSubst = top.mDownSubst; - e2.mDownSubst = e1.mUpSubst; - ec.downSubst = e2.mUpSubst; - top.mUpSubst = ec.upSubst; - - local ec::TypeCheck = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then check(e1.mtyperep, e2.mtyperep) - else check(monadInnerType(e1.mtyperep), e2.mtyperep) - else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then check(e1.mtyperep, monadInnerType(e2.mtyperep)) - else check(e1.mtyperep, e2.mtyperep); - ec.finalSubst = top.mUpSubst; - top.mtyperep = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then e1.mtyperep - else e2.mtyperep; - - e1.monadicallyUsed = isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst; - e2.monadicallyUsed = isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst; - top.monadicNames = e1.monadicNames ++ e2.monadicNames; - - local e1UnDec::Expr = - if e1.mtyperep.isDecorated - then Silver_Expr {silver:core:new( $Expr {e1.monadRewritten})} - else e1.monadRewritten; - local e2UnDec::Expr = - if e2.mtyperep.isDecorated - then Silver_Expr {silver:core:new( $Expr {e2.monadRewritten})} - else e2.monadRewritten; - --e1 >>= ( (\x y -> y >>= \z -> Return(x + z))(_, e2) ) - local bindBoth::Expr = - Silver_Expr { - $Expr {monadBind()} - ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadBind()} - (y, - \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} -> - $Expr {monadReturn()} - (x + z))) (_, $Expr {e2UnDec})) - }; - --e1 >>= ( (\x y -> Return(x + y))(_, e2) ) - local bind1::Expr = - Silver_Expr { - $Expr {monadBind()} - ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep))} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadReturn()} - (x + y))(_, $Expr {e2UnDec})) - }; - --e2 >>= ( (\x y -> Return(x + y))(e1, _) ) - local bind2::Expr = - Silver_Expr { - $Expr {monadBind()} - ($Expr {e2UnDec}, - (\x::$TypeExpr {typerepTypeExpr(e1.mtyperep)} - y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} -> - $Expr {monadReturn()} - (x + y))($Expr {e1UnDec}, _)) - }; - top.monadRewritten = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then bindBoth - else bind1 - else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then bind2 - else plus(e1.monadRewritten, '+', e2.monadRewritten); -} - -aspect production minus -top::Expr ::= e1::Expr '-' e2::Expr -{ - top.merrors := e1.merrors ++ e2.merrors; - top.merrors <- - if isMonad(e1.mtyperep, top.env) - then if monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then [] - else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ - " implicitly in this '-', not " ++ monadToString(e1.mtyperep))] - else []; - top.merrors <- - if isMonad(e2.mtyperep, top.env) - then if monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then [] - else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ - " implicitly in this '-', not " ++ monadToString(e2.mtyperep))] - else []; - - e1.mDownSubst = top.mDownSubst; - e2.mDownSubst = e1.mUpSubst; - ec.downSubst = e2.mUpSubst; - top.mUpSubst = ec.upSubst; - - local ec::TypeCheck = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then check(e1.mtyperep, e2.mtyperep) - else check(monadInnerType(e1.mtyperep), e2.mtyperep) - else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then check(e1.mtyperep, monadInnerType(e2.mtyperep)) - else check(e1.mtyperep, e2.mtyperep); - ec.finalSubst = top.mUpSubst; - top.mtyperep = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then e1.mtyperep - else e2.mtyperep; - - e1.monadicallyUsed = isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst; - e2.monadicallyUsed = isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst; - top.monadicNames = e1.monadicNames ++ e2.monadicNames; - - local e1UnDec::Expr = - if e1.mtyperep.isDecorated - then Silver_Expr {silver:core:new( $Expr {e1.monadRewritten})} - else e1.monadRewritten; - local e2UnDec::Expr = - if e2.mtyperep.isDecorated - then Silver_Expr {silver:core:new( $Expr {e2.monadRewritten})} - else e2.monadRewritten; - --e1 >>= ( (\x y -> y >>= \z -> Return(x - z))(_, e2) ) - local bindBoth::Expr = - Silver_Expr { - $Expr {monadBind()} - ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadBind()} - (y, - \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} -> - $Expr {monadReturn()} - (x - z))) (_, $Expr {e2UnDec})) - }; - --e1 >>= ( (\x y -> Return(x - y))(_, e2) ) - local bind1::Expr = - Silver_Expr { - $Expr {monadBind()} - ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep))} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadReturn()} - (x - y))(_, $Expr {e2UnDec})) - }; - --e2 >>= ( (\x y -> Return(x - y))(e1, _) ) - local bind2::Expr = - Silver_Expr { - $Expr {monadBind()} - ($Expr {e2UnDec}, - (\x::$TypeExpr {typerepTypeExpr(e1.mtyperep)} - y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} -> - $Expr {monadReturn()} - (x - y))($Expr {e1UnDec}, _)) - }; - top.monadRewritten = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then bindBoth - else bind1 - else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then bind2 - else minus(e1.monadRewritten, '-', e2.monadRewritten); -} - -aspect production multiply -top::Expr ::= e1::Expr '*' e2::Expr -{ - top.merrors := e1.merrors ++ e2.merrors; - top.merrors <- - if isMonad(e1.mtyperep, top.env) - then if monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then [] - else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ - " implicitly in this '*', not " ++ monadToString(e1.mtyperep))] - else []; - top.merrors <- - if isMonad(e2.mtyperep, top.env) - then if monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then [] - else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ - " implicitly in this '*', not " ++ monadToString(e2.mtyperep))] - else []; - - e1.mDownSubst = top.mDownSubst; - e2.mDownSubst = e1.mUpSubst; - ec.downSubst = e2.mUpSubst; - top.mUpSubst = ec.upSubst; - - local ec::TypeCheck = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then check(e1.mtyperep, e2.mtyperep) - else check(monadInnerType(e1.mtyperep), e2.mtyperep) - else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then check(e1.mtyperep, monadInnerType(e2.mtyperep)) - else check(e1.mtyperep, e2.mtyperep); - ec.finalSubst = top.mUpSubst; - top.mtyperep = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then e1.mtyperep - else e2.mtyperep; - - e1.monadicallyUsed = isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst; - e2.monadicallyUsed = isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst; - top.monadicNames = e1.monadicNames ++ e2.monadicNames; - - local e1UnDec::Expr = - if e1.mtyperep.isDecorated - then Silver_Expr {silver:core:new( $Expr {e1.monadRewritten})} - else e1.monadRewritten; - local e2UnDec::Expr = - if e2.mtyperep.isDecorated - then Silver_Expr {silver:core:new( $Expr {e2.monadRewritten})} - else e2.monadRewritten; - --e1 >>= ( (\x y -> y >>= \z -> Return(x * z))(_, e2) ) - local bindBoth::Expr = - Silver_Expr { - $Expr {monadBind()} - ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadBind()} - (y, - \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} -> - $Expr {monadReturn()} - (x * z))) (_, $Expr {e2UnDec})) - }; - --e1 >>= ( (\x y -> Return(x * y))(_, e2) ) - local bind1::Expr = - Silver_Expr { - $Expr {monadBind()} - ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep))} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadReturn()} - (x * y))(_, $Expr {e2UnDec})) - }; - --e2 >>= ( (\x y -> Return(x * y))(e1, _) ) - local bind2::Expr = - Silver_Expr { - $Expr {monadBind()} - ($Expr {e2UnDec}, - (\x::$TypeExpr {typerepTypeExpr(e1.mtyperep)} - y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} -> - $Expr {monadReturn()} - (x * y))($Expr {e1UnDec}, _)) - }; - top.monadRewritten = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then bindBoth - else bind1 - else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then bind2 - else multiply(e1.monadRewritten, '*', e2.monadRewritten); -} - -aspect production divide -top::Expr ::= e1::Expr '/' e2::Expr -{ - top.merrors := e1.merrors ++ e2.merrors; - top.merrors <- - if isMonad(e1.mtyperep, top.env) - then if monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then [] - else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ - " implicitly in this '/', not " ++ monadToString(e1.mtyperep))] - else []; - top.merrors <- - if isMonad(e2.mtyperep, top.env) - then if monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then [] - else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ - " implicitly in this '/', not " ++ monadToString(e2.mtyperep))] - else []; - - e1.mDownSubst = top.mDownSubst; - e2.mDownSubst = e1.mUpSubst; - ec.downSubst = e2.mUpSubst; - top.mUpSubst = ec.upSubst; - - local ec::TypeCheck = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then check(e1.mtyperep, e2.mtyperep) - else check(monadInnerType(e1.mtyperep), e2.mtyperep) - else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then check(e1.mtyperep, monadInnerType(e2.mtyperep)) - else check(e1.mtyperep, e2.mtyperep); - ec.finalSubst = top.mUpSubst; - top.mtyperep = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then e1.mtyperep - else e2.mtyperep; - - e1.monadicallyUsed = isMonad(e1.mtyperep, top.env); - e2.monadicallyUsed = isMonad(e2.mtyperep, top.env); - top.monadicNames = e1.monadicNames ++ e2.monadicNames; - - local e1UnDec::Expr = - if e1.mtyperep.isDecorated - then Silver_Expr {silver:core:new( $Expr {e1.monadRewritten})} - else e1.monadRewritten; - local e2UnDec::Expr = - if e2.mtyperep.isDecorated - then Silver_Expr {silver:core:new( $Expr {e2.monadRewritten})} - else e2.monadRewritten; - --e1 >>= ( (\x y -> y >>= \z -> Return(x / z))(_, e2) ) - local bindBoth::Expr = - Silver_Expr { - $Expr {monadBind()} - ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadBind()} - (y, - \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} -> - $Expr {monadReturn()} - (x / z))) (_, $Expr {e2UnDec})) - }; - --e1 >>= ( (\x y -> Return(x / y))(_, e2) ) - local bind1::Expr = - Silver_Expr { - $Expr {monadBind()} - ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep))} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadReturn()} - (x / y))(_, $Expr {e2UnDec})) - }; - --e2 >>= ( (\x y -> Return(x / y))(e1, _) ) - local bind2::Expr = - Silver_Expr { - $Expr {monadBind()} - ($Expr {e2UnDec}, - (\x::$TypeExpr {typerepTypeExpr(e1.mtyperep)} - y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} -> - $Expr {monadReturn()} - (x / y))($Expr {e1UnDec}, _)) - }; - top.monadRewritten = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then bindBoth - else bind1 - else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then bind2 - else divide(e1.monadRewritten, '/', e2.monadRewritten); -} - -aspect production modulus -top::Expr ::= e1::Expr '%' e2::Expr -{ - top.merrors := e1.merrors ++ e2.merrors; - top.merrors <- - if isMonad(e1.mtyperep, top.env) - then if monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then [] - else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ - " implicitly in this '%', not " ++ monadToString(e1.mtyperep))] - else []; - top.merrors <- - if isMonad(e2.mtyperep, top.env) - then if monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then [] - else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ - " implicitly in this '%', not " ++ monadToString(e2.mtyperep))] - else []; - - e1.mDownSubst = top.mDownSubst; - e2.mDownSubst = e1.mUpSubst; - ec.downSubst = e2.mUpSubst; - top.mUpSubst = ec.upSubst; - - local ec::TypeCheck = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then check(e1.mtyperep, e2.mtyperep) - else check(monadInnerType(e1.mtyperep), e2.mtyperep) - else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then check(e1.mtyperep, monadInnerType(e2.mtyperep)) - else check(e1.mtyperep, e2.mtyperep); - ec.finalSubst = top.mUpSubst; - top.mtyperep = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then e1.mtyperep - else e2.mtyperep; - - e1.monadicallyUsed = isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst; - e2.monadicallyUsed = isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst; - top.monadicNames = e1.monadicNames ++ e2.monadicNames; - - local e1UnDec::Expr = - if e1.mtyperep.isDecorated - then Silver_Expr {silver:core:new( $Expr {e1.monadRewritten})} - else e1.monadRewritten; - local e2UnDec::Expr = - if e2.mtyperep.isDecorated - then Silver_Expr {silver:core:new( $Expr {e2.monadRewritten})} - else e2.monadRewritten; - --e1 >>= ( (\x y -> y >>= \z -> Return(x % z))(_, e2) ) - local bindBoth::Expr = - Silver_Expr { - $Expr {monadBind()} - ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadBind()} - (y, - \z::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} -> - $Expr {monadReturn()} - (x % z))) (_, $Expr {e2UnDec})) - }; - --e1 >>= ( (\x y -> Return(x % y))(_, e2) ) - local bind1::Expr = - Silver_Expr { - $Expr {monadBind()} - ($Expr {e1UnDec}, - (\x::$TypeExpr {typerepTypeExpr(monadInnerType(e1.mtyperep))} - y::$TypeExpr {typerepTypeExpr(dropDecorated(e2.mtyperep))} -> - $Expr {monadReturn()} - (x % y))(_, $Expr {e2UnDec})) - }; - --e2 >>= ( (\x y -> Return(x % y))(e1, _) ) - local bind2::Expr = - Silver_Expr { - $Expr {monadBind()} - ($Expr {e2UnDec}, - (\x::$TypeExpr {typerepTypeExpr(e1.mtyperep)} - y::$TypeExpr {typerepTypeExpr(monadInnerType(e2.mtyperep))} -> - $Expr {monadReturn()} - (x % y))($Expr {e1UnDec}, _)) - }; - top.monadRewritten = if isMonad(e1.mtyperep, top.env) && monadsMatch(top.expectedMonad, e1.mtyperep, top.mDownSubst).fst - then if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then bindBoth - else bind1 - else if isMonad(e2.mtyperep, top.env) && monadsMatch(top.expectedMonad, e2.mtyperep, top.mDownSubst).fst - then bind2 - else modulus(e1.monadRewritten, '%', e2.monadRewritten); -} - -aspect production neg -top::Expr ::= '-' e::Expr -{ - top.merrors := e.merrors; - - top.mtyperep = e.mtyperep; - - e.monadicallyUsed = isMonad(e.mtyperep, top.env) && monadsMatch(top.expectedMonad, e.mtyperep, top.mDownSubst).fst; - top.monadicNames = e.monadicNames; - - propagate mDownSubst, mUpSubst; - - local eUnDec::Expr = - if e.mtyperep.isDecorated - then Silver_Expr {silver:core:new($Expr {e.monadRewritten})} - else e.monadRewritten; - top.monadRewritten = - if isMonad(e.mtyperep, top.env) - then Silver_Expr { - $Expr {monadBind()} - ($Expr {eUnDec}, - \x::$TypeExpr {typerepTypeExpr(monadInnerType(e.mtyperep))} -> - $Expr {monadReturn()}(-x)) - } - else neg('-', e.monadRewritten); -} - aspect production terminalConstructor top::Expr ::= 'terminal' '(' t::TypeExpr ',' es::Expr ',' el::Expr ')' { diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index a0394e764..48e5843d2 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -471,24 +471,6 @@ top::Expr ::= 'false' top.transform = booleanASTExpr(false); } -aspect production and -top::Expr ::= e1::Expr '&&' e2::Expr -{ - top.transform = andASTExpr(e1.transform, e2.transform); -} - -aspect production or -top::Expr ::= e1::Expr '||' e2::Expr -{ - top.transform = orASTExpr(e1.transform, e2.transform); -} - -aspect production notOp -top::Expr ::= '!' e::Expr -{ - top.transform = notASTExpr(e.transform); -} - aspect production intConst top::Expr ::= i::Int_t { @@ -507,42 +489,6 @@ top::Expr ::= 'attachNote' note::Expr 'on' e::Expr 'end' top.transform = noteAttachmentASTExpr(note.transform, e.transform); } -aspect production plus -top::Expr ::= e1::Expr '+' e2::Expr -{ - top.transform = plusASTExpr(e1.transform, e2.transform); -} - -aspect production minus -top::Expr ::= e1::Expr '-' e2::Expr -{ - top.transform = minusASTExpr(e1.transform, e2.transform); -} - -aspect production multiply -top::Expr ::= e1::Expr '*' e2::Expr -{ - top.transform = multiplyASTExpr(e1.transform, e2.transform); -} - -aspect production divide -top::Expr ::= e1::Expr '/' e2::Expr -{ - top.transform = divideASTExpr(e1.transform, e2.transform); -} - -aspect production modulus -top::Expr ::= e1::Expr '%' e2::Expr -{ - top.transform = modulusASTExpr(e1.transform, e2.transform); -} - -aspect production neg -top::Expr ::= '-' e::Expr -{ - top.transform = negASTExpr(e.transform); -} - aspect production stringConst top::Expr ::= s::String_t { diff --git a/grammars/silver/compiler/translation/java/core/Expr.sv b/grammars/silver/compiler/translation/java/core/Expr.sv index 1d256f4fd..62502bfcd 100644 --- a/grammars/silver/compiler/translation/java/core/Expr.sv +++ b/grammars/silver/compiler/translation/java/core/Expr.sv @@ -540,7 +540,9 @@ top::Expr ::= 'false' top.translation = "false"; top.lazyTranslation = top.translation; } - +{- TODO: We should re-enable the specialized translations here for primitive types, + - but that requires some attributes on the operands that we can't supply here. + - See https://github.com/melt-umn/silver/issues/812 aspect production and top::Expr ::= e1::Expr '&&' e2::Expr { @@ -561,7 +563,7 @@ top::Expr ::= '!' e::Expr top.translation = s"(!${e.translation})"; top.lazyTranslation = wrapThunk(top.translation, top.frame.lazyApplication); } - +-} aspect production ifThenElse top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'else' e3::Expr { @@ -594,7 +596,7 @@ top::Expr ::= 'attachNote' note::Expr 'on' e::Expr 'end' top.translation = e.translation; top.lazyTranslation = e.lazyTranslation; } - +{- aspect production plus top::Expr ::= e1::Expr '+' e2::Expr { @@ -631,7 +633,7 @@ top::Expr ::= '-' e::Expr top.translation = s"(-${e.translation})"; top.lazyTranslation = wrapThunk(top.translation, top.frame.lazyApplication); } - +-} aspect production terminalConstructor top::Expr ::= 'terminal' '(' t::TypeExpr ',' es::Expr ',' el::Expr ')' { From 28f524c87d41c24b1f1a6be229ccafc8ca5aceec Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Sun, 29 Oct 2023 18:12:36 -0500 Subject: [PATCH 087/283] Some fixes related to term rewriting --- .../compiler/extension/rewriting/Expr.sv | 56 ++++++++++--------- .../rewrite/expreval/AbstractSyntax.sv | 2 +- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index 48e5843d2..350d6b206 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -125,35 +125,37 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp case e, es of | productionReference(q), _ -> prodCallASTExpr(q.lookupValue.fullName, es.transform, anns.transform) - -- Special cases for efficiency + -- Special cases for efficiency, and workaround for type inference issues. + -- TODO: This doesn't work as expected when these operators are overloaded. | classMemberReference(q), snocAppExprs(oneAppExprs(presentAppExpr(e1)), _, presentAppExpr(e2)) -> - if q.lookupValue.fullName == "silver:core:eq" - then eqeqASTExpr(e1.transform, e2.transform) - else if q.lookupValue.fullName == "silver:core:neq" - then neqASTExpr(e1.transform, e2.transform) - else if q.lookupValue.fullName == "silver:core:lt" - then ltASTExpr(e1.transform, e2.transform) - else if q.lookupValue.fullName == "silver:core:lte" - then lteqASTExpr(e1.transform, e2.transform) - else if q.lookupValue.fullName == "silver:core:gt" - then gtASTExpr(e1.transform, e2.transform) - else if q.lookupValue.fullName == "silver:core:gte" - then gteqASTExpr(e1.transform, e2.transform) - else if q.lookupValue.fullName == "silver:core:append" - then appendASTExpr(e1.transform, e2.transform) - else applyASTExpr(e.transform, es.transform, anns.transform) + case q.lookupValue.fullName of + | "silver:core:conj" -> andASTExpr(e1.transform, e2.transform) + | "silver:core:disj" -> orASTExpr(e1.transform, e2.transform) + | "silver:core:eq" -> eqeqASTExpr(e1.transform, e2.transform) + | "silver:core:neq" -> neqASTExpr(e1.transform, e2.transform) + | "silver:core:lt" -> ltASTExpr(e1.transform, e2.transform) + | "silver:core:lte" -> lteqASTExpr(e1.transform, e2.transform) + | "silver:core:gt" -> gtASTExpr(e1.transform, e2.transform) + | "silver:core:gte" -> gteqASTExpr(e1.transform, e2.transform) + | "silver:core:add" -> plusASTExpr(e1.transform, e2.transform) + | "silver:core:sub" -> minusASTExpr(e1.transform, e2.transform) + | "silver:core:mul" -> multiplyASTExpr(e1.transform, e2.transform) + | "silver:core:div" -> divideASTExpr(e1.transform, e2.transform) + | "silver:core:mod" -> modulusASTExpr(e1.transform, e2.transform) + | "silver:core:append" -> appendASTExpr(e1.transform, e2.transform) + | _ -> applyASTExpr(e.transform, es.transform, anns.transform) + end | classMemberReference(q), oneAppExprs(presentAppExpr(e)) -> - if q.lookupValue.fullName == "silver:core:toString" - then toStringASTExpr(e.transform) - else if q.lookupValue.fullName == "silver:core:toInteger" - then toIntegerASTExpr(e.transform) - else if q.lookupValue.fullName == "silver:core:toFloat" - then toFloatASTExpr(e.transform) - else if q.lookupValue.fullName == "silver:core:toBoolean" - then toBooleanASTExpr(e.transform) - else if q.lookupValue.fullName == "silver:core:length" - then lengthASTExpr(e.transform) - else applyASTExpr(e.transform, es.transform, anns.transform) + case q.lookupValue.fullName of + | "silver:core:not" -> notASTExpr(e.transform) + | "silver:core:negate" -> negASTExpr(e.transform) + | "silver:core:toString" -> toStringASTExpr(e.transform) + | "silver:core:toInteger" -> toIntegerASTExpr(e.transform) + | "silver:core:toFloat" -> toFloatASTExpr(e.transform) + | "silver:core:toBoolean" -> toBooleanASTExpr(e.transform) + | "silver:core:length" -> lengthASTExpr(e.transform) + | _ -> applyASTExpr(e.transform, es.transform, anns.transform) + end | _, _ -> applyASTExpr(e.transform, es.transform, anns.transform) end; diff --git a/test/silver_features/rewrite/expreval/AbstractSyntax.sv b/test/silver_features/rewrite/expreval/AbstractSyntax.sv index 42ead624d..35aa0847d 100644 --- a/test/silver_features/rewrite/expreval/AbstractSyntax.sv +++ b/test/silver_features/rewrite/expreval/AbstractSyntax.sv @@ -1,6 +1,6 @@ grammar silver_features:rewrite:expreval; -imports silver:core hiding add, sub, mul, div; +imports silver:core; imports silver:langutil; imports silver:langutil:pp; imports silver:rewrite; From 17389bb6611e08a7fb65d2874e04266561fe5e39 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 30 Oct 2023 10:14:27 -0500 Subject: [PATCH 088/283] Fix implicit monads issue --- .../extension/implicit_monads/Expr.sv | 178 ++++++++++++++++++ 1 file changed, 178 insertions(+) diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index b737dfe9e..d6bfffb51 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -1254,6 +1254,184 @@ top::Expr ::= 'false' top.monadRewritten = falseConst('false'); } +-- These aspects for and/or provide special-case monadic short circuit evaluation semantics, +-- if the second operand corresponds to failure. +aspect production and +top::Expr ::= e1::Expr '&&' e2::Expr +{ + -- TODO: Need to re-decorate here, to avoid hidden transitive deps flow analysis issue. + -- See https://github.com/melt-umn/silver/issues/812 + forward ne1 = new(e1); + forward ne2 = new(e2); + + top.merrors := ne1.merrors ++ ne2.merrors; + top.merrors <- + if isMonad(ne1.mtyperep, top.env) + then if monadsMatch(top.expectedMonad, ne1.mtyperep, top.mDownSubst).fst + then [] + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ + " implicitly in this '&&', not " ++ monadToString(ne1.mtyperep))] + else []; + top.merrors <- + if isMonad(ne2.mtyperep, top.env) + then if monadsMatch(top.expectedMonad, ne2.mtyperep, top.mDownSubst).fst + then [] + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ + " implicitly in this '&&', not " ++ monadToString(ne2.mtyperep))] + else []; + + local ec1::TypeCheck = if isMonad(ne1.mtyperep, top.env) && monadsMatch(top.expectedMonad, ne1.mtyperep, top.mDownSubst).fst + then check(monadInnerType(ne1.mtyperep), boolType()) + else check(ne1.mtyperep, boolType()); + local ec2::TypeCheck = if isMonad(ne2.mtyperep, top.env) && monadsMatch(top.expectedMonad, ne2.mtyperep, top.mDownSubst).fst + then check(monadInnerType(ne2.mtyperep), boolType()) + else check(ne2.mtyperep, boolType()); + ec1.finalSubst = top.finalSubst; + ec2.finalSubst = top.finalSubst; + ne1.mDownSubst = top.mDownSubst; + ne2.mDownSubst = ne1.mUpSubst; + ec1.downSubst = ne2.mUpSubst; + ec2.downSubst = ec1.upSubst; + top.mUpSubst = ec2.upSubst; + top.mtyperep = if isMonad(ne1.mtyperep, top.env) && monadsMatch(top.expectedMonad, ne1.mtyperep, top.mDownSubst).fst + then ne1.mtyperep --assume it will be well-typed + else if isMonad(ne2.mtyperep, top.env) && monadsMatch(top.expectedMonad, ne2.mtyperep, top.mDownSubst).fst + then ne2.mtyperep + else boolType(); + + ne1.monadicallyUsed = isMonad(ne1.mtyperep, top.env) && monadsMatch(top.expectedMonad, ne1.mtyperep, top.mDownSubst).fst; + ne2.monadicallyUsed = isMonad(ne2.mtyperep, top.env) && monadsMatch(top.expectedMonad, ne2.mtyperep, top.mDownSubst).fst; + top.monadicNames = ne1.monadicNames ++ ne2.monadicNames; + + local e1UnDec::Expr = + if ne1.mtyperep.isDecorated + then Silver_Expr {silver:core:new( $Expr {ne1.monadRewritten})} + else ne1.monadRewritten; + local e2UnDec::Expr = + if ne2.mtyperep.isDecorated + then Silver_Expr {silver:core:new( $Expr {ne2.monadRewritten})} + else ne2.monadRewritten; + --e1 >>= ( (\x y -> if x then y else Return(false))(_, e2) ) + local bindBoth::Expr = + Silver_Expr { + $Expr {monadBind()} + ($Expr {e1UnDec}, + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(ne2.mtyperep))} + y::$TypeExpr {typerepTypeExpr(dropDecorated(ne2.mtyperep))} -> + if x then y else $Expr {monadReturn()}(false)) (_, $Expr {e2UnDec})) + }; + --e1 >>= ( (\x y -> Return(x && y))(_, e2) ) + local bind1::Expr = + Silver_Expr { + $Expr {monadBind()} + ($Expr {e1UnDec}, + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(ne1.mtyperep))} + y::$TypeExpr {typerepTypeExpr(dropDecorated(ne2.mtyperep))} -> + $Expr {monadReturn()} + (x && y))(_, $Expr {e2UnDec})) + }; + --if e1 then e2 else Return(false) + local bind2::Expr = + Silver_Expr { + if $Expr {e1UnDec} then $Expr {e2UnDec} else $Expr {monadReturn()}(false) + }; + top.monadRewritten = if isMonad(ne1.mtyperep, top.env) && monadsMatch(top.expectedMonad, ne1.mtyperep, top.mDownSubst).fst + then if isMonad(ne2.mtyperep, top.env) && monadsMatch(top.expectedMonad, ne2.mtyperep, top.mDownSubst).fst + then bindBoth + else bind1 + else if isMonad(ne2.mtyperep, top.env) && monadsMatch(top.expectedMonad, ne2.mtyperep, top.mDownSubst).fst + then bind2 + else and(ne1.monadRewritten, '&&', ne2.monadRewritten); +} + +aspect production or +top::Expr ::= e1::Expr '||' e2::Expr +{ + -- TODO: Need to re-decorate here, to avoid hidden transitive deps flow analysis issue. + -- See https://github.com/melt-umn/silver/issues/812 + forward ne1 = new(e1); + forward ne2 = new(e2); + + top.merrors := ne1.merrors ++ ne2.merrors; + top.merrors <- + if isMonad(ne1.mtyperep, top.env) + then if monadsMatch(top.expectedMonad, ne1.mtyperep, top.mDownSubst).fst + then [] + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ + " implicitly in this '||', not " ++ monadToString(ne1.mtyperep))] + else []; + top.merrors <- + if isMonad(ne2.mtyperep, top.env) + then if monadsMatch(top.expectedMonad, ne2.mtyperep, top.mDownSubst).fst + then [] + else [errFromOrigin(top, "Can only use " ++ monadToString(top.expectedMonad) ++ + " implicitly in this '||', not " ++ monadToString(ne2.mtyperep))] + else []; + + local ec1::TypeCheck = if isMonad(ne1.mtyperep, top.env) && monadsMatch(top.expectedMonad, ne1.mtyperep, top.mDownSubst).fst + then check(monadInnerType(ne1.mtyperep), boolType()) + else check(ne1.mtyperep, boolType()); + local ec2::TypeCheck = if isMonad(ne2.mtyperep, top.env) && monadsMatch(top.expectedMonad, ne2.mtyperep, top.mDownSubst).fst + then check(monadInnerType(ne2.mtyperep), boolType()) + else check(ne2.mtyperep, boolType()); + ec1.finalSubst = top.finalSubst; + ec2.finalSubst = top.finalSubst; + ne1.mDownSubst = top.mDownSubst; + ne2.mDownSubst = ne1.mUpSubst; + ec1.downSubst = ne2.mUpSubst; + ec2.downSubst = ec1.upSubst; + top.mUpSubst = ec2.upSubst; + top.mtyperep = if isMonad(ne1.mtyperep, top.env) && monadsMatch(top.expectedMonad, ne1.mtyperep, top.mDownSubst).fst + then ne1.mtyperep --assume it will be well-typed + else if isMonad(ne2.mtyperep, top.env) && monadsMatch(top.expectedMonad, ne2.mtyperep, top.mDownSubst).fst + then ne2.mtyperep + else boolType(); + + ne1.monadicallyUsed = isMonad(ne1.mtyperep, top.env) && monadsMatch(top.expectedMonad, ne1.mtyperep, top.mDownSubst).fst; + ne2.monadicallyUsed = isMonad(ne2.mtyperep, top.env) && monadsMatch(top.expectedMonad, ne2.mtyperep, top.mDownSubst).fst; + top.monadicNames = ne1.monadicNames ++ ne2.monadicNames; + + local e1UnDec::Expr = + if ne1.mtyperep.isDecorated + then Silver_Expr {silver:core:new( $Expr {ne1.monadRewritten})} + else ne1.monadRewritten; + local e2UnDec::Expr = + if ne2.mtyperep.isDecorated + then Silver_Expr {silver:core:new( $Expr {ne2.monadRewritten})} + else ne2.monadRewritten; + --e1 >>= ( (\x y -> if x then Return(true) else y)(_, e2) ) + local bindBoth::Expr = + Silver_Expr { + $Expr {monadBind()} + ($Expr {e1UnDec}, + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(ne2.mtyperep))} + y::$TypeExpr {typerepTypeExpr(dropDecorated(ne2.mtyperep))} -> + if x then $Expr {monadReturn()}(true) else y) (_, $Expr {e2UnDec})) + }; + --e1 >>= ( (\x y -> Return(x || y))(_, e2) ) + local bind1::Expr = + Silver_Expr { + $Expr {monadBind()} + ($Expr {e1UnDec}, + (\x::$TypeExpr {typerepTypeExpr(monadInnerType(ne1.mtyperep))} + y::$TypeExpr {typerepTypeExpr(dropDecorated(ne2.mtyperep))} -> + $Expr {monadReturn()} + (x || y))(_, $Expr {e2UnDec})) + }; + --if e1 then Return(true) else e2 + local bind2::Expr = + Silver_Expr { + if $Expr {e1UnDec} then $Expr {monadReturn()}(true) else $Expr {e2UnDec} + }; + top.monadRewritten = if isMonad(ne1.mtyperep, top.env) && monadsMatch(top.expectedMonad, ne1.mtyperep, top.mDownSubst).fst + then if isMonad(ne2.mtyperep, top.env) && monadsMatch(top.expectedMonad, ne2.mtyperep, top.mDownSubst).fst + then bindBoth + else bind1 + else if isMonad(ne2.mtyperep, top.env) && monadsMatch(top.expectedMonad, ne2.mtyperep, top.mDownSubst).fst + then bind2 + else or(ne1.monadRewritten, '||', ne2.monadRewritten); +} + concrete production ifThen top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'end' --this is easier than anything else to do { From b35c01765862f11a10b3824a19ca7c350399d858 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 30 Oct 2023 14:38:42 -0500 Subject: [PATCH 089/283] Add genericShow function in silver:core --- grammars/silver/core/HackyUnParse.sv | 21 ++++++++++++++++----- runtime/java/src/common/Util.java | 25 +++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/grammars/silver/core/HackyUnParse.sv b/grammars/silver/core/HackyUnParse.sv index 8ee345554..e61fb9c40 100644 --- a/grammars/silver/core/HackyUnParse.sv +++ b/grammars/silver/core/HackyUnParse.sv @@ -4,10 +4,7 @@ grammar silver:core; - hackUnparse takes any value, and produce a string that represents - that value. It is mainly useful for debugging. - - - Not considered part of the "standard" library of Silver. It may change from - - release to release. Don't rely on it. - - - - In the distant future, this may become obsolete when a 'Show' typeclass is available. + - @warning This is deprecated. Use silver:langutil:pp:show instead, or genericShow in polymorphic contexts/generated code. -} function hackUnparse String ::= nt::a @@ -17,4 +14,18 @@ String ::= nt::a "java" : return "(common.Util.hackyhackyUnparse(%nt%))"; } - +@{-- + - Take any value, and return a human-readable string representation. + - This attempts to make use of the pp or unparse attributes, if a term/tree with either of those is provided. + - Intended for debugging purposes or for error handling in generated code; prefer silver:langutil:pp:show when possible. + - + - Implementation note: this function makes use of silver:langutil:reflect:genericPP if that library is available, + - else falling back to the less-sophisticated hackUnparse implementation in the runtime. + -} +function genericShow +String ::= x::a +{ + return error("Not impl"); +} foreign { + "java" : return "(common.Util.genericShow(%x%))"; +} diff --git a/runtime/java/src/common/Util.java b/runtime/java/src/common/Util.java index 5590af164..ebec4c5b0 100644 --- a/runtime/java/src/common/Util.java +++ b/runtime/java/src/common/Util.java @@ -1,6 +1,8 @@ package common; import java.io.*; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.*; import java.util.stream.Collectors; import java.net.URI; @@ -392,6 +394,29 @@ private static void hackyhackyUnparseList(ConsCell c, StringBuilder sb) { sb.append("]"); } + /** + * Attempt to use the improved genericPP from silver:langutil:reflect if that library is available; + * else fall back to hackUnparse. + * Note that we can't actually let the runtime/silver:core depend on that library, + * thus we attempt to call it via reflection. + * + * @param o The object to show + * @return A string representation. + */ + public static StringCatter genericShow(Object o) { + try { + Method genericPP = Class.forName("silver.langutil.reflect.PgenericPP") + .getMethod("invoke", OriginContext.class, Object.class); + Method showDoc = Class.forName("silver.langutil.pp.PshowDoc") + .getMethod("invoke", OriginContext.class, Object.class, Object.class); + Object pp = genericPP.invoke(null, OriginContext.FFI_CONTEXT, o); + return (StringCatter)showDoc.invoke(null, OriginContext.FFI_CONTEXT, 80, pp); + } catch(ClassNotFoundException | NoSuchMethodException | SecurityException | + IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + return hackyhackyUnparse(o); + } + } + /** * Calls a Copper parser, and returns a ParseResult object. * From e00205668b7707cafae36697614579765508a1f3 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 30 Oct 2023 15:05:54 -0500 Subject: [PATCH 090/283] Change uses of hackUnparse to genericShow --- .../silver/compiler/definition/core/AGDcl.sv | 2 +- .../silver/compiler/definition/core/Expr.sv | 3 +- .../silver/compiler/driver/util/RootSpec.sv | 2 +- .../compiler/extension/autoattr/Destruct.sv | 2 +- .../compiler/extension/doc/core/Root.sv | 4 +-- .../extension/doc/core/TypeClassDcls.sv | 8 ++--- .../extension/doc/core/doclang/DclComment.sv | 2 +- .../extension/patternmatching/PatternTypes.sv | 2 +- .../compiler/extension/rewriting/Expr.sv | 2 +- .../extension/strategyattr/StrategyUtils.sv | 2 +- .../extension/testing/EqualityTest.sv | 4 +-- .../compiler/extension/testing/Helper.sv | 14 +-------- .../translation/java/driver/BuildProcess.sv | 2 +- grammars/silver/core/IOMisc.sv | 2 +- grammars/silver/testing/TestSuite.sv | 11 +++---- support/vim/syntax/sv.vim | 2 +- test/origintracking/tracing_origins/test.sv | 2 +- .../silver_construction/SilverConstruction.sv | 30 +++++++++---------- test/silver_features/Reflection.sv | 2 -- test/silver_features/Tuple.sv | 4 +-- test/silver_features/TypeClasses.sv | 4 +-- test/stdlib/NativeSerialize.sv | 16 +++++----- 22 files changed, 52 insertions(+), 70 deletions(-) diff --git a/grammars/silver/compiler/definition/core/AGDcl.sv b/grammars/silver/compiler/definition/core/AGDcl.sv index 7516b7212..b5f3d9136 100644 --- a/grammars/silver/compiler/definition/core/AGDcl.sv +++ b/grammars/silver/compiler/definition/core/AGDcl.sv @@ -55,7 +55,7 @@ top::AGDcl ::= e::[Message] abstract production defsAGDcl top::AGDcl ::= d::[Def] { - top.unparse = s"{- Defs:\n${hackUnparse(d)} -}"; + top.unparse = s"{- Defs:\n${genericShow(d)} -}"; top.defs := d; } diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index 88792873e..7af7efc6a 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -264,8 +264,7 @@ top::Expr ::= q::'forward' concrete production application top::Expr ::= e::Expr '(' es::AppExprs ',' anns::AnnoAppExprs ')' { - -- TODO: fix comma when one or the other is empty - top.unparse = e.unparse ++ "(" ++ es.unparse ++ "," ++ anns.unparse ++ ")"; + top.unparse = e.unparse ++ "(" ++ es.unparse ++ (if null(es.exprs) || null(anns.exprs) then "" else ", ") ++ anns.unparse ++ ")"; propagate config, grammarName, env, freeVars, frame, originRules, compiledGrammars; e.isRoot = false; diff --git a/grammars/silver/compiler/driver/util/RootSpec.sv b/grammars/silver/compiler/driver/util/RootSpec.sv index 899193a06..a1521a695 100644 --- a/grammars/silver/compiler/driver/util/RootSpec.sv +++ b/grammars/silver/compiler/driver/util/RootSpec.sv @@ -138,7 +138,7 @@ top::RootSpec ::= g::Grammar oldInterface::Maybe grammarName:: extraFileErrors := []; -- Seed flow deps with {compiledGrammars, config} - extraFileErrors <- if false then error(hackUnparse((top.compiledGrammars, top.config))) else []; + extraFileErrors <- if false then error(genericShow((top.compiledGrammars, top.config))) else []; top.allFileErrors = map( \ fe::(String, [Message]) -> case fe of (fileName, fileErrors) -> diff --git a/grammars/silver/compiler/extension/autoattr/Destruct.sv b/grammars/silver/compiler/extension/autoattr/Destruct.sv index e331ad489..8664758f0 100644 --- a/grammars/silver/compiler/extension/autoattr/Destruct.sv +++ b/grammars/silver/compiler/extension/autoattr/Destruct.sv @@ -103,7 +103,7 @@ top::ProductionStmt ::= attr::Decorated! QName "Destruct attribute " ++ $Expr{stringConst(terminal(String_t, s"\"${attr.name}\"", attr.nameLoc))} ++ " demanded on child " ++ $Expr{stringConst(terminal(String_t, s"\"${ie.snd.elementName}\"", attr.nameLoc))} ++ " of production " ++ $Expr{stringConst(terminal(String_t, s"\"${top.frame.signature.fullName}\"", attr.nameLoc))} ++ - " when given value " ++ silver:core:hackUnparse(a) ++ " does not match.") -- TODO: Shouldn't really be using hackUnparse here. + " when given value " ++ silver:core:genericShow(a) ++ " does not match.") end; }, filter( diff --git a/grammars/silver/compiler/extension/doc/core/Root.sv b/grammars/silver/compiler/extension/doc/core/Root.sv index dd7fc105b..cd7e9bb71 100644 --- a/grammars/silver/compiler/extension/doc/core/Root.sv +++ b/grammars/silver/compiler/extension/doc/core/Root.sv @@ -88,9 +88,9 @@ aspect default production top::AGDcl ::= { top.upDocConfig := []; - -- top.docs := [mkUndocumentedItem(s"", top)]; + -- top.docs := [mkUndocumentedItem(s"", top)]; top.docDcls := []; - -- top.docUnparse = head(explode("\n", top.unparse)) ++ "\n{{< hint danger >}}\nNo docUnparse defined for `" ++ hackUnparse(top) ++ "`\n{{< /hint >}}\n\n"; + -- top.docUnparse = head(explode("\n", top.unparse)) ++ "\n{{< hint danger >}}\nNo docUnparse defined for `" ++ genericShow(top) ++ "`\n{{< /hint >}}\n\n"; } aspect production appendAGDcl diff --git a/grammars/silver/compiler/extension/doc/core/TypeClassDcls.sv b/grammars/silver/compiler/extension/doc/core/TypeClassDcls.sv index d6f3add91..20d351a0c 100644 --- a/grammars/silver/compiler/extension/doc/core/TypeClassDcls.sv +++ b/grammars/silver/compiler/extension/doc/core/TypeClassDcls.sv @@ -52,11 +52,11 @@ top::ClassBody ::= h::ClassBodyItem t::ClassBody aspect default production top::ClassBodyItem ::= { - top.docForName = ""; + top.docForName = ""; top.upDocConfig := []; top.docDcls := []; top.docs := [undocumentedItem(top.scopeName ++ "." ++ top.docForName, "`" ++ top.scopeName ++ "`." ++ top.docUnparse, top.grammarName)]; - top.docUnparse = ""; + top.docUnparse = ""; } concrete production documentedClassBodyItem @@ -131,11 +131,11 @@ top::InstanceBody ::= h::InstanceBodyItem t::InstanceBody aspect default production top::InstanceBodyItem ::= { - top.docForName = ""; + top.docForName = ""; top.upDocConfig := []; top.docDcls := []; top.docs := [undocumentedItem(top.scopeName ++ "." ++ top.docForName, "`" ++ top.scopeName ++ "`." ++ top.docUnparse, top.grammarName)]; - top.docUnparse = ""; + top.docUnparse = ""; } concrete production documentedInstanceBodyItem diff --git a/grammars/silver/compiler/extension/doc/core/doclang/DclComment.sv b/grammars/silver/compiler/extension/doc/core/doclang/DclComment.sv index faabb5e81..d59a05018 100644 --- a/grammars/silver/compiler/extension/doc/core/doclang/DclComment.sv +++ b/grammars/silver/compiler/extension/doc/core/doclang/DclComment.sv @@ -320,7 +320,7 @@ top::DclCommentBlock ::= Hide_t concrete production configBlock top::DclCommentBlock ::= Config_t Whitespace_t param::Id_t Whitespace_t Equals_t Whitespace_t value::ConfigValue { - top.body = "@config " ++ param.lexeme ++ " = " ++ hackUnparse(value); --not emitted + top.body = "@config " ++ param.lexeme ++ " = " ++ genericShow(value); --not emitted top.otherBlocks = []; top.paramBlocks = []; top.configArgs = [(param.lexeme, value)]; diff --git a/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv b/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv index 9d1d7c4f0..3014822ae 100644 --- a/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv +++ b/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv @@ -70,7 +70,7 @@ synthesized attribute patternTypeName::String; concrete production prodAppPattern_named top::Pattern ::= prod::QName '(' ps::PatternList ',' nps::NamedPatternList ')' { - top.unparse = prod.unparse ++ "(" ++ ps.unparse ++ ")"; + top.unparse = prod.unparse ++ "(" ++ ps.unparse ++ (if !null(ps.patternList) && !null(nps.namedPatternList) then ", " else "") ++ nps.unparse ++ ")"; local parms :: Integer = prod.lookupValue.typeScheme.arity; diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index a0394e764..9383c759c 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -579,7 +579,7 @@ top::Expr ::= h::Expr '::' t::Expr case forward of | functionInvocation(_, snocAppExprs(oneAppExprs(presentAppExpr(decH)), _, presentAppExpr(decT)), _) -> consListASTExpr(decH.transform, decT.transform) - | _ -> error("Unexpected forward: " ++ hackUnparse(forward)) + | _ -> error("Unexpected forward: " ++ genericShow(forward)) end; } diff --git a/grammars/silver/compiler/extension/strategyattr/StrategyUtils.sv b/grammars/silver/compiler/extension/strategyattr/StrategyUtils.sv index f34400f2f..cda53f4a6 100644 --- a/grammars/silver/compiler/extension/strategyattr/StrategyUtils.sv +++ b/grammars/silver/compiler/extension/strategyattr/StrategyUtils.sv @@ -16,7 +16,7 @@ top::StrategyExpr ::= silver:core:unsafeTrace( $name{top.frame.signature.outputElement.elementName}, silver:core:print( - hackUnparse($name{top.frame.signature.outputElement.elementName}) ++ "\n\n", + genericShow($name{top.frame.signature.outputElement.elementName}) ++ "\n\n", silver:core:unsafeIO())) }; } diff --git a/grammars/silver/compiler/extension/testing/EqualityTest.sv b/grammars/silver/compiler/extension/testing/EqualityTest.sv index 9e5187db9..1cb0c070d 100644 --- a/grammars/silver/compiler/extension/testing/EqualityTest.sv +++ b/grammars/silver/compiler/extension/testing/EqualityTest.sv @@ -151,8 +151,8 @@ ag::AGDcl ::= kwd::'equalityTest' attributeDef(concreteDefLHS(qNameId(tref)), '.', qNameAttrOccur(qNameId(msgref)), '=', foldStringExprs([ strCnst("Test at " ++ getParsedOriginLocationOrFallback(ag).unparse ++ " failed.\nChecking that expression\n " ++ - stringifyString(value.unparse) ++ "\nshould be same as expression\n " ++ - stringifyString(expected.unparse) ++ "\nActual value:\n "), + value.unparse ++ "\nshould be same as expression\n " ++ + expected.unparse ++ "\nActual value:\n "), Silver_Expr { silver:testing:showTestValue(value) }, strCnst("\nExpected value: \n "), Silver_Expr { silver:testing:showTestValue(expected) }, diff --git a/grammars/silver/compiler/extension/testing/Helper.sv b/grammars/silver/compiler/extension/testing/Helper.sv index a6e8a7215..a68e3f6c4 100644 --- a/grammars/silver/compiler/extension/testing/Helper.sv +++ b/grammars/silver/compiler/extension/testing/Helper.sv @@ -32,7 +32,7 @@ Expr ::= es::[Expr] function strCnst Expr ::= s::String { - return stringConst(terminal(String_t, "\"" ++ stringifyString(s) ++ "\"")); + return stringConst(terminal(String_t, "\"" ++ escapeString(s) ++ "\"")); } -- Create an attribute reference from two names. as in "n.a" @@ -42,15 +42,3 @@ Expr ::= n::String a::String return access(mkNameExpr(n), '.', qNameAttrOccur(qName(a))); } - --- replace " characters with two: \ and " -function stringifyString -String ::= s::String -{ - -- be sure to escape backslashes first! - return substitute("\n", "\\n", - substitute("\t", "\\t", - substitute("\"", "\\\"", - substitute("\\", "\\\\", s)))); -} - diff --git a/grammars/silver/compiler/translation/java/driver/BuildProcess.sv b/grammars/silver/compiler/translation/java/driver/BuildProcess.sv index 11e06ecd0..723793479 100644 --- a/grammars/silver/compiler/translation/java/driver/BuildProcess.sv +++ b/grammars/silver/compiler/translation/java/driver/BuildProcess.sv @@ -97,7 +97,7 @@ top::Compilation ::= g::Grammars _ buildGrammars::[String] benv::BuildEnv keepFiles := []; -- Seed flow deps with {config} - keepFiles <- if false then error(hackUnparse(top.config)) else []; + keepFiles <- if false then error(genericShow(top.config)) else []; top.postOps <- [genBuild(buildXmlLocation, buildXml)] ++ diff --git a/grammars/silver/core/IOMisc.sv b/grammars/silver/core/IOMisc.sv index 92bc2da96..c055a62a9 100644 --- a/grammars/silver/core/IOMisc.sv +++ b/grammars/silver/core/IOMisc.sv @@ -76,7 +76,7 @@ a ::= val::a str::String function unsafeTraceDump a ::= val::a { - return unsafeTrace(val, printlnT(hackUnparse(val), unsafeIO())); + return unsafeTrace(val, printlnT(genericShow(val), unsafeIO())); } diff --git a/grammars/silver/testing/TestSuite.sv b/grammars/silver/testing/TestSuite.sv index abd2f742c..9f5aa167b 100644 --- a/grammars/silver/testing/TestSuite.sv +++ b/grammars/silver/testing/TestSuite.sv @@ -1,9 +1,5 @@ grammar silver:testing ; -imports silver:reflect; -imports silver:langutil; -imports silver:langutil:pp; - nonterminal Test with msg, pass, ioIn, ioOut ; @@ -112,14 +108,15 @@ Boolean ::= f::(Boolean ::=) times::Integer f() && repeatTestTimes(f, times - 1); } --- TODO: Consider replacing this with the regular Show type class, --- would require some way of propagating the pp attribute. +-- The expected and result values in equalityTest are bound as locals, +-- causing them to be implicitly decorated if they are nonterminals. +-- This exists as a workaround to ensure they are displayed properly as undecorated terms. class ShowTestValue a { showTestValue :: (String ::= a); } instance ShowTestValue a { - showTestValue = \ x::a -> show(80, reflect(x)); + showTestValue = genericShow; } instance ShowTestValue a => ShowTestValue Decorated a with i { diff --git a/support/vim/syntax/sv.vim b/support/vim/syntax/sv.vim index ba546b965..4afedda10 100644 --- a/support/vim/syntax/sv.vim +++ b/support/vim/syntax/sv.vim @@ -22,7 +22,7 @@ syn keyword svlangFlowOther forwarding forwards to return pluck syn keyword svlangFlow case rule of let in end decorate with prefix else forward if new then -syn keyword svlangFunction print toString toInteger toFloat length reference substring indexOf error cast left right partitionEithers hackUnparse print readLineStdin exit mkdir system writeFile appendFile fileTime isFile isDirectory readFile cwd envVar listContents deleteFile deleteTree copyFile touchFile error unsafeIO genInt genRand unsafeTrace dirNameInFilePath fileNameInFilePath splitFileNameAndExtension map foldr foldl foldr1 foldl1 filter partition containsBy nubBy removeBy removeAllBy last drop take dropWhile takeWhile takeUntil positionOf positionOfHelper repeat zipWith reverse sortBy groupBy intersperse unionBy intersectBy unionsBy nil cons append null listLength head tail locationLte fromMaybe orElse consMaybe catMaybes fst snd lookupBy lookupAllBy unzipPairs parseTreeOrDieWithoutStackTrace implode explode indexOf lastIndexOf substring startsWith endsWith substitute replicate isDigit isAlpha isSpace isLower isUpper toIntSafe compareString stringConcat stringEq stringLte runIO evalIO unsafeEvalIO bindList returnList bindMaybe returnMaybe runState evalState ioval +syn keyword svlangFunction print toString toInteger toFloat length reference substring indexOf error cast left right partitionEithers genericShow print readLineStdin exit mkdir system writeFile appendFile fileTime isFile isDirectory readFile cwd envVar listContents deleteFile deleteTree copyFile touchFile error unsafeIO genInt genRand unsafeTrace dirNameInFilePath fileNameInFilePath splitFileNameAndExtension map foldr foldl foldr1 foldl1 filter partition containsBy nubBy removeBy removeAllBy last drop take dropWhile takeWhile takeUntil positionOf positionOfHelper repeat zipWith reverse sortBy groupBy intersperse unionBy intersectBy unionsBy nil cons append null listLength head tail locationLte fromMaybe orElse consMaybe catMaybes fst snd lookupBy lookupAllBy unzipPairs parseTreeOrDieWithoutStackTrace implode explode indexOf lastIndexOf substring startsWith endsWith substitute replicate isDigit isAlpha isSpace isLower isUpper toIntSafe compareString stringConcat stringEq stringLte runIO evalIO unsafeEvalIO bindList returnList bindMaybe returnMaybe runState evalState ioval "syn keyword svlangIdeInner contained builder postbuilder exporter folder property string required string wizard new file stub generator product name version option resource diff --git a/test/origintracking/tracing_origins/test.sv b/test/origintracking/tracing_origins/test.sv index d56721077..19bb84cdb 100644 --- a/test/origintracking/tracing_origins/test.sv +++ b/test/origintracking/tracing_origins/test.sv @@ -15,6 +15,6 @@ equalityTest( | just(originAndRedexOriginInfo(_, _, [traceNote("tracing_origins:test.sv:10:15"), traceNote("tracing_origins:test.sv:14:27")], _, originNotes=[traceNote("common:nat.sv:18:16")])) -> "OK" - | ou -> hackUnparse(ou) + | ou -> genericShow(ou) end, "OK", String, oitests); diff --git a/test/silver_construction/SilverConstruction.sv b/test/silver_construction/SilverConstruction.sv index a921043a9..665d14768 100644 --- a/test/silver_construction/SilverConstruction.sv +++ b/test/silver_construction/SilverConstruction.sv @@ -14,12 +14,12 @@ silver:compiler:definition:core:Expr ::= v1::Boolean return if v1 then Silver_Expr {true} else Silver_Expr {false}; } -equalityTest(hackUnparse(testExprBool(true)), "silver:compiler:definition:core:trueConst('true')", String, silver_construction_tests); -equalityTest(hackUnparse(testExprBool(false)), "silver:compiler:definition:core:falseConst('false')", String, silver_construction_tests); +equalityTest(genericShow(testExprBool(true)), "silver:compiler:definition:core:Expr { true }", String, silver_construction_tests); +equalityTest(genericShow(testExprBool(false)), "silver:compiler:definition:core:Expr { false }", String, silver_construction_tests); -equalityTest(hackUnparse(Silver_Expr{1}), "silver:compiler:definition:core:intConst('1')", String, silver_construction_tests); -equalityTest(hackUnparse(Silver_Expr{1.343}), "silver:compiler:definition:core:floatConst('1.343')", String, silver_construction_tests); -equalityTest(hackUnparse(Silver_Expr{[dog, doggy, doggies]}), "silver:compiler:modification:list:fullList('[', silver:compiler:definition:core:exprsCons(silver:compiler:definition:core:baseExpr(silver:compiler:definition:core:qNameId(silver:compiler:definition:core:nameIdLower('dog'))), ',', silver:compiler:definition:core:exprsCons(silver:compiler:definition:core:baseExpr(silver:compiler:definition:core:qNameId(silver:compiler:definition:core:nameIdLower('doggy'))), ',', silver:compiler:definition:core:exprsSingle(silver:compiler:definition:core:baseExpr(silver:compiler:definition:core:qNameId(silver:compiler:definition:core:nameIdLower('doggies')))))), ']')", String, silver_construction_tests); +equalityTest(genericShow(Silver_Expr{1}), "silver:compiler:definition:core:Expr { 1 }", String, silver_construction_tests); +equalityTest(genericShow(Silver_Expr{1.343}), "silver:compiler:definition:core:Expr { 1.343 }", String, silver_construction_tests); +equalityTest(genericShow(Silver_Expr{[dog, doggy, doggies]}), "silver:compiler:definition:core:Expr { [ dog, doggy, doggies ] }", String, silver_construction_tests); -- TESTING Silver_Pattern @@ -31,16 +31,16 @@ Pattern ::= v1::Boolean v2::Boolean return Silver_Pattern { silver:core:pair(fst=$Pattern{a}, fst=$Pattern{b}) }; } -equalityTest(hackUnparse(testPatternBools(true, true)), "silver:compiler:extension:patternmatching:propAppPattern_onlyNamed(silver:compiler:definition:core:qNameCons(silver:compiler:definition:core:nameIdLower('silver'), ':', silver:compiler:definition:core:qNameCons(silver:compiler:definition:core:nameIdLower('core'), ':', silver:compiler:definition:core:qNameId(silver:compiler:definition:core:nameIdLower('pair')))), '(', silver:compiler:extension:patternmatching:namedPatternList_more(silver:compiler:extension:patternmatching:namedPattern(silver:compiler:definition:core:qNameId(silver:compiler:definition:core:nameIdLower('fst')), '=', silver:compiler:extension:patternmatching:truePattern('true')), ',', silver:compiler:extension:patternmatching:namedPatternList_one(silver:compiler:extension:patternmatching:namedPattern(silver:compiler:definition:core:qNameId(silver:compiler:definition:core:nameIdLower('fst')), '=', silver:compiler:extension:patternmatching:truePattern('true')))), ')')", String, silver_construction_tests); -equalityTest(hackUnparse(testPatternBools(false, true)), "silver:compiler:extension:patternmatching:propAppPattern_onlyNamed(silver:compiler:definition:core:qNameCons(silver:compiler:definition:core:nameIdLower('silver'), ':', silver:compiler:definition:core:qNameCons(silver:compiler:definition:core:nameIdLower('core'), ':', silver:compiler:definition:core:qNameId(silver:compiler:definition:core:nameIdLower('pair')))), '(', silver:compiler:extension:patternmatching:namedPatternList_more(silver:compiler:extension:patternmatching:namedPattern(silver:compiler:definition:core:qNameId(silver:compiler:definition:core:nameIdLower('fst')), '=', silver:compiler:extension:patternmatching:falsePattern('false')), ',', silver:compiler:extension:patternmatching:namedPatternList_one(silver:compiler:extension:patternmatching:namedPattern(silver:compiler:definition:core:qNameId(silver:compiler:definition:core:nameIdLower('fst')), '=', silver:compiler:extension:patternmatching:truePattern('true')))), ')')", String, silver_construction_tests); +equalityTest(genericShow(testPatternBools(true, true)), "silver:compiler:extension:patternmatching:Pattern { silver:core:pair(fst=true, fst=true) }", String, silver_construction_tests); +equalityTest(genericShow(testPatternBools(false, true)), "silver:compiler:extension:patternmatching:Pattern { silver:core:pair(fst=false, fst=true) }", String, silver_construction_tests); -equalityTest(hackUnparse(Silver_Pattern {8}), "silver:compiler:extension:patternmatching:intPattern('8')", String, silver_construction_tests); -equalityTest(hackUnparse(Silver_Pattern {8.99999}), "silver:compiler:extension:patternmatching:fltPattern('8.99999')", String, silver_construction_tests); -equalityTest(hackUnparse(Silver_Pattern {[a,b,c]}), "silver:compiler:extension:patternmatching:listPattern('[', silver:compiler:extension:patternmatching:patternList_snoc(silver:compiler:extension:patternmatching:patternList_snoc(silver:compiler:extension:patternmatching:patternList_one(silver:compiler:extension:patternmatching:varPattern(silver:compiler:definition:core:nameIdLower('a'))), ',', silver:compiler:extension:patternmatching:varPattern(silver:compiler:definition:core:nameIdLower('b'))), ',', silver:compiler:extension:patternmatching:varPattern(silver:compiler:definition:core:nameIdLower('c'))), ']')", String, silver_construction_tests); +equalityTest(genericShow(Silver_Pattern {8}), "silver:compiler:extension:patternmatching:Pattern { 8 }", String, silver_construction_tests); +equalityTest(genericShow(Silver_Pattern {8.99999}), "silver:compiler:extension:patternmatching:Pattern { 8.99999 }", String, silver_construction_tests); +equalityTest(genericShow(Silver_Pattern {[a,b,c]}), "silver:compiler:extension:patternmatching:Pattern { [a, b, c] }", String, silver_construction_tests); -- TESTING Silver_TypeExpr -equalityTest(hackUnparse(Silver_TypeExpr { Boolean }), "silver:compiler:definition:type:syntax:booleanTypeExpr('Boolean')", String, silver_construction_tests); -equalityTest(hackUnparse(Silver_TypeExpr { Integer }), "silver:compiler:definition:type:syntax:integerTypeExpr('Integer')", String, silver_construction_tests); -equalityTest(hackUnparse(Silver_TypeExpr { Float }), "silver:compiler:definition:type:syntax:floatTypeExpr('Float')", String, silver_construction_tests); -equalityTest(hackUnparse(Silver_TypeExpr {Pair }), "silver:compiler:definition:type:syntax:appTypeExpr(silver:compiler:definition:type:syntax:nominalTypeExpr(silver:compiler:definition:core:qNameTypeId('Pair')), silver:compiler:definition:type:syntax:bTypeList('<', silver:compiler:definition:type:syntax:typeListCons(silver:compiler:definition:type:syntax:stringTypeExpr('String'), silver:compiler:definition:type:syntax:typeListSingle(silver:compiler:definition:type:syntax:integerTypeExpr('Integer'))), '>'))", String, silver_construction_tests); -equalityTest (hackUnparse(Silver_TypeExpr { [Integer] }), "silver:compiler:modification:list:listTypeExpr('[', silver:compiler:definition:type:syntax:integerTypeExpr('Integer'), ']')", String, silver_construction_tests); +equalityTest(genericShow(Silver_TypeExpr { Boolean }), "silver:compiler:definition:type:syntax:TypeExpr { Boolean }", String, silver_construction_tests); +equalityTest(genericShow(Silver_TypeExpr { Integer }), "silver:compiler:definition:type:syntax:TypeExpr { Integer }", String, silver_construction_tests); +equalityTest(genericShow(Silver_TypeExpr { Float }), "silver:compiler:definition:type:syntax:TypeExpr { Float }", String, silver_construction_tests); +equalityTest(genericShow(Silver_TypeExpr {Pair }), "silver:compiler:definition:type:syntax:TypeExpr { Pair }", String, silver_construction_tests); +equalityTest (genericShow(Silver_TypeExpr { [Integer] }), "silver:compiler:definition:type:syntax:TypeExpr { [Integer] }", String, silver_construction_tests); diff --git a/test/silver_features/Reflection.sv b/test/silver_features/Reflection.sv index caffb9ad5..c9683b5b9 100644 --- a/test/silver_features/Reflection.sv +++ b/test/silver_features/Reflection.sv @@ -3,8 +3,6 @@ import silver:reflect; import silver:langutil; import silver:langutil:pp; --- TODO: Actually make hackUnparse work like this. --- Not possible for now because core shouldn't depend on anything else. function lessHackyUnparse String ::= x::a { diff --git a/test/silver_features/Tuple.sv b/test/silver_features/Tuple.sv index 61b76fbde..f985d8cc7 100644 --- a/test/silver_features/Tuple.sv +++ b/test/silver_features/Tuple.sv @@ -90,7 +90,7 @@ equalityTest(studentGPAMatch(("Student1", true, (2020, 3.45))), 3.45, Float, sil equalityTest(studentGPAMatch(("Student2", false, (2020, 2.96))), 2.96, Float, silver_tests); -- Empty tuple -equalityTest(hackUnparse(()), "silver:core:unit()", String, silver_tests); +equalityTest(genericShow(()), "silver:core:unit()", String, silver_tests); function emptyTupleTest Boolean ::= tuple::() @@ -126,7 +126,7 @@ function makeDate return (day, month, year); } -equalityTest(hackUnparse(makeDate(1, 12, 2021)), "silver:core:pair(silver:core:fst=1, silver:core:snd=silver:core:pair(silver:core:fst=12, silver:core:snd=2021))", String, silver_tests); +equalityTest(genericShow(makeDate(1, 12, 2021)), "silver:core:pair(silver:core:fst=1, silver:core:snd=silver:core:pair(silver:core:fst=12, silver:core:snd=2021))", String, silver_tests); function temp String ::= diff --git a/test/silver_features/TypeClasses.sv b/test/silver_features/TypeClasses.sv index a5433872d..5452161cb 100644 --- a/test/silver_features/TypeClasses.sv +++ b/test/silver_features/TypeClasses.sv @@ -248,7 +248,7 @@ equalityTest(myfmap(\ x::Integer -> toFloat(x), left("abc")).fromLeft, "abc", St equalityTest(myfmap(\ x::Integer -> toFloat(x), let e::Either = right(42) in e end).fromRight, 42.0, Float, silver_tests); wrongCode "Ambiguous type variable a (arising from the use of myfmap) prevents the constraint silver_features:MyFunctor silver:core:Either from being solved" { - global ambRes::String = hackUnparse(myfmap(\ x::Integer -> toFloat(x), right(42)).fromRight); + global ambRes::String = genericShow(myfmap(\ x::Integer -> toFloat(x), right(42)).fromRight); } wrongCode "Either has kind * -> * -> *, but the class MyFunctor expected kind * -> *" { @@ -283,7 +283,7 @@ instance AmbInst Float { } wrongCode "Ambiguous type variable a (arising from the use of ambval) prevents the constraint silver_features:AmbInst a from being solved." { - global ambStr::String = hackUnparse(ambval); + global ambStr::String = genericShow(ambval); } global intIsEqual::(Boolean ::= Integer Integer) = myeq; diff --git a/test/stdlib/NativeSerialize.sv b/test/stdlib/NativeSerialize.sv index a72fa4684..2cc957b24 100644 --- a/test/stdlib/NativeSerialize.sv +++ b/test/stdlib/NativeSerialize.sv @@ -20,10 +20,10 @@ global val1 :: NSNT = ns_bar(ns_foo(1, 0.5, false, "AAA", terminal(NSTerm_t, "zz ["garfield", "odie", "nermal"], thingy=2442); global ser1 :: Either = nativeSerialize(val1); global des1 :: Either = if ser1.isRight then nativeDeserialize(ser1.fromRight) else left(ser1.fromLeft); -global fin1 :: String = if des1.isRight then hackUnparse(des1.fromRight) else des1.fromLeft; +global fin1 :: String = if des1.isRight then genericShow(des1.fromRight) else des1.fromLeft; equalityTest( - hackUnparse(val1), fin1, + genericShow(val1), fin1, String, core_tests); @@ -31,10 +31,10 @@ equalityTest( global val2 :: [Integer] = [111, 222, 333]; global ser2 :: Either = nativeSerialize(val2); global des2 :: Either = if ser2.isRight then nativeDeserialize(ser2.fromRight) else left(ser2.fromLeft); -global fin2 :: String = if des2.isRight then hackUnparse(des2.fromRight) else des2.fromLeft; +global fin2 :: String = if des2.isRight then genericShow(des2.fromRight) else des2.fromLeft; equalityTest( - hackUnparse(val2), fin2, + genericShow(val2), fin2, String, core_tests); @@ -42,7 +42,7 @@ equalityTest( global val3 :: [Integer] = [111, 222, 333]; global ser3 :: Either = nativeSerialize(val3); global des3 :: Either = if ser3.isRight then nativeDeserialize(ser3.fromRight) else left(ser3.fromLeft); -global fin3 :: String = if des3.isRight then hackUnparse(des3.fromRight) else des3.fromLeft; +global fin3 :: String = if des3.isRight then genericShow(des3.fromRight) else des3.fromLeft; equalityTest( "nativeDeserialize is constructing [String], but found [Integer]", fin3, @@ -52,10 +52,10 @@ equalityTest( global val4 :: [Integer] = repeat(123, 65537); -- Test long lists global ser4 :: Either = nativeSerialize(val4); global des4 :: Either = if ser4.isRight then nativeDeserialize(ser4.fromRight) else left(ser4.fromLeft); -global fin4 :: String = if des4.isRight then hackUnparse(des4.fromRight) else des4.fromLeft; +global fin4 :: String = if des4.isRight then genericShow(des4.fromRight) else des4.fromLeft; equalityTest( - hackUnparse(val4), fin4, + genericShow(val4), fin4, String, core_tests); @@ -64,5 +64,5 @@ global bytefiletest::IO = do { readBinaryFile("test_svb.svb"); }; -equalityTest(hackUnparse(nativeDeserialize(evalIO(bytefiletest, unsafeIO()).iovalue).fromRight), hackUnparse(val1), +equalityTest(genericShow(nativeDeserialize(evalIO(bytefiletest, unsafeIO()).iovalue).fromRight), genericShow(val1), String, core_tests); From 98e5a57d4939626a064b29b6d39ff6ea929fa690 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 30 Oct 2023 15:57:15 -0500 Subject: [PATCH 091/283] Fix flow errors --- grammars/silver/compiler/definition/core/Expr.sv | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index 7af7efc6a..51ef40806 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -264,7 +264,7 @@ top::Expr ::= q::'forward' concrete production application top::Expr ::= e::Expr '(' es::AppExprs ',' anns::AnnoAppExprs ')' { - top.unparse = e.unparse ++ "(" ++ es.unparse ++ (if null(es.exprs) || null(anns.exprs) then "" else ", ") ++ anns.unparse ++ ")"; + top.unparse = e.unparse ++ "(" ++ es.unparse ++ (if es.appExprSize > 0 && anns.appExprSize > 0 then ", " else "") ++ anns.unparse ++ ")"; propagate config, grammarName, env, freeVars, frame, originRules, compiledGrammars; e.isRoot = false; @@ -1071,7 +1071,7 @@ top::AppExprs ::= tracked nonterminal AnnoAppExprs with config, grammarName, env, unparse, errors, freeVars, frame, compiledGrammars, - isPartial, appExprApplied, exprs, + isPartial, appExprApplied, exprs, appExprSize, remainingFuncAnnotations, funcAnnotations, missingAnnotations, partialAnnoTypereps, annoIndexConverted, annoIndexSupplied, originRules; tracked nonterminal AnnoExpr with @@ -1139,6 +1139,7 @@ top::AnnoAppExprs ::= es::AnnoAppExprs ',' e::AnnoExpr top.unparse = es.unparse ++ ", " ++ e.unparse; top.isPartial = es.isPartial || e.isPartial; + top.appExprSize = 1 + es.appExprSize; e.remainingFuncAnnotations = top.remainingFuncAnnotations; es.remainingFuncAnnotations = e.missingAnnotations; @@ -1155,6 +1156,7 @@ top::AnnoAppExprs ::= e::AnnoExpr top.unparse = e.unparse; top.isPartial = e.isPartial; + top.appExprSize = 1; top.errors <- if null(top.missingAnnotations) then [] else [errFromOrigin(top, "Missing named parameters for function '" ++ top.appExprApplied ++ "': " @@ -1174,6 +1176,7 @@ top::AnnoAppExprs ::= top.unparse = ""; top.isPartial = false; + top.appExprSize = 0; top.errors <- if null(top.missingAnnotations) then [] else [errFromOrigin(top, "Missing named parameters for function '" ++ top.appExprApplied ++ "': " From dc02b97008ed77d53f52b047fb4e0402e865c457 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 30 Oct 2023 16:20:02 -0500 Subject: [PATCH 092/283] Fix remaining flow errors --- .../silver/compiler/extension/patternmatching/Case.sv | 7 ++++++- .../compiler/extension/patternmatching/PatternTypes.sv | 8 ++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/grammars/silver/compiler/extension/patternmatching/Case.sv b/grammars/silver/compiler/extension/patternmatching/Case.sv index 71cc1d9d5..9fb2ecd9d 100644 --- a/grammars/silver/compiler/extension/patternmatching/Case.sv +++ b/grammars/silver/compiler/extension/patternmatching/Case.sv @@ -47,8 +47,10 @@ synthesized attribute expandHeadPattern :: (AbstractMatchRule ::= [String]); -- For completeness checking, we need to know if we have a condition synthesized attribute hasCondition::Boolean; +synthesized attribute count::Integer; + -- P , ... -tracked nonterminal PatternList with config, unparse, patternList, env, frame, errors, patternVars, patternVarEnv; +tracked nonterminal PatternList with config, unparse, count, patternList, env, frame, errors, patternVars, patternVarEnv; propagate config, frame, env, errors on PatternList; -- Turns PatternList into [Pattern] @@ -1152,6 +1154,7 @@ concrete production patternList_one top::PatternList ::= p::Pattern { top.unparse = p.unparse; + top.count = 1; top.patternVars = p.patternVars; p.patternVarEnv = top.patternVarEnv; @@ -1169,6 +1172,7 @@ abstract production patternList_more top::PatternList ::= p::Pattern ',' ps1::PatternList { top.unparse = p.unparse ++ (if ps1.unparse == "" then "" else ", " ++ ps1.unparse); + top.count = 1 + ps1.count; top.patternVars = p.patternVars ++ ps1.patternVars; p.patternVarEnv = top.patternVarEnv; @@ -1182,6 +1186,7 @@ concrete production patternList_nil top::PatternList ::= { top.unparse = ""; + top.count = 0; top.patternVars = []; top.patternList = []; diff --git a/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv b/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv index 3014822ae..0ead2fc0d 100644 --- a/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv +++ b/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv @@ -6,6 +6,7 @@ import silver:compiler:modification:list only LSqr_t, RSqr_t; - The forms of syntactic patterns that are permissible in (nested) case expresssions. -} tracked nonterminal Pattern with config, unparse, env, frame, errors, patternVars, patternVarEnv, patternIsVariable, patternVariableName, patternSubPatternList, patternNamedSubPatternList, patternSortKey, isPrimitivePattern, isBoolPattern, isListPattern, patternTypeName; +flowtype Pattern = unparse {}; propagate config, frame, env, errors on Pattern; {-- @@ -70,7 +71,7 @@ synthesized attribute patternTypeName::String; concrete production prodAppPattern_named top::Pattern ::= prod::QName '(' ps::PatternList ',' nps::NamedPatternList ')' { - top.unparse = prod.unparse ++ "(" ++ ps.unparse ++ (if !null(ps.patternList) && !null(nps.namedPatternList) then ", " else "") ++ nps.unparse ++ ")"; + top.unparse = prod.unparse ++ "(" ++ ps.unparse ++ (if ps.count > 0 && nps.count > 0 then ", " else "") ++ nps.unparse ++ ")"; local parms :: Integer = prod.lookupValue.typeScheme.arity; @@ -337,13 +338,14 @@ top::PatternList ::= synthesized attribute namedPatternList::[Pair]; -tracked nonterminal NamedPatternList with config, unparse, frame, env, errors, patternVars, patternVarEnv, namedPatternList; +tracked nonterminal NamedPatternList with config, unparse, count, frame, env, errors, patternVars, patternVarEnv, namedPatternList; propagate config, frame, env, errors on NamedPatternList; concrete production namedPatternList_one top::NamedPatternList ::= p::NamedPattern { top.unparse = p.unparse; + top.count = 1; top.patternVars = p.patternVars; p.patternVarEnv = top.patternVarEnv; @@ -353,6 +355,7 @@ concrete production namedPatternList_more top::NamedPatternList ::= p::NamedPattern ',' ps::NamedPatternList { top.unparse = p.unparse ++ ", " ++ ps.unparse; + top.count = 1 + ps.count; top.patternVars = p.patternVars ++ ps.patternVars; p.patternVarEnv = top.patternVarEnv; @@ -365,6 +368,7 @@ abstract production namedPatternList_nil top::NamedPatternList ::= { top.unparse = ""; + top.count = 0; top.patternVars = []; top.namedPatternList = []; From adc4613b9f595e270ffe1ca6b9656935f541cf9e Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 1 Nov 2023 08:14:29 -0500 Subject: [PATCH 093/283] Implement reflective unparse with layout --- grammars/silver/langutil/unparse/Unparse.sv | 97 +++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 grammars/silver/langutil/unparse/Unparse.sv diff --git a/grammars/silver/langutil/unparse/Unparse.sv b/grammars/silver/langutil/unparse/Unparse.sv new file mode 100644 index 000000000..910e0c96e --- /dev/null +++ b/grammars/silver/langutil/unparse/Unparse.sv @@ -0,0 +1,97 @@ +grammar silver:langutil:unparse; + +imports silver:reflect:util; +imports silver:langutil; + +function unparse +String ::= origText::String x::a +{ + local ast::AST = reflect(x); + ast.origText = origText; + ast.parseTree = just(getParseTree(x)); + local astLoc::Location = ast.matchingOriginLoc.fromJust; + return + substring(0, astLoc.index, origText) ++ + ast.unparseWithLayout ++ + substring(astLoc.endIndex, length(origText), origText); +} + +function getParseTree +AST ::= ast::a +{ + return + case getOriginInfo(ast) of + | just(parsedOriginInfo(l)) -> reflect(ast) + | just(originOriginInfo(o, _)) -> getParseTree(o) + | just(originAndRedexOriginInfo(o, _, _, _)) -> getParseTree(o) + | _ -> error("Tree does not have a parsed origin: " ++ showOriginInfoChain(ast)) + end; +} + +synthesized attribute unparseWithLayout::String occurs on AST, ASTs; +synthesized attribute matchingOriginLoc::Maybe occurs on AST; + +inherited attribute origText::String occurs on AST, ASTs; +propagate origText on AST, ASTs; + +inherited attribute parseTree::Maybe; +attribute parseTree occurs on AST; +attribute parseTree occurs on ASTs; + +aspect default production +top::AST ::= +{ + top.unparseWithLayout = error("Can't unparse " ++ genericShow(top)); + top.matchingOriginLoc = nothing(); +} + +aspect production nonterminalAST +top::AST ::= prodName::String children::ASTs annotations::NamedASTs +{ + top.unparseWithLayout = children.unparseWithLayout; + top.matchingOriginLoc = bind(top.parseTree, getParsedOriginLocation); + children.parseTree = + case fromMaybe(getParseTree(top), top.parseTree) of + | nonterminalAST(p, c, _) when prodName == p -> just(c) + | _ -> nothing() + end; +} + +aspect production terminalAST +top::AST ::= terminalName::String lexeme::String location::Location +{ + top.unparseWithLayout = lexeme; + top.matchingOriginLoc = just(location); +} + +aspect production consAST +top::ASTs ::= h::AST t::ASTs +{ + top.unparseWithLayout = + h.unparseWithLayout ++ + case t of + | consAST(h2, _) -> + case h.matchingOriginLoc, h2.matchingOriginLoc of + | just(l1), just(l2) -> substring(l1.endIndex, l2.index, top.origText) + | _, _ -> "" + end + | nilAST() -> "" + end ++ + t.unparseWithLayout; + h.parseTree = + case top.parseTree of + | just(consAST(a, _)) -> just(a) + | _ -> nothing() + end; + t.parseTree = + case top.parseTree of + | just(consAST(_, a)) -> just(a) + | _ -> nothing() + end; +} + +aspect production nilAST +top::ASTs ::= +{ + top.unparseWithLayout = ""; +} From 4ba0f64f78e4ffe9c62a68f48eacd5df43af7e1f Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 1 Nov 2023 08:14:55 -0500 Subject: [PATCH 094/283] Initial implementation of refactoring framework --- grammars/silver/compiler/host/Project.sv | 1 + .../silver/compiler/refactor/BuildProcess.sv | 71 +++++++++++++++++++ grammars/silver/compiler/refactor/RootSpec.sv | 15 ++++ .../silver/compiler/refactor/Transforms.sv | 67 +++++++++++++++++ 4 files changed, 154 insertions(+) create mode 100644 grammars/silver/compiler/refactor/BuildProcess.sv create mode 100644 grammars/silver/compiler/refactor/RootSpec.sv create mode 100644 grammars/silver/compiler/refactor/Transforms.sv diff --git a/grammars/silver/compiler/host/Project.sv b/grammars/silver/compiler/host/Project.sv index e6f6d3751..fb4b86fd4 100644 --- a/grammars/silver/compiler/host/Project.sv +++ b/grammars/silver/compiler/host/Project.sv @@ -57,3 +57,4 @@ exports silver:compiler:driver; exports silver:compiler:analysis:warnings:flow; exports silver:compiler:analysis:warnings:exporting; exports silver:compiler:langserver; +exports silver:compiler:refactor; diff --git a/grammars/silver/compiler/refactor/BuildProcess.sv b/grammars/silver/compiler/refactor/BuildProcess.sv new file mode 100644 index 000000000..c24b2c038 --- /dev/null +++ b/grammars/silver/compiler/refactor/BuildProcess.sv @@ -0,0 +1,71 @@ +grammar silver:compiler:refactor; + +import silver:compiler:driver; +import silver:compiler:translation:java:driver; +import silver:compiler:definition:env; +import silver:compiler:definition:core; + +import silver:util:cmdargs; + +import silver:langutil:unparse; + +synthesized attribute doRefactor :: Boolean occurs on CmdArgs; + +aspect production endCmdArgs +top::CmdArgs ::= _ +{ + top.doRefactor = false; +} +abstract production refactorFlag +top::CmdArgs ::= rest::CmdArgs +{ + top.doRefactor = true; + top.noBindingChecking = true; + top.noJavaGeneration = true; + forwards to @rest; +} + +aspect function parseArgs +Either ::= args::[String] +{ + flags <- [ flagSpec(name="--refactor", paramString=nothing(), + help="Apply a transformation to the Silver specification", + flagParser=flag(refactorFlag)) + ]; +} +aspect production compilation +top::Compilation ::= g::Grammars _ buildGrammars::[String] benv::BuildEnv +{ + top.postOps <- + if top.config.doRefactor + then [doRefactor(top.config, grammarsRelevant)] + else []; +} + +abstract production doRefactor +top::DriverAction ::= a::Decorated CmdArgs specs::[Decorated RootSpec] +{ + top.run = do { + eprintln("Applying Refactoring."); + traverse_(refactorSpec, specs); + return 0; + }; + top.order = 4; +} + +function refactorSpec +IO<()> ::= r::Decorated RootSpec +{ + return do { + eprintln("\t[" ++ r.declaredName ++ "]"); + traverse_(\ item::(String, Root) -> + when_(!endsWith(".md", item.1), -- TODO: Make this work with literate Silver files + do { + let fullPath::String = r.grammarSource ++ item.1; + text::String <- readFile(fullPath); + let newText::String = unparse(text, item.2); + writeFile(fullPath, newText); + }), + r.transformedFiles); + }; +} diff --git a/grammars/silver/compiler/refactor/RootSpec.sv b/grammars/silver/compiler/refactor/RootSpec.sv new file mode 100644 index 000000000..a9b942dc9 --- /dev/null +++ b/grammars/silver/compiler/refactor/RootSpec.sv @@ -0,0 +1,15 @@ +grammar silver:compiler:refactor; + +import silver:compiler:driver:util; + +monoid attribute transformedFiles::[(String, Root)] occurs on RootSpec, Grammar; +propagate transformedFiles on RootSpec, Grammar; + +aspect production consGrammar +top::Grammar ::= h::Root t::Grammar +{ + top.transformedFiles <- [ + (getParsedOriginLocation(h).fromJust.filename, + rewriteWith(topDown(try(h.transforms)), new(h)).fromJust) + ]; +} diff --git a/grammars/silver/compiler/refactor/Transforms.sv b/grammars/silver/compiler/refactor/Transforms.sv new file mode 100644 index 000000000..f9cde35c3 --- /dev/null +++ b/grammars/silver/compiler/refactor/Transforms.sv @@ -0,0 +1,67 @@ +grammar silver:compiler:refactor; + +imports silver:compiler:definition:core; +imports silver:compiler:definition:concrete_syntax; +imports silver:compiler:definition:type:syntax; +imports silver:compiler:definition:flow:syntax; + +imports silver:compiler:modification:let_fix; +imports silver:compiler:modification:lambda_fn; +imports silver:compiler:modification:collection; +imports silver:compiler:modification:primitivepattern; +imports silver:compiler:modification:ffi; +imports silver:compiler:modification:copper; +imports silver:compiler:modification:defaultattr; +imports silver:compiler:modification:list; +imports silver:compiler:modification:copper_mda; + +imports silver:rewrite; + +monoid attribute transforms::Strategy with fail(), choice; + +attribute transforms occurs on + Root, AGDcls, AGDcl, + ProductionModifiers, ProductionModifierList, TerminalModifiers, + AspectProductionSignature, AspectProductionLHS, AspectFunctionSignature, AspectFunctionLHS, AspectRHS, AspectRHSElem, + ClassBody, ClassBodyItem, + Expr, Exprs, ExprInhs, ExprInh, ExprLHSExpr, AppExprs, AppExpr, AnnoAppExprs, AnnoExpr, + FunctionSignature, FunctionLHS, + InstanceBody, InstanceBodyItem, + ModuleStmts, ModuleStmt, ImportStmt, ImportStmts, ModuleExpr, ModuleName, NameList, WithElems, WithElem, Module, ModuleExportedDefs, + Name, + NTDeclQualifiers, NonterminalModifiers, NonterminalModifierList, + ProductionBody, ProductionStmts, ProductionStmt, DefLHS, ForwardInhs, ForwardInh, ForwardLHSExpr, + ProductionSignature, ProductionLHS, ProductionRHS, ProductionRHSElem, + QName, QNameType, QNameAttrOccur, GrammarDcl, + FlowSpecs, FlowSpec, FlowSpecId, FlowSpecInhs, FlowSpecInh, NtList, NtName, + ConstraintList, Constraint, KindExpr, TypeExpr, + Signature, SignatureLHS, TypeExprs, BracketedTypeExprs, BracketedOptTypeExprs, NamedTypeExprs, + NameOrBOperator, + LexerClassModifiers, ParserComponents, ParserComponentModifiers, ParserComponentModifier, + TerminalPrefix, TerminalPrefixItems, TerminalPrefixItem, + TermList, TermPrecs, TermPrecList, LexerClasses, LexerClassList, + AspectDefaultProductionSignature, FFIDefs, FFIDef, + AssignExpr, PrimPatterns, PrimPattern, VarBinders, VarBinder; +propagate transforms on + Root, AGDcls, AGDcl, + ProductionModifiers, ProductionModifierList, TerminalModifiers, + AspectProductionSignature, AspectProductionLHS, AspectFunctionSignature, AspectFunctionLHS, AspectRHS, AspectRHSElem, + ClassBody, ClassBodyItem, + Expr, Exprs, ExprInhs, ExprInh, ExprLHSExpr, AppExprs, AppExpr, AnnoAppExprs, AnnoExpr, + FunctionSignature, FunctionLHS, + InstanceBody, InstanceBodyItem, + ModuleStmts, ModuleStmt, ImportStmt, ImportStmts, ModuleExpr, ModuleName, NameList, WithElems, WithElem, Module, ModuleExportedDefs, + Name, + NTDeclQualifiers, NonterminalModifiers, NonterminalModifierList, + ProductionBody, ProductionStmts, ProductionStmt, DefLHS, ForwardInhs, ForwardInh, ForwardLHSExpr, + ProductionSignature, ProductionLHS, ProductionRHS, ProductionRHSElem, + QName, QNameType, QNameAttrOccur, GrammarDcl, + FlowSpecs, FlowSpec, FlowSpecId, FlowSpecInhs, FlowSpecInh, NtList, NtName, + ConstraintList, Constraint, KindExpr, TypeExpr, + Signature, SignatureLHS, TypeExprs, BracketedTypeExprs, BracketedOptTypeExprs, NamedTypeExprs, + NameOrBOperator, + LexerClassModifiers, ParserComponents, ParserComponentModifiers, ParserComponentModifier, + TerminalPrefix, TerminalPrefixItems, TerminalPrefixItem, + TermList, TermPrecs, TermPrecList, LexerClasses, LexerClassList, + AspectDefaultProductionSignature, FFIDefs, FFIDef, + AssignExpr, PrimPatterns, PrimPattern, VarBinders, VarBinder; From fce8fad8532caded8fd229d0306bb0297c765978 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 1 Nov 2023 08:20:32 -0500 Subject: [PATCH 095/283] Fold chained choice/sequence strategies --- grammars/silver/rewrite/Strategy.sv | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/grammars/silver/rewrite/Strategy.sv b/grammars/silver/rewrite/Strategy.sv index a4f8853bd..66a620823 100644 --- a/grammars/silver/rewrite/Strategy.sv +++ b/grammars/silver/rewrite/Strategy.sv @@ -32,7 +32,14 @@ top::Strategy ::= top.result = nothing(); } -abstract production sequence +global sequence::(Strategy ::= Strategy Strategy) = \ s1 s2 -> + case s1, s2 of + | id(), _ -> s2 + | _, id() -> s1 + | _, _ -> sequence_(s1, s2) + end; + +abstract production sequence_ top::Strategy ::= s1::Strategy s2::Strategy { top.pp = pp"(${s1.pp} <* ${s2.pp})"; @@ -41,7 +48,14 @@ top::Strategy ::= s1::Strategy s2::Strategy top.result = bind(s1.result, \ AST -> s2.result); } -abstract production choice +global choice::(Strategy ::= Strategy Strategy) = \ s1 s2 -> + case s1, s2 of + | fail(), _ -> s2 + | _, fail() -> s1 + | _, _ -> choice_(s1, s2) + end; + +abstract production choice_ top::Strategy ::= s1::Strategy s2::Strategy { top.pp = pp"(${s1.pp} <+ ${s2.pp})"; From 785119b5d69c6d0468cd0758757a2837a2509410 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 1 Nov 2023 09:25:20 -0500 Subject: [PATCH 096/283] Lambda RHS should be tracked --- grammars/silver/compiler/modification/lambda_fn/Lambda.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv index 0904b7a10..c06c8b933 100644 --- a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv +++ b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv @@ -54,12 +54,12 @@ top::Expr ::= params::LambdaRHS e::Expr } -nonterminal LambdaRHS with +tracked nonterminal LambdaRHS with givenLambdaParamIndex, givenLambdaId, env, grammarName, flowEnv, lambdaBoundVars, lambdaDefs, lexicalTypeVariables, lexicalTyVarKinds, inputElements, unparse, elementCount; -nonterminal LambdaRHSElem with +tracked nonterminal LambdaRHSElem with givenLambdaParamIndex, givenLambdaId, grammarName, deterministicCount, env, flowEnv, lambdaBoundVars, lambdaDefs, unparse, lexicalTypeVariables, inputElements, lexicalTyVarKinds; From f06109822d3755dd5439a090c0e698822f7d73b9 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 1 Nov 2023 09:25:37 -0500 Subject: [PATCH 097/283] Better errors and comments --- grammars/silver/langutil/unparse/Unparse.sv | 30 ++++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/grammars/silver/langutil/unparse/Unparse.sv b/grammars/silver/langutil/unparse/Unparse.sv index 910e0c96e..8dadfa596 100644 --- a/grammars/silver/langutil/unparse/Unparse.sv +++ b/grammars/silver/langutil/unparse/Unparse.sv @@ -3,12 +3,26 @@ grammar silver:langutil:unparse; imports silver:reflect:util; imports silver:langutil; +@{-- + - Unparse a tree, preserving layout from its parse tree via origin tracking. + - The productions in the tree should only consist of nonterminal and terminal symbols; + - in a language with seperate concrete and abstract syntax, this may require defining a + - translation from abstract back to concrete syntax. + - + - This is intended for use in e.g. refactoring tools, where transformations can be applied + - on the tree, but one would like to turn the tree back into a string without affecting + - layout in otherwise-unchanged portions of the tree. + - + - @param origText The original text that was parsed to create the origin of tree. + - @param tree The concrete syntax tree to unparse. + - @return The unparse of the tree, with layout from origText inserted in unchanged portions of the tree. + -} function unparse -String ::= origText::String x::a +String ::= origText::String tree::a { - local ast::AST = reflect(x); + local ast::AST = reflect(tree); ast.origText = origText; - ast.parseTree = just(getParseTree(x)); + ast.parseTree = just(getParseTree(tree)); local astLoc::Location = ast.matchingOriginLoc.fromJust; return substring(0, astLoc.index, origText) ++ @@ -49,7 +63,15 @@ aspect production nonterminalAST top::AST ::= prodName::String children::ASTs annotations::NamedASTs { top.unparseWithLayout = children.unparseWithLayout; - top.matchingOriginLoc = bind(top.parseTree, getParsedOriginLocation); + top.matchingOriginLoc = do { + tree :: AST <- top.parseTree; + return + case getParsedOriginLocation(tree) of + | just(l) -> l + | nothing() -> + error("Tree does not have a parsed origin: " ++ showOriginInfoChain(tree)) + end; + }; children.parseTree = case fromMaybe(getParseTree(top), top.parseTree) of | nonterminalAST(p, c, _) when prodName == p -> just(c) From 7468be92892dfeb3c206ff7398bb1ac9a1fc54db Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 1 Nov 2023 09:27:05 -0500 Subject: [PATCH 098/283] Some restructuring, bug fixes --- grammars/silver/compiler/refactor/BuildProcess.sv | 14 +++++++++++--- grammars/silver/compiler/refactor/RootSpec.sv | 15 --------------- grammars/silver/compiler/refactor/Transforms.sv | 9 +++++++++ 3 files changed, 20 insertions(+), 18 deletions(-) delete mode 100644 grammars/silver/compiler/refactor/RootSpec.sv diff --git a/grammars/silver/compiler/refactor/BuildProcess.sv b/grammars/silver/compiler/refactor/BuildProcess.sv index c24b2c038..51dbaa96a 100644 --- a/grammars/silver/compiler/refactor/BuildProcess.sv +++ b/grammars/silver/compiler/refactor/BuildProcess.sv @@ -2,8 +2,6 @@ grammar silver:compiler:refactor; import silver:compiler:driver; import silver:compiler:translation:java:driver; -import silver:compiler:definition:env; -import silver:compiler:definition:core; import silver:util:cmdargs; @@ -20,6 +18,7 @@ abstract production refactorFlag top::CmdArgs ::= rest::CmdArgs { top.doRefactor = true; + top.doClean = true; top.noBindingChecking = true; top.noJavaGeneration = true; forwards to @rest; @@ -64,8 +63,17 @@ IO<()> ::= r::Decorated RootSpec let fullPath::String = r.grammarSource ++ item.1; text::String <- readFile(fullPath); let newText::String = unparse(text, item.2); - writeFile(fullPath, newText); + when_(text != newText, writeFile(fullPath, newText)); }), r.transformedFiles); }; } + +monoid attribute transformedFiles::[(String, Root)] occurs on RootSpec, Grammar; +propagate transformedFiles on RootSpec, Grammar; + +aspect production consGrammar +top::Grammar ::= h::Root t::Grammar +{ + top.transformedFiles <- [(getParsedOriginLocation(h).fromJust.filename, h.transformed)]; +} diff --git a/grammars/silver/compiler/refactor/RootSpec.sv b/grammars/silver/compiler/refactor/RootSpec.sv deleted file mode 100644 index a9b942dc9..000000000 --- a/grammars/silver/compiler/refactor/RootSpec.sv +++ /dev/null @@ -1,15 +0,0 @@ -grammar silver:compiler:refactor; - -import silver:compiler:driver:util; - -monoid attribute transformedFiles::[(String, Root)] occurs on RootSpec, Grammar; -propagate transformedFiles on RootSpec, Grammar; - -aspect production consGrammar -top::Grammar ::= h::Root t::Grammar -{ - top.transformedFiles <- [ - (getParsedOriginLocation(h).fromJust.filename, - rewriteWith(topDown(try(h.transforms)), new(h)).fromJust) - ]; -} diff --git a/grammars/silver/compiler/refactor/Transforms.sv b/grammars/silver/compiler/refactor/Transforms.sv index f9cde35c3..051c4980b 100644 --- a/grammars/silver/compiler/refactor/Transforms.sv +++ b/grammars/silver/compiler/refactor/Transforms.sv @@ -1,6 +1,7 @@ grammar silver:compiler:refactor; imports silver:compiler:definition:core; +imports silver:compiler:definition:env; imports silver:compiler:definition:concrete_syntax; imports silver:compiler:definition:type:syntax; imports silver:compiler:definition:flow:syntax; @@ -17,6 +18,14 @@ imports silver:compiler:modification:copper_mda; imports silver:rewrite; +synthesized attribute transformed::Root occurs on Root; + +aspect production root +top::Root ::= _ _ _ _ +{ + top.transformed = rewriteWith(topDown(try(top.transforms)), new(top)).fromJust; +} + monoid attribute transforms::Strategy with fail(), choice; attribute transforms occurs on From 3bad7f3ba5d5f5025e70bd10f3b3b78ba2b665b3 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 1 Nov 2023 16:23:40 -0500 Subject: [PATCH 099/283] Support for op overloads in rewrite rules --- .../compiler/extension/rewriting/Expr.sv | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index 22e32aeca..ce5f0dbb9 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -125,9 +125,9 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp case e, es of | productionReference(q), _ -> prodCallASTExpr(q.lookupValue.fullName, es.transform, anns.transform) - -- Special cases for efficiency, and workaround for type inference issues. - -- TODO: This doesn't work as expected when these operators are overloaded. - | classMemberReference(q), snocAppExprs(oneAppExprs(presentAppExpr(e1)), _, presentAppExpr(e2)) -> + -- Special cases for efficiency. + | classMemberReference(q), snocAppExprs(oneAppExprs(presentAppExpr(e1)), _, presentAppExpr(e2)) + when e1.finalType.isPrimitive -> case q.lookupValue.fullName of | "silver:core:conj" -> andASTExpr(e1.transform, e2.transform) | "silver:core:disj" -> orASTExpr(e1.transform, e2.transform) @@ -145,7 +145,8 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp | "silver:core:append" -> appendASTExpr(e1.transform, e2.transform) | _ -> applyASTExpr(e.transform, es.transform, anns.transform) end - | classMemberReference(q), oneAppExprs(presentAppExpr(e)) -> + | classMemberReference(q), oneAppExprs(presentAppExpr(e)) + when e.finalType.isPrimitive -> case q.lookupValue.fullName of | "silver:core:not" -> notASTExpr(e.transform) | "silver:core:negate" -> negASTExpr(e.transform) @@ -156,11 +157,26 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp | "silver:core:length" -> lengthASTExpr(e.transform) | _ -> applyASTExpr(e.transform, es.transform, anns.transform) end + | classMemberReference(q), oneAppExprs(presentAppExpr(e)) + when e.finalType matches appType(listCtrType(), _) -> + case q.lookupValue.fullName of + | "silver:core:length" -> lengthASTExpr(e.transform) + | _ -> applyASTExpr(e.transform, es.transform, anns.transform) + end | _, _ -> applyASTExpr(e.transform, es.transform, anns.transform) end; } +synthesized attribute isPrimitive::Boolean occurs on Type; +aspect isPrimitive on Type of +| intType() -> true +| floatType() -> true +| boolType() -> true +| stringType() -> true +| _ -> false +end; + aspect production partialApplication top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs { From 9eb48a73079f13f615e058ac48af423f84278727 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 1 Nov 2023 16:25:59 -0500 Subject: [PATCH 100/283] Example transform to insert new - working, but slow --- .../silver/compiler/refactor/BuildProcess.sv | 15 ++---- .../silver/compiler/refactor/ExplicitNew.sv | 52 +++++++++++++++++++ .../silver/compiler/refactor/Transforms.sv | 7 ++- 3 files changed, 60 insertions(+), 14 deletions(-) create mode 100644 grammars/silver/compiler/refactor/ExplicitNew.sv diff --git a/grammars/silver/compiler/refactor/BuildProcess.sv b/grammars/silver/compiler/refactor/BuildProcess.sv index 51dbaa96a..1eea9fa77 100644 --- a/grammars/silver/compiler/refactor/BuildProcess.sv +++ b/grammars/silver/compiler/refactor/BuildProcess.sv @@ -1,10 +1,9 @@ grammar silver:compiler:refactor; -import silver:compiler:driver; -import silver:compiler:translation:java:driver; - -import silver:util:cmdargs; +imports silver:util:cmdargs; +imports silver:compiler:driver; +import silver:compiler:translation:java:driver; import silver:langutil:unparse; synthesized attribute doRefactor :: Boolean occurs on CmdArgs; @@ -24,14 +23,6 @@ top::CmdArgs ::= rest::CmdArgs forwards to @rest; } -aspect function parseArgs -Either ::= args::[String] -{ - flags <- [ flagSpec(name="--refactor", paramString=nothing(), - help="Apply a transformation to the Silver specification", - flagParser=flag(refactorFlag)) - ]; -} aspect production compilation top::Compilation ::= g::Grammars _ buildGrammars::[String] benv::BuildEnv { diff --git a/grammars/silver/compiler/refactor/ExplicitNew.sv b/grammars/silver/compiler/refactor/ExplicitNew.sv new file mode 100644 index 000000000..593818f34 --- /dev/null +++ b/grammars/silver/compiler/refactor/ExplicitNew.sv @@ -0,0 +1,52 @@ +grammar silver:compiler:refactor; + +synthesized attribute refactorExplicitNew :: Boolean occurs on CmdArgs; + +aspect production endCmdArgs +top::CmdArgs ::= _ +{ + top.refactorExplicitNew = false; +} +abstract production refactorExplicitNewFlag +top::CmdArgs ::= rest::CmdArgs +{ + top.refactorExplicitNew = true; + forwards to refactorFlag(@rest); +} + +aspect function parseArgs +Either ::= args::[String] +{ + flags <- [ flagSpec(name="--refactor-explicit-new", paramString=nothing(), + help="Insert an explicit call to new() at all instances of implcit undecoration", + flagParser=flag(refactorExplicitNewFlag)) + ]; +} + +aspect production childReference +top::Expr ::= q::Decorated! QName +{ + top.transforms <- + if top.config.refactorExplicitNew + && isDecorable(q.lookupValue.typeScheme.monoType, top.env) && !top.finalType.isDecorated + then + rule on Expr of + | baseExpr(q1) when q1.name == q.name && q1.nameLoc == q.nameLoc -> + Silver_Expr { new($QName{q1}) } + end + else fail(); +} + +aspect production localReference +top::Expr ::= q::Decorated! QName +{ + top.transforms <- + if top.config.refactorExplicitNew + && isDecorable(q.lookupValue.typeScheme.monoType, top.env) && !top.finalType.isDecorated + then + rule on Expr of + | baseExpr(q1) when q1.name == q.name && q1.nameLoc == q.nameLoc -> + Silver_Expr { new($QName{q1}) } + end + else fail(); +} diff --git a/grammars/silver/compiler/refactor/Transforms.sv b/grammars/silver/compiler/refactor/Transforms.sv index 051c4980b..d2ab93dc4 100644 --- a/grammars/silver/compiler/refactor/Transforms.sv +++ b/grammars/silver/compiler/refactor/Transforms.sv @@ -1,11 +1,14 @@ grammar silver:compiler:refactor; imports silver:compiler:definition:core; +imports silver:compiler:definition:type; imports silver:compiler:definition:env; imports silver:compiler:definition:concrete_syntax; imports silver:compiler:definition:type:syntax; imports silver:compiler:definition:flow:syntax; +imports silver:compiler:analysis:typechecking:core; + imports silver:compiler:modification:let_fix; imports silver:compiler:modification:lambda_fn; imports silver:compiler:modification:collection; @@ -23,13 +26,13 @@ synthesized attribute transformed::Root occurs on Root; aspect production root top::Root ::= _ _ _ _ { - top.transformed = rewriteWith(topDown(try(top.transforms)), new(top)).fromJust; + top.transformed = rewriteWith(bottomUp(try(top.transforms)), new(top)).fromJust; } monoid attribute transforms::Strategy with fail(), choice; attribute transforms occurs on - Root, AGDcls, AGDcl, + Root, AGDcls, AGDcl, ProductionModifiers, ProductionModifierList, TerminalModifiers, AspectProductionSignature, AspectProductionLHS, AspectFunctionSignature, AspectFunctionLHS, AspectRHS, AspectRHSElem, ClassBody, ClassBodyItem, From 4e4ec0ed6b8610c5b4bb39a5a7bc4c6f78906172 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 1 Nov 2023 19:04:31 -0500 Subject: [PATCH 101/283] Performance fixes for refactoring, rewrite at AGDcl level --- .../silver/compiler/refactor/Transforms.sv | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/grammars/silver/compiler/refactor/Transforms.sv b/grammars/silver/compiler/refactor/Transforms.sv index d2ab93dc4..ad273a7ba 100644 --- a/grammars/silver/compiler/refactor/Transforms.sv +++ b/grammars/silver/compiler/refactor/Transforms.sv @@ -21,30 +21,33 @@ imports silver:compiler:modification:copper_mda; imports silver:rewrite; -synthesized attribute transformed::Root occurs on Root; +functor attribute transformed occurs on Root, AGDcls; +propagate transformed on Root; -aspect production root -top::Root ::= _ _ _ _ -{ - top.transformed = rewriteWith(bottomUp(try(top.transforms)), new(top)).fromJust; -} +aspect transformed on AGDcls of +| consAGDcls(h, t) -> consAGDcls( + case h.transforms of + | fail() -> new(h) + | ts -> rewriteWith(bottomUp(try(ts)), new(h)).fromJust + end, + t.transformed) +| nilAGDcls() -> nilAGDcls() +end; monoid attribute transforms::Strategy with fail(), choice; attribute transforms occurs on - Root, AGDcls, AGDcl, + AGDcl, ProductionModifiers, ProductionModifierList, TerminalModifiers, AspectProductionSignature, AspectProductionLHS, AspectFunctionSignature, AspectFunctionLHS, AspectRHS, AspectRHSElem, ClassBody, ClassBodyItem, Expr, Exprs, ExprInhs, ExprInh, ExprLHSExpr, AppExprs, AppExpr, AnnoAppExprs, AnnoExpr, FunctionSignature, FunctionLHS, InstanceBody, InstanceBodyItem, - ModuleStmts, ModuleStmt, ImportStmt, ImportStmts, ModuleExpr, ModuleName, NameList, WithElems, WithElem, Module, ModuleExportedDefs, - Name, + ModuleStmts, ModuleStmt, ImportStmt, ImportStmts, ModuleExpr, ModuleName, NameList, WithElems, WithElem, Module, NTDeclQualifiers, NonterminalModifiers, NonterminalModifierList, ProductionBody, ProductionStmts, ProductionStmt, DefLHS, ForwardInhs, ForwardInh, ForwardLHSExpr, ProductionSignature, ProductionLHS, ProductionRHS, ProductionRHSElem, - QName, QNameType, QNameAttrOccur, GrammarDcl, FlowSpecs, FlowSpec, FlowSpecId, FlowSpecInhs, FlowSpecInh, NtList, NtName, ConstraintList, Constraint, KindExpr, TypeExpr, Signature, SignatureLHS, TypeExprs, BracketedTypeExprs, BracketedOptTypeExprs, NamedTypeExprs, @@ -55,19 +58,16 @@ attribute transforms occurs on AspectDefaultProductionSignature, FFIDefs, FFIDef, AssignExpr, PrimPatterns, PrimPattern, VarBinders, VarBinder; propagate transforms on - Root, AGDcls, AGDcl, + AGDcl, ProductionModifiers, ProductionModifierList, TerminalModifiers, AspectProductionSignature, AspectProductionLHS, AspectFunctionSignature, AspectFunctionLHS, AspectRHS, AspectRHSElem, ClassBody, ClassBodyItem, Expr, Exprs, ExprInhs, ExprInh, ExprLHSExpr, AppExprs, AppExpr, AnnoAppExprs, AnnoExpr, FunctionSignature, FunctionLHS, InstanceBody, InstanceBodyItem, - ModuleStmts, ModuleStmt, ImportStmt, ImportStmts, ModuleExpr, ModuleName, NameList, WithElems, WithElem, Module, ModuleExportedDefs, - Name, NTDeclQualifiers, NonterminalModifiers, NonterminalModifierList, ProductionBody, ProductionStmts, ProductionStmt, DefLHS, ForwardInhs, ForwardInh, ForwardLHSExpr, ProductionSignature, ProductionLHS, ProductionRHS, ProductionRHSElem, - QName, QNameType, QNameAttrOccur, GrammarDcl, FlowSpecs, FlowSpec, FlowSpecId, FlowSpecInhs, FlowSpecInh, NtList, NtName, ConstraintList, Constraint, KindExpr, TypeExpr, Signature, SignatureLHS, TypeExprs, BracketedTypeExprs, BracketedOptTypeExprs, NamedTypeExprs, From 92ef2f21aa420fb573d8cbeaf3dd0176790459c1 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 1 Nov 2023 19:24:09 -0500 Subject: [PATCH 102/283] Strategy tweak for performance --- grammars/silver/compiler/refactor/Transforms.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/compiler/refactor/Transforms.sv b/grammars/silver/compiler/refactor/Transforms.sv index ad273a7ba..67e39a320 100644 --- a/grammars/silver/compiler/refactor/Transforms.sv +++ b/grammars/silver/compiler/refactor/Transforms.sv @@ -28,7 +28,7 @@ aspect transformed on AGDcls of | consAGDcls(h, t) -> consAGDcls( case h.transforms of | fail() -> new(h) - | ts -> rewriteWith(bottomUp(try(ts)), new(h)).fromJust + | ts -> rewriteWith(allTopDown(ts), new(h)).fromJust end, t.transformed) | nilAGDcls() -> nilAGDcls() From 63b2ef8601c75c3172ed299af4d7d831481fad35 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 1 Nov 2023 19:26:18 -0500 Subject: [PATCH 103/283] Insert explicit new in a few places --- grammars/silver/core/IO.sv | 4 ++-- grammars/silver/core/State.sv | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/grammars/silver/core/IO.sv b/grammars/silver/core/IO.sv index f93bc092b..9e99abb20 100644 --- a/grammars/silver/core/IO.sv +++ b/grammars/silver/core/IO.sv @@ -79,7 +79,7 @@ instance MonadFix IO { function runIO IOToken ::= st::IO ioIn::IOToken { - return evalIO(st, ioIn).io; + return evalIO(new(st), ioIn).io; } function evalIO @@ -92,7 +92,7 @@ IOVal ::= st::IO ioIn::IOToken function unsafeEvalIO a ::= st::IO { - local res::IOVal = evalIO(st, unsafeIO()); + local res::IOVal = evalIO(new(st), unsafeIO()); return unsafeTrace(res.iovalue, res.io); } diff --git a/grammars/silver/core/State.sv b/grammars/silver/core/State.sv index 6fad828e6..e7d903fc2 100644 --- a/grammars/silver/core/State.sv +++ b/grammars/silver/core/State.sv @@ -86,5 +86,5 @@ Pair ::= st::State initialState::s function evalState a ::= st::State initialState::s { - return runState(st, initialState).snd; + return runState(new(st), initialState).snd; } \ No newline at end of file From 6a2c6fb34d5e8e01f9e6f472ca9077e52f050a09 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 1 Nov 2023 19:40:37 -0500 Subject: [PATCH 104/283] Fix precedence of @ --- grammars/silver/compiler/definition/core/Terminals.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/compiler/definition/core/Terminals.sv b/grammars/silver/compiler/definition/core/Terminals.sv index 111af9d14..6b4682b28 100644 --- a/grammars/silver/compiler/definition/core/Terminals.sv +++ b/grammars/silver/compiler/definition/core/Terminals.sv @@ -65,7 +65,6 @@ terminal With_kwd 'with' lexer classes {KEYWORD,RESERVED}, preced terminal AttachNote_kwd 'attachNote' lexer classes {BUILTIN,RESERVED}; -terminal DecSite_t '@' lexer classes {OP}, precedence = 2; terminal Comma_t ',' precedence = 4; terminal Or_t '||' lexer classes {OP}, precedence = 5, association = left; terminal And_t '&&' lexer classes {OP}, precedence = 6, association = left; @@ -83,6 +82,7 @@ terminal Multiply_t '*' lexer classes {OP}, precedence = 12, association = l terminal Divide_t '/' lexer classes {OP}, precedence = 12, association = left; terminal Modulus_t '%' lexer classes {OP}, precedence = 12, association = left; terminal ColonColon_t '::' lexer classes {OP}, precedence = 14, association = right; -- HasType AND cons. right due to cons. +terminal DecSite_t '@' lexer classes {OP}, precedence = 20; terminal LParen_t '(' precedence = 24; terminal RParen_t ')' precedence = 1, association = left; -- Precedence and association eeded for dangling else in action code. terminal LCurly_t '{' ; From f04bae80be16c2d60a6eff0b61932b5153b460c9 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 1 Nov 2023 19:41:40 -0500 Subject: [PATCH 105/283] Use sharing in strategy combinator prods --- grammars/silver/compiler/extension/rewriting/Rewriting.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grammars/silver/compiler/extension/rewriting/Rewriting.sv b/grammars/silver/compiler/extension/rewriting/Rewriting.sv index a7b659794..dd60cf912 100644 --- a/grammars/silver/compiler/extension/rewriting/Rewriting.sv +++ b/grammars/silver/compiler/extension/rewriting/Rewriting.sv @@ -29,14 +29,14 @@ concrete production sequenceOperator top::Expr ::= s1::Expr '<*' s2::Expr { top.unparse = s"(${s1.unparse} <* ${s2.unparse})"; - forwards to mkStrFunctionInvocation("silver:rewrite:sequence", [s1, s2]); + forwards to Silver_Expr { silver:rewrite:sequence($Expr{@s1}, $Expr{@s2}) }; } concrete production choiceOperator top::Expr ::= s1::Expr '<+' s2::Expr { top.unparse = s"(${s1.unparse} <+ ${s2.unparse})"; - forwards to mkStrFunctionInvocation("silver:rewrite:choice", [s1, s2]); + forwards to Silver_Expr { silver:rewrite:choice($Expr{@s1}, $Expr{@s2}) }; } From 5d3bec8499bea3046771acfa70acf429c770debd Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 1 Nov 2023 20:39:42 -0500 Subject: [PATCH 106/283] Remove unlawful instance --- grammars/silver/core/DivisionRing.sv | 4 ---- 1 file changed, 4 deletions(-) diff --git a/grammars/silver/core/DivisionRing.sv b/grammars/silver/core/DivisionRing.sv index 515046e20..cd086d4f0 100644 --- a/grammars/silver/core/DivisionRing.sv +++ b/grammars/silver/core/DivisionRing.sv @@ -14,10 +14,6 @@ class Ring a => DivisionRing a { recip :: (a ::= a); } -instance DivisionRing Integer { - recip = \ a -> 1/a; -} - instance DivisionRing Float { recip = \ a -> 1.0 / a; } From b997bc5970c92eed29a9d37690ccbd7db09bb6ca Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 1 Nov 2023 21:16:29 -0500 Subject: [PATCH 107/283] Remove instance Field Integer --- grammars/silver/core/Field.sv | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/grammars/silver/core/Field.sv b/grammars/silver/core/Field.sv index ce1dfe2d4..8a41913ac 100644 --- a/grammars/silver/core/Field.sv +++ b/grammars/silver/core/Field.sv @@ -13,5 +13,4 @@ grammar silver:core; -} class DivisionRing a, EuclideanRing a => Field a {} -instance Field Integer {} -instance Field Float {} \ No newline at end of file +instance Field Float {} From 7c5e6d2f70202837c43a4f015f9954b4bfb1b8d6 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 1 Nov 2023 21:36:00 -0500 Subject: [PATCH 108/283] Make % on float return 0.0 to match PureScript; add a warning --- grammars/silver/compiler/definition/core/Expr.sv | 6 ++++++ grammars/silver/core/EuclideanRing.sv | 12 ++---------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index cb22e6a47..a057dad91 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -847,6 +847,12 @@ top::Expr ::= e1::Expr '%' e2::Expr { top.unparse = e1.unparse ++ " % " ++ e2.unparse; + top.errors <- + case top.finalType of + | floatType() -> [wrnFromOrigin(top, "Float modulo always returns zero")] + | _ -> [] + end; + forwards to Silver_Expr { silver:core:mod($Expr{@e1}, $Expr{@e2}) }; } diff --git a/grammars/silver/core/EuclideanRing.sv b/grammars/silver/core/EuclideanRing.sv index 76ed387df..a425487b6 100644 --- a/grammars/silver/core/EuclideanRing.sv +++ b/grammars/silver/core/EuclideanRing.sv @@ -41,9 +41,9 @@ Integer ::= a::Integer b::Integer } instance EuclideanRing Float { - degree = \n -> if n < 0.0 then toInteger(-n) else toInteger(n); + degree = \ _ -> 1; div = divFloat; - mod = modFloat; + mod = \ a b -> 0.0; -- This matches what PureScript does. } function divFloat @@ -54,14 +54,6 @@ Float ::= a::Float b::Float "java": return "(%a% / (float)%b%)"; } -function modFloat -Float ::= a::Float b::Float -{ - return error("Foreign function"); -} foreign { - "java": return "(%a% % (float)%b%)"; -} - @{- Computes the greatest common divisor of two numbers. -} function gcd Eq a, EuclideanRing a => a ::= a::a b::a From e9bc69af83dcd300575cd1ed7e108acdb141f7ff Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 1 Nov 2023 21:55:07 -0500 Subject: [PATCH 109/283] Fix flow errors --- grammars/silver/compiler/refactor/Transforms.sv | 1 - 1 file changed, 1 deletion(-) diff --git a/grammars/silver/compiler/refactor/Transforms.sv b/grammars/silver/compiler/refactor/Transforms.sv index 67e39a320..5dc583fb9 100644 --- a/grammars/silver/compiler/refactor/Transforms.sv +++ b/grammars/silver/compiler/refactor/Transforms.sv @@ -44,7 +44,6 @@ attribute transforms occurs on Expr, Exprs, ExprInhs, ExprInh, ExprLHSExpr, AppExprs, AppExpr, AnnoAppExprs, AnnoExpr, FunctionSignature, FunctionLHS, InstanceBody, InstanceBodyItem, - ModuleStmts, ModuleStmt, ImportStmt, ImportStmts, ModuleExpr, ModuleName, NameList, WithElems, WithElem, Module, NTDeclQualifiers, NonterminalModifiers, NonterminalModifierList, ProductionBody, ProductionStmts, ProductionStmt, DefLHS, ForwardInhs, ForwardInh, ForwardLHSExpr, ProductionSignature, ProductionLHS, ProductionRHS, ProductionRHSElem, From e4d0e5f9c573e1a07661a862e99e7888654a63eb Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 2 Nov 2023 11:12:42 -0500 Subject: [PATCH 110/283] Fix warning --- grammars/silver/rewrite/ASTExpr.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/rewrite/ASTExpr.sv b/grammars/silver/rewrite/ASTExpr.sv index 38c63aaf3..a24c75593 100644 --- a/grammars/silver/rewrite/ASTExpr.sv +++ b/grammars/silver/rewrite/ASTExpr.sv @@ -315,7 +315,7 @@ top::ASTExpr ::= a::ASTExpr b::ASTExpr top.value = case a.value, b.value of | integerAST(x), integerAST(y) -> integerAST(x % y) - | floatAST(x), floatAST(y) -> floatAST(x % y) + | floatAST(x), floatAST(y) -> floatAST(0.0) | _, _ -> error("Invalid values") end; } From ec29dc7280e04f01743b5d8974d06c5a194f7c6c Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 2 Nov 2023 11:27:37 -0500 Subject: [PATCH 111/283] Fix another flow error --- grammars/silver/compiler/definition/flow/syntax/FlowSpec.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/compiler/definition/flow/syntax/FlowSpec.sv b/grammars/silver/compiler/definition/flow/syntax/FlowSpec.sv index 6d1450963..c7bf3610d 100644 --- a/grammars/silver/compiler/definition/flow/syntax/FlowSpec.sv +++ b/grammars/silver/compiler/definition/flow/syntax/FlowSpec.sv @@ -178,7 +178,7 @@ top::FlowSpecInhs ::= h::FlowSpecInh ',' t::FlowSpecInhs tracked nonterminal FlowSpecInh with config, grammarName, errors, env, unparse, onNt, inhList, refList, flowEnv; -flowtype FlowSpecInh = forward {grammarName, env, flowEnv, onNt}, inhList {forward}, errors {forward}; +flowtype FlowSpecInh = forward {grammarName, env, flowEnv}, decorate {forward, onNt}, inhList {decorate}, errors {decorate}; propagate config, grammarName, errors, env, flowEnv on FlowSpecInh; From 4ced91fb8579a7a410b7beb5be66475d98df0fde Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 2 Nov 2023 12:11:26 -0500 Subject: [PATCH 112/283] Remove float modulo tests --- test/silver_features/Main.sv | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/silver_features/Main.sv b/test/silver_features/Main.sv index c195a957a..6325de4e7 100644 --- a/test/silver_features/Main.sv +++ b/test/silver_features/Main.sv @@ -20,9 +20,6 @@ equalityTest( 4 / 3, 1, Integer, silver_tests ); -- Modulo works as expected equalityTest( 4 % 3, 1, Integer, silver_tests ); --- Works on floats, too! -equalityTest( 4.0 % 3.0, 1.0, Float, silver_tests ); -- careful, float equality -equalityTest( 4.5 % 1.0, 0.5, Float, silver_tests ); -- careful, float equality -- Cares about sign of first operand, does NOT care for second operand! equalityTest( -4 % 3, -1, Integer, silver_tests ); equalityTest( 4 % -3, 1, Integer, silver_tests ); From c21ff0578df45599bd7e5e988fe6de8a8e075dbb Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 2 Nov 2023 12:29:19 -0500 Subject: [PATCH 113/283] Don't fold fail in every choice --- .../silver/compiler/refactor/Transforms.sv | 2 +- grammars/silver/rewrite/Strategy.sv | 25 +++++++------------ 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/grammars/silver/compiler/refactor/Transforms.sv b/grammars/silver/compiler/refactor/Transforms.sv index 5dc583fb9..fe18e3d55 100644 --- a/grammars/silver/compiler/refactor/Transforms.sv +++ b/grammars/silver/compiler/refactor/Transforms.sv @@ -34,7 +34,7 @@ aspect transformed on AGDcls of | nilAGDcls() -> nilAGDcls() end; -monoid attribute transforms::Strategy with fail(), choice; +monoid attribute transforms::Strategy with fail(), choice_; attribute transforms occurs on AGDcl, diff --git a/grammars/silver/rewrite/Strategy.sv b/grammars/silver/rewrite/Strategy.sv index 66a620823..973cb1436 100644 --- a/grammars/silver/rewrite/Strategy.sv +++ b/grammars/silver/rewrite/Strategy.sv @@ -32,14 +32,7 @@ top::Strategy ::= top.result = nothing(); } -global sequence::(Strategy ::= Strategy Strategy) = \ s1 s2 -> - case s1, s2 of - | id(), _ -> s2 - | _, id() -> s1 - | _, _ -> sequence_(s1, s2) - end; - -abstract production sequence_ +abstract production sequence top::Strategy ::= s1::Strategy s2::Strategy { top.pp = pp"(${s1.pp} <* ${s2.pp})"; @@ -48,14 +41,7 @@ top::Strategy ::= s1::Strategy s2::Strategy top.result = bind(s1.result, \ AST -> s2.result); } -global choice::(Strategy ::= Strategy Strategy) = \ s1 s2 -> - case s1, s2 of - | fail(), _ -> s2 - | _, fail() -> s1 - | _, _ -> choice_(s1, s2) - end; - -abstract production choice_ +abstract production choice top::Strategy ::= s1::Strategy s2::Strategy { top.pp = pp"(${s1.pp} <+ ${s2.pp})"; @@ -64,6 +50,13 @@ top::Strategy ::= s1::Strategy s2::Strategy top.result = orElse(s1.result, s2.result); } +global choice_::(Strategy ::= Strategy Strategy) = \ s1 s2 -> + case s1, s2 of + | fail(), _ -> s2 + | _, fail() -> s1 + | _, _ -> choice(s1, s2) + end; + -- Traversals abstract production all top::Strategy ::= s::Strategy From 62f1d279b9cd0d4f531c31d88d618600dadc3d0e Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 2 Nov 2023 13:12:56 -0500 Subject: [PATCH 114/283] Add support for default pre/post terminal layout when unparsing a subtree not present in the orign parse tree --- .../silver/compiler/refactor/BuildProcess.sv | 4 -- grammars/silver/compiler/refactor/Project.sv | 39 +++++++++++++++++++ .../silver/compiler/refactor/Transforms.sv | 21 ---------- grammars/silver/langutil/unparse/Unparse.sv | 39 +++++++++++++++---- 4 files changed, 70 insertions(+), 33 deletions(-) create mode 100644 grammars/silver/compiler/refactor/Project.sv diff --git a/grammars/silver/compiler/refactor/BuildProcess.sv b/grammars/silver/compiler/refactor/BuildProcess.sv index 1eea9fa77..7ac864b84 100644 --- a/grammars/silver/compiler/refactor/BuildProcess.sv +++ b/grammars/silver/compiler/refactor/BuildProcess.sv @@ -1,10 +1,6 @@ grammar silver:compiler:refactor; -imports silver:util:cmdargs; -imports silver:compiler:driver; - import silver:compiler:translation:java:driver; -import silver:langutil:unparse; synthesized attribute doRefactor :: Boolean occurs on CmdArgs; diff --git a/grammars/silver/compiler/refactor/Project.sv b/grammars/silver/compiler/refactor/Project.sv new file mode 100644 index 000000000..94524c441 --- /dev/null +++ b/grammars/silver/compiler/refactor/Project.sv @@ -0,0 +1,39 @@ +grammar silver:compiler:refactor; + +imports silver:util:cmdargs; +imports silver:compiler:driver; + +imports silver:compiler:definition:core; +imports silver:compiler:definition:type; +imports silver:compiler:definition:env; +imports silver:compiler:definition:concrete_syntax; +imports silver:compiler:definition:type:syntax; +imports silver:compiler:definition:flow:syntax; + +imports silver:compiler:analysis:typechecking:core; + +imports silver:compiler:modification:let_fix; +imports silver:compiler:modification:lambda_fn; +imports silver:compiler:modification:collection; +imports silver:compiler:modification:primitivepattern; +imports silver:compiler:modification:ffi; +imports silver:compiler:modification:copper; +imports silver:compiler:modification:defaultattr; +imports silver:compiler:modification:list; +imports silver:compiler:modification:copper_mda; + +imports silver:rewrite; +imports silver:langutil:unparse; + +aspect production terminalAST +top::AST ::= _ _ _ +{ + termPreLayout <- [ + ("silver:compiler:definition:core:Equal_t", " ") + ]; + termPostLayout <- [ + ("silver:compiler:definition:core:Global_kwd", " "), + ("silver:compiler:definition:core:Comma_t", " "), + ("silver:compiler:definition:core:Equal_t", " ") + ]; +} diff --git a/grammars/silver/compiler/refactor/Transforms.sv b/grammars/silver/compiler/refactor/Transforms.sv index fe18e3d55..dac5584ad 100644 --- a/grammars/silver/compiler/refactor/Transforms.sv +++ b/grammars/silver/compiler/refactor/Transforms.sv @@ -1,26 +1,5 @@ grammar silver:compiler:refactor; -imports silver:compiler:definition:core; -imports silver:compiler:definition:type; -imports silver:compiler:definition:env; -imports silver:compiler:definition:concrete_syntax; -imports silver:compiler:definition:type:syntax; -imports silver:compiler:definition:flow:syntax; - -imports silver:compiler:analysis:typechecking:core; - -imports silver:compiler:modification:let_fix; -imports silver:compiler:modification:lambda_fn; -imports silver:compiler:modification:collection; -imports silver:compiler:modification:primitivepattern; -imports silver:compiler:modification:ffi; -imports silver:compiler:modification:copper; -imports silver:compiler:modification:defaultattr; -imports silver:compiler:modification:list; -imports silver:compiler:modification:copper_mda; - -imports silver:rewrite; - functor attribute transformed occurs on Root, AGDcls; propagate transformed on Root; diff --git a/grammars/silver/langutil/unparse/Unparse.sv b/grammars/silver/langutil/unparse/Unparse.sv index 8dadfa596..390d3c2db 100644 --- a/grammars/silver/langutil/unparse/Unparse.sv +++ b/grammars/silver/langutil/unparse/Unparse.sv @@ -44,6 +44,8 @@ AST ::= ast::a synthesized attribute unparseWithLayout::String occurs on AST, ASTs; synthesized attribute matchingOriginLoc::Maybe occurs on AST; +synthesized attribute defaultPreLayout::Maybe occurs on AST, ASTs; +synthesized attribute defaultPostLayout::Maybe occurs on AST, ASTs; inherited attribute origText::String occurs on AST, ASTs; propagate origText on AST, ASTs; @@ -57,6 +59,8 @@ top::AST ::= { top.unparseWithLayout = error("Can't unparse " ++ genericShow(top)); top.matchingOriginLoc = nothing(); + top.defaultPreLayout = nothing(); + top.defaultPostLayout = nothing(); } aspect production nonterminalAST @@ -77,6 +81,8 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs | nonterminalAST(p, c, _) when prodName == p -> just(c) | _ -> nothing() end; + top.defaultPreLayout = children.defaultPreLayout; + top.defaultPostLayout = children.defaultPostLayout; } aspect production terminalAST @@ -84,21 +90,32 @@ top::AST ::= terminalName::String lexeme::String location::Location { top.unparseWithLayout = lexeme; top.matchingOriginLoc = just(location); + + production attribute termPreLayout::[(String, String)] with ++; + termPreLayout := []; + production attribute termPostLayout::[(String, String)] with ++; + termPostLayout := []; + + top.defaultPreLayout = lookup(terminalName, termPreLayout); + top.defaultPostLayout = lookup(terminalName, termPostLayout); } aspect production consAST top::ASTs ::= h::AST t::ASTs { + local layoutStr::String = fromMaybe("", + case t of + | consAST(h2, _) -> alt( + do { + l1::Location <- h.matchingOriginLoc; + l2::Location <- h2.matchingOriginLoc; + return substring(l1.endIndex, l2.index, top.origText); + }, alt(h.defaultPostLayout, t.defaultPreLayout)) + | nilAST() -> empty + end); top.unparseWithLayout = h.unparseWithLayout ++ - case t of - | consAST(h2, _) -> - case h.matchingOriginLoc, h2.matchingOriginLoc of - | just(l1), just(l2) -> substring(l1.endIndex, l2.index, top.origText) - | _, _ -> "" - end - | nilAST() -> "" - end ++ + layoutStr ++ t.unparseWithLayout; h.parseTree = case top.parseTree of @@ -110,10 +127,16 @@ top::ASTs ::= h::AST t::ASTs | just(consAST(_, a)) -> just(a) | _ -> nothing() end; + top.defaultPreLayout = h.defaultPreLayout; + top.defaultPostLayout = alt( + t.defaultPostLayout, + if t.unparseWithLayout == "" then h.defaultPostLayout else empty); } aspect production nilAST top::ASTs ::= { top.unparseWithLayout = ""; + top.defaultPreLayout = nothing(); + top.defaultPostLayout = nothing(); } From cffa3ad8067c23890ed5086229d43d7997dbd828 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 2 Nov 2023 13:16:00 -0500 Subject: [PATCH 115/283] Prototype of transform to use concise functions. For the moment just use a global to approximate a concise function declaration. --- .../compiler/refactor/ConciseFunctions.sv | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 grammars/silver/compiler/refactor/ConciseFunctions.sv diff --git a/grammars/silver/compiler/refactor/ConciseFunctions.sv b/grammars/silver/compiler/refactor/ConciseFunctions.sv new file mode 100644 index 000000000..35a1cd5ce --- /dev/null +++ b/grammars/silver/compiler/refactor/ConciseFunctions.sv @@ -0,0 +1,41 @@ +grammar silver:compiler:refactor; + +synthesized attribute refactorConciseFunctions :: Boolean occurs on CmdArgs; + +aspect production endCmdArgs +top::CmdArgs ::= _ +{ + top.refactorConciseFunctions = false; +} +abstract production refactorConciseFunctionsFlag +top::CmdArgs ::= rest::CmdArgs +{ + top.refactorConciseFunctions = true; + forwards to refactorFlag(@rest); +} + +aspect function parseArgs +Either ::= args::[String] +{ + flags <- [ flagSpec(name="--refactor-concise-functions", paramString=nothing(), + help="Replace simple production-style functions with concise function syntax", + flagParser=flag(refactorConciseFunctionsFlag)) + ]; +} + +aspect production functionDcl +top::AGDcl ::= 'function' id::Name ns::FunctionSignature body::ProductionBody +{ + top.transforms <- + case body of + | productionBody(_, productionStmtsSnoc(productionStmtsNil(), returnDef(_, e, _)), _) -> + rule on AGDcl of + | a when getParsedOriginLocation(a) == getParsedOriginLocation(top) -> + Silver_AGDcl { + -- TODO: Change this to actually be the right translation when concise functions are finished + global $Name{id} :: a = $Expr{new(e)}; + } + end + | _ -> fail() + end; +} From d67e47b4873584083ba1ebc615af640eafbbeeed Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 2 Nov 2023 14:26:07 -0500 Subject: [PATCH 116/283] Allow specifying a parent grammar to refactor --- .../silver/compiler/refactor/BuildProcess.sv | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/grammars/silver/compiler/refactor/BuildProcess.sv b/grammars/silver/compiler/refactor/BuildProcess.sv index 7ac864b84..163656ab7 100644 --- a/grammars/silver/compiler/refactor/BuildProcess.sv +++ b/grammars/silver/compiler/refactor/BuildProcess.sv @@ -3,11 +3,13 @@ grammar silver:compiler:refactor; import silver:compiler:translation:java:driver; synthesized attribute doRefactor :: Boolean occurs on CmdArgs; +synthesized attribute refactorGrammars :: [String] occurs on CmdArgs; aspect production endCmdArgs top::CmdArgs ::= _ { top.doRefactor = false; + top.refactorGrammars = []; } abstract production refactorFlag top::CmdArgs ::= rest::CmdArgs @@ -18,13 +20,38 @@ top::CmdArgs ::= rest::CmdArgs top.noJavaGeneration = true; forwards to @rest; } +abstract production refactorGrammarsFlag +top::CmdArgs ::= s::String rest::CmdArgs +{ + top.refactorGrammars = s :: rest.refactorGrammars; + forwards to @rest; +} + +aspect function parseArgs +Either ::= args::[String] +{ + flags <- + [ flagSpec(name="--refactor-in", paramString=just(""), + help="parent grammar of grammars to refactor", + flagParser=option(refactorGrammarsFlag)) ]; +} aspect production compilation top::Compilation ::= g::Grammars _ buildGrammars::[String] benv::BuildEnv { + local refactorGrammars::[Decorated RootSpec] = + filter(\ r::Decorated RootSpec -> + null(g.config.refactorGrammars) || + case r of + | grammarRootSpec(_, _, grammarName, _, _, _) -> + any(map(startsWith(_, grammarName), g.config.refactorGrammars)) + | _ -> false + end, + grammarsRelevant); + top.postOps <- if top.config.doRefactor - then [doRefactor(top.config, grammarsRelevant)] + then [doRefactor(top.config, refactorGrammars)] else []; } From 5a5de603a84a00acf40ff416dd9becd1518a0732 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 2 Nov 2023 14:27:02 -0500 Subject: [PATCH 117/283] Avoid transforming ffi functions --- grammars/silver/compiler/refactor/ConciseFunctions.sv | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/grammars/silver/compiler/refactor/ConciseFunctions.sv b/grammars/silver/compiler/refactor/ConciseFunctions.sv index 35a1cd5ce..64a2849b2 100644 --- a/grammars/silver/compiler/refactor/ConciseFunctions.sv +++ b/grammars/silver/compiler/refactor/ConciseFunctions.sv @@ -28,7 +28,8 @@ top::AGDcl ::= 'function' id::Name ns::FunctionSignature body::ProductionBody { top.transforms <- case body of - | productionBody(_, productionStmtsSnoc(productionStmtsNil(), returnDef(_, e, _)), _) -> + | productionBody(_, productionStmtsSnoc(productionStmtsNil(), returnDef(_, e, _)), _) + when top.config.refactorConciseFunctions -> rule on AGDcl of | a when getParsedOriginLocation(a) == getParsedOriginLocation(top) -> Silver_AGDcl { @@ -39,3 +40,10 @@ top::AGDcl ::= 'function' id::Name ns::FunctionSignature body::ProductionBody | _ -> fail() end; } + +aspect production functionDclFFI +top::AGDcl ::= 'function' id::Name ns::FunctionSignature body::ProductionBody 'foreign' '{' ffidefs::FFIDefs '}' +{ + -- This is a forwarding prod, we don't want to rewrite FFI functions like normal ones + top.transforms := ns.transforms <+ body.transforms <+ ffidefs.transforms; +} From aac6899392311da855f43f77e6dbf97e6abe5b50 Mon Sep 17 00:00:00 2001 From: unironically Date: Mon, 6 Nov 2023 20:23:07 -0600 Subject: [PATCH 118/283] Synthesizing undecorated TypeExpr to pass to forward in shortFunctionDcl --- .../extension/concisefunctions/Syntax.sv | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv index ce6050d98..7e8adcc10 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -5,26 +5,19 @@ terminal Fun_kwd 'fun'; concrete production shortFunctionDcl top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' { - propagate flowEnv, grammarName, moduleNames; - - top.unparse = "fun " ++ id.unparse ++ "::" ++ ns.unparse ++ " = " ++ e.unparse ++ ";"; - - ns.signatureName = top.grammarName ++ ":" ++ id.name; - ns.env = newScopeEnv(ns.defs, top.env); - - local prodRHS::ProductionRHS = ns.rhs; - prodRHS.env = ns.env; + top.unparse = "fun " ++ id.unparse ++ ns.unparse ++ " = " ++ e.unparse ++ ";"; forwards to globalValueDclConcrete ( - 'global', @id, '::', ns.cl, '=>', typerepTypeExpr(ns.namedSignature.typerep), '=', - lambda_c('\', prodRHS.toLamRHS, '->', @e),';' + 'global', id, '::', ns.cl, '=>', ns.funTyExpr, '=', + lambda_c('\', ns.rhs.toLamRHS, '->', e),';' ); } synthesized attribute cl::ConstraintList occurs on FunctionSignature; synthesized attribute lhs::FunctionLHS occurs on FunctionSignature; synthesized attribute rhs::ProductionRHS occurs on FunctionSignature; +synthesized attribute funTyExpr::TypeExpr occurs on FunctionSignature; aspect production functionSignature top::FunctionSignature ::= cl::ConstraintList '=>' lhs::FunctionLHS '::=' rhs::ProductionRHS @@ -32,7 +25,7 @@ top::FunctionSignature ::= cl::ConstraintList '=>' lhs::FunctionLHS '::=' rhs::P top.cl = cl; top.lhs = lhs; top.rhs = rhs; - top.t = lhs.t; + top.funTyExpr = funTypeExpr ('(', psignature(presentSignatureLhs(lhs.tyExpr), '::=', rhs.tyExprs), ')'); } aspect production functionSignatureNoCL @@ -41,41 +34,47 @@ top::FunctionSignature ::= lhs::FunctionLHS '::=' rhs::ProductionRHS top.cl = nilConstraint(); top.lhs = lhs; top.rhs = rhs; - top.t = lhs.t; + top.funTyExpr = funTypeExpr ('(', psignature(presentSignatureLhs(lhs.tyExpr), '::=', rhs.tyExprs), ')'); } -synthesized attribute t::TypeExpr occurs on FunctionLHS, FunctionSignature; +synthesized attribute tyExpr::TypeExpr occurs on FunctionLHS; aspect production functionLHS top::FunctionLHS ::= t::TypeExpr { - top.t = t; + top.tyExpr = t; } synthesized attribute toLamRHS::LambdaRHS occurs on ProductionRHS; +synthesized attribute tyExprs::TypeExprs occurs on ProductionRHS; aspect production productionRHSNil top::ProductionRHS ::= { top.toLamRHS = lambdaRHSNil(); + top.tyExprs = typeListNone(); } aspect production productionRHSCons top::ProductionRHS ::= h::ProductionRHSElem t::ProductionRHS { top.toLamRHS = lambdaRHSCons(h.toLamRHSElem, t.toLamRHS); + top.tyExprs = typeListCons(h.tyExpr, t.tyExprs); } synthesized attribute toLamRHSElem::LambdaRHSElem occurs on ProductionRHSElem; +attribute tyExpr occurs on ProductionRHSElem; aspect production productionRHSElem top::ProductionRHSElem ::= id::Name '::' t::TypeExpr { top.toLamRHSElem = lambdaRHSElemIdTy(id, '::', t); + top.tyExpr = t; } aspect production productionRHSElemType top::ProductionRHSElem ::= t::TypeExpr { top.toLamRHSElem = lambdaRHSElemTy('_', '::', t); + top.tyExpr = t; } \ No newline at end of file From 1d668a3ec00aa60a7db0366f8abc9a0492a8cc2f Mon Sep 17 00:00:00 2001 From: unironically Date: Mon, 6 Nov 2023 20:59:37 -0600 Subject: [PATCH 119/283] Added back propagate flowEnv, grammarName, moduleNames, env --- grammars/silver/compiler/extension/concisefunctions/Syntax.sv | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv index 7e8adcc10..67725cd6b 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -5,12 +5,14 @@ terminal Fun_kwd 'fun'; concrete production shortFunctionDcl top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' { + propagate flowEnv, grammarName, moduleNames, env; + top.unparse = "fun " ++ id.unparse ++ ns.unparse ++ " = " ++ e.unparse ++ ";"; forwards to globalValueDclConcrete ( 'global', id, '::', ns.cl, '=>', ns.funTyExpr, '=', - lambda_c('\', ns.rhs.toLamRHS, '->', e),';' + lambda_c('\', ns.rhs.toLamRHS, '->', e), ';' ); } From 8149098704120f8501edbae986659c118166a69f Mon Sep 17 00:00:00 2001 From: unironically Date: Mon, 6 Nov 2023 21:42:17 -0600 Subject: [PATCH 120/283] Quenching MWDA's thirst --- .../silver/compiler/extension/concisefunctions/Syntax.sv | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv index 67725cd6b..010ba607a 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -9,10 +9,15 @@ top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' top.unparse = "fun " ++ id.unparse ++ ns.unparse ++ " = " ++ e.unparse ++ ";"; + ns.signatureName = top.grammarName ++ ":" ++ id.name; + + local rhs::ProductionRHS = ns.rhs; + rhs.env = top.env; + forwards to globalValueDclConcrete ( 'global', id, '::', ns.cl, '=>', ns.funTyExpr, '=', - lambda_c('\', ns.rhs.toLamRHS, '->', e), ';' + lambda_c('\', rhs.toLamRHS, '->', e), ';' ); } From 2345996daf1ad0a7c9b3d018f0e26afa4f795186 Mon Sep 17 00:00:00 2001 From: unironically Date: Mon, 6 Nov 2023 22:07:57 -0600 Subject: [PATCH 121/283] Quenching MWDA's thirst 2 --- grammars/silver/compiler/extension/concisefunctions/Syntax.sv | 1 + 1 file changed, 1 insertion(+) diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv index 010ba607a..8d2c8099c 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -41,6 +41,7 @@ top::FunctionSignature ::= lhs::FunctionLHS '::=' rhs::ProductionRHS top.cl = nilConstraint(); top.lhs = lhs; top.rhs = rhs; + rhs.env = top.env; top.funTyExpr = funTypeExpr ('(', psignature(presentSignatureLhs(lhs.tyExpr), '::=', rhs.tyExprs), ')'); } From 25b21bf181c673bd980a4e908e490ef60e0284a2 Mon Sep 17 00:00:00 2001 From: unironically Date: Mon, 6 Nov 2023 22:51:07 -0600 Subject: [PATCH 122/283] Quenching MWDA's thirst 3 --- grammars/silver/compiler/extension/concisefunctions/Syntax.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv index 8d2c8099c..1bf30f608 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -38,10 +38,10 @@ top::FunctionSignature ::= cl::ConstraintList '=>' lhs::FunctionLHS '::=' rhs::P aspect production functionSignatureNoCL top::FunctionSignature ::= lhs::FunctionLHS '::=' rhs::ProductionRHS { + propagate env; top.cl = nilConstraint(); top.lhs = lhs; top.rhs = rhs; - rhs.env = top.env; top.funTyExpr = funTypeExpr ('(', psignature(presentSignatureLhs(lhs.tyExpr), '::=', rhs.tyExprs), ')'); } From 89f5badbf05c71406460e24847728d39e0b8aa35 Mon Sep 17 00:00:00 2001 From: unironically Date: Mon, 6 Nov 2023 23:18:58 -0600 Subject: [PATCH 123/283] Better handling of function signature --- .../compiler/extension/concisefunctions/Syntax.sv | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv index 1bf30f608..5f5c8814b 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -13,18 +13,19 @@ top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' local rhs::ProductionRHS = ns.rhs; rhs.env = top.env; + local lhs::FunctionLHS = ns.lhs; forwards to globalValueDclConcrete ( - 'global', id, '::', ns.cl, '=>', ns.funTyExpr, '=', - lambda_c('\', rhs.toLamRHS, '->', e), ';' + 'global', id, '::', ns.cl, '=>', + funTypeExpr ('(', psignature(presentSignatureLhs(lhs.tyExpr), '::=', rhs.tyExprs), ')'), + '=', lambda_c('\', rhs.toLamRHS, '->', e), ';' ); } synthesized attribute cl::ConstraintList occurs on FunctionSignature; synthesized attribute lhs::FunctionLHS occurs on FunctionSignature; synthesized attribute rhs::ProductionRHS occurs on FunctionSignature; -synthesized attribute funTyExpr::TypeExpr occurs on FunctionSignature; aspect production functionSignature top::FunctionSignature ::= cl::ConstraintList '=>' lhs::FunctionLHS '::=' rhs::ProductionRHS @@ -32,17 +33,14 @@ top::FunctionSignature ::= cl::ConstraintList '=>' lhs::FunctionLHS '::=' rhs::P top.cl = cl; top.lhs = lhs; top.rhs = rhs; - top.funTyExpr = funTypeExpr ('(', psignature(presentSignatureLhs(lhs.tyExpr), '::=', rhs.tyExprs), ')'); } aspect production functionSignatureNoCL top::FunctionSignature ::= lhs::FunctionLHS '::=' rhs::ProductionRHS { - propagate env; top.cl = nilConstraint(); top.lhs = lhs; top.rhs = rhs; - top.funTyExpr = funTypeExpr ('(', psignature(presentSignatureLhs(lhs.tyExpr), '::=', rhs.tyExprs), ')'); } synthesized attribute tyExpr::TypeExpr occurs on FunctionLHS; From 3c33b34a333d1b3a57013070fc6768b00953a674 Mon Sep 17 00:00:00 2001 From: unironically Date: Tue, 7 Nov 2023 00:01:12 -0600 Subject: [PATCH 124/283] Better handling of function signature --- .../compiler/extension/concisefunctions/Syntax.sv | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv index 5f5c8814b..b54911cdb 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -13,12 +13,11 @@ top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' local rhs::ProductionRHS = ns.rhs; rhs.env = top.env; - local lhs::FunctionLHS = ns.lhs; forwards to globalValueDclConcrete ( 'global', id, '::', ns.cl, '=>', - funTypeExpr ('(', psignature(presentSignatureLhs(lhs.tyExpr), '::=', rhs.tyExprs), ')'), + funTypeExpr ('(', psignature(presentSignatureLhs(ns.lhs.tyExpr), '::=', rhs.tyExprs), ')'), '=', lambda_c('\', rhs.toLamRHS, '->', e), ';' ); } @@ -76,11 +75,4 @@ top::ProductionRHSElem ::= id::Name '::' t::TypeExpr { top.toLamRHSElem = lambdaRHSElemIdTy(id, '::', t); top.tyExpr = t; -} - -aspect production productionRHSElemType -top::ProductionRHSElem ::= t::TypeExpr -{ - top.toLamRHSElem = lambdaRHSElemTy('_', '::', t); - top.tyExpr = t; } \ No newline at end of file From 716db81f088c0633df61d96e0a773b13db0d8a7e Mon Sep 17 00:00:00 2001 From: unironically Date: Tue, 7 Nov 2023 10:52:28 -0600 Subject: [PATCH 125/283] Removing unnecessary propagates --- .../silver/compiler/extension/concisefunctions/Syntax.sv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv index b54911cdb..8874979b7 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -5,7 +5,7 @@ terminal Fun_kwd 'fun'; concrete production shortFunctionDcl top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' { - propagate flowEnv, grammarName, moduleNames, env; + propagate moduleNames; top.unparse = "fun " ++ id.unparse ++ ns.unparse ++ " = " ++ e.unparse ++ ";"; @@ -16,9 +16,9 @@ top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' forwards to globalValueDclConcrete ( - 'global', id, '::', ns.cl, '=>', + 'global', @id, '::', ns.cl, '=>', funTypeExpr ('(', psignature(presentSignatureLhs(ns.lhs.tyExpr), '::=', rhs.tyExprs), ')'), - '=', lambda_c('\', rhs.toLamRHS, '->', e), ';' + '=', lambda_c('\', rhs.toLamRHS, '->', @e), ';' ); } From 718d707b17bf08ec982ef43cf8f393ce019213fd Mon Sep 17 00:00:00 2001 From: unironically Date: Tue, 7 Nov 2023 14:22:25 -0600 Subject: [PATCH 126/283] Testing for concise function syntax --- test/silver_features/ConciseFunctions.sv | 52 ++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 test/silver_features/ConciseFunctions.sv diff --git a/test/silver_features/ConciseFunctions.sv b/test/silver_features/ConciseFunctions.sv new file mode 100644 index 000000000..d40711537 --- /dev/null +++ b/test/silver_features/ConciseFunctions.sv @@ -0,0 +1,52 @@ +{- No tyvars -} +fun adder Integer ::= x::Integer y::Integer = x + y; + +equalityTest(adder(1, 2), 3, Integer, silver_tests); +equalityTest(adder(1, -2), -1, Integer, silver_tests); + +{- Multiple tyvars -} +fun foldr b ::= f::(b ::= a b) i::b l::[a] = + if null(l) then i else f(head(l), foldr(f, i, tail(l))); + +equalityTest(foldr(adder, 0, [1,2,3,4]), 10, Integer, silver_tests); +equalityTest(foldr(adder, 0, []), 0, Integer, silver_tests); + +{- Multiple tyvars with a constraint -} +fun find Eq a => b ::= lst::[(a, b)] key::a otherwise::b = + case lst of + [] -> otherwise + | h::t -> if fst(h) == key then snd(h) else find (t, key, otherwise) + end; + +global mapLst::[(String, Integer)] = [("a", 1), ("b", 2), ("c", 3), ("d", 4)]; +equalityTest(find (mapLst, "c", -1), 3, Integer, silver_tests); +equalityTest(find (mapLst, "e", -1), -1, Integer, silver_tests); + + +nonterminal TestBinding with what; +synthesized attribute key::String occurs on TestBinding; +synthesized attribute val::Integer occurs on TestBinding; +inherited attribute inhKey::String occurs on TestBinding; + +abstract production testBinding +top::TestBinding ::= s::String i::Integer +{ + top.key = s; + top.val = i; +} + +{- Occurs on constraints -} +fun getKey attribute key i occurs on a => String ::= thing::Decorated a with i = thing.key; +fun getInhKey attribute inhKey occurs on a => String ::= thing::Decorated a with i = thing.inhKey; +fun getVal attribute val i occurs on a => Integer ::= thing::Decorated a with i = thing.val; + +global bnd::Decorated TestBinding = decorate testBinding ("a", 5) with {inhKey = "key";}; + +equalityTest(getVal(bnd), 5, Integer, silver_tests); +equalityTest(getKey(bnd), "a", String, silver_tests); +equalityTest(getInhKey(bnd), "key", String, silver_tests); + +{- subset constraint -} +fun getInhKey2 {inhKey} subset i => String ::= x::Decorated TestBinding with i = x.inhKey; + +equalityTest(getInhKey2(bnd), "key", String, silver_tests); \ No newline at end of file From 86397cd26f30952944ec14efb86372dfc78df649 Mon Sep 17 00:00:00 2001 From: unironically Date: Tue, 7 Nov 2023 14:45:05 -0600 Subject: [PATCH 127/283] Documentation, removal of signatureName attribute --- .../silver/compiler/extension/concisefunctions/Syntax.sv | 8 ++++++-- test/silver_features/ConciseFunctions.sv | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv index 8874979b7..01d6b4334 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -2,6 +2,12 @@ grammar silver:compiler:extension:concisefunctions; terminal Fun_kwd 'fun'; +{-- + - Concise function declarations - these forward to globals with lambda expressions + - @param id The name of the concise function + - @param ns The signature of the function + - @param e The expression that serves as the body of the function + -} concrete production shortFunctionDcl top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' { @@ -9,8 +15,6 @@ top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' top.unparse = "fun " ++ id.unparse ++ ns.unparse ++ " = " ++ e.unparse ++ ";"; - ns.signatureName = top.grammarName ++ ":" ++ id.name; - local rhs::ProductionRHS = ns.rhs; rhs.env = top.env; diff --git a/test/silver_features/ConciseFunctions.sv b/test/silver_features/ConciseFunctions.sv index d40711537..39a41e316 100644 --- a/test/silver_features/ConciseFunctions.sv +++ b/test/silver_features/ConciseFunctions.sv @@ -23,7 +23,7 @@ equalityTest(find (mapLst, "c", -1), 3, Integer, silver_tests); equalityTest(find (mapLst, "e", -1), -1, Integer, silver_tests); -nonterminal TestBinding with what; +nonterminal TestBinding; synthesized attribute key::String occurs on TestBinding; synthesized attribute val::Integer occurs on TestBinding; inherited attribute inhKey::String occurs on TestBinding; From f6596f3322a9817b85be27b2a061b0de228b0383 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 7 Nov 2023 15:27:40 -0600 Subject: [PATCH 128/283] Add antiquote for FunctionSignature --- .../compiler/extension/silverconstruction/Syntax.sv | 11 +++++++++++ .../extension/silverconstruction/Terminals.sv | 1 + .../extension/silverconstruction/Translation.sv | 1 + 3 files changed, 13 insertions(+) diff --git a/grammars/silver/compiler/extension/silverconstruction/Syntax.sv b/grammars/silver/compiler/extension/silverconstruction/Syntax.sv index 77feba0af..d6745c620 100644 --- a/grammars/silver/compiler/extension/silverconstruction/Syntax.sv +++ b/grammars/silver/compiler/extension/silverconstruction/Syntax.sv @@ -93,6 +93,17 @@ top::Pattern ::= '$Pattern' '{' e::Expr '}' [errFromOrigin(top, "$Pattern should not occur outside of quoted Silver literal")]); } +concrete production antiquoteFunctionSignature +top::FunctionSignature ::= '$FunctionSignature' '{' e::Expr '}' +{ + top.unparse = s"$$FunctionSignature{${e.unparse}}"; + forwards to + functionSignatureNoCL( + functionLHS( + errorTypeExpr([errFromOrigin(top, "$FunctionSignature should not occur outside of quoted Silver literal")])), + '::=', productionRHSNil()); +} + concrete production antiquoteProductionRHS top::ProductionRHS ::= '$ProductionRHS' '{' e::Expr '}' { diff --git a/grammars/silver/compiler/extension/silverconstruction/Terminals.sv b/grammars/silver/compiler/extension/silverconstruction/Terminals.sv index 1bc2aefd8..b6007c700 100644 --- a/grammars/silver/compiler/extension/silverconstruction/Terminals.sv +++ b/grammars/silver/compiler/extension/silverconstruction/Terminals.sv @@ -14,6 +14,7 @@ terminal AntiquoteExprInhs_t '$ExprInhs' lexer classes {Antiqu terminal AntiquoteTypeExpr_t '$TypeExpr' lexer classes {Antiquote}; terminal AntiquoteConstraintList_t '$ConstraintList' lexer classes {Antiquote}; terminal AntiquotePattern_t '$Pattern' lexer classes {Antiquote}; +terminal AntiquoteFunctionSignature_t '$FunctionSignature' lexer classes {Antiquote}; terminal AntiquoteProductionRHS_t '$ProductionRHS' lexer classes {Antiquote}; terminal AntiquoteAspectRHS_t '$AspectRHS' lexer classes {Antiquote}; terminal AntiquoteProductionStmt_t '$ProductionStmt' lexer classes {Antiquote}; diff --git a/grammars/silver/compiler/extension/silverconstruction/Translation.sv b/grammars/silver/compiler/extension/silverconstruction/Translation.sv index 6fb289e1e..a82c5db35 100644 --- a/grammars/silver/compiler/extension/silverconstruction/Translation.sv +++ b/grammars/silver/compiler/extension/silverconstruction/Translation.sv @@ -12,6 +12,7 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs "silver:compiler:extension:silverconstruction:antiquoteTypeExpr", "silver:compiler:extension:silverconstruction:antiquoteConstraintList", "silver:compiler:extension:silverconstruction:antiquotePattern", + "silver:compiler:extension:silverconstruction:antiquoteFunctionSignature", "silver:compiler:extension:silverconstruction:antiquoteProductionRHS", "silver:compiler:extension:silverconstruction:antiquoteAspectRHS", "silver:compiler:extension:silverconstruction:antiquoteProductionStmt", From 5be339c9d197e8d838503b62c689f9d8531733a7 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 7 Nov 2023 16:24:04 -0600 Subject: [PATCH 129/283] Support specifying layout in unparse for a particular production --- grammars/silver/langutil/unparse/Unparse.sv | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/grammars/silver/langutil/unparse/Unparse.sv b/grammars/silver/langutil/unparse/Unparse.sv index 390d3c2db..da35f6eab 100644 --- a/grammars/silver/langutil/unparse/Unparse.sv +++ b/grammars/silver/langutil/unparse/Unparse.sv @@ -46,6 +46,8 @@ synthesized attribute unparseWithLayout::String occurs on AST, ASTs; synthesized attribute matchingOriginLoc::Maybe occurs on AST; synthesized attribute defaultPreLayout::Maybe occurs on AST, ASTs; synthesized attribute defaultPostLayout::Maybe occurs on AST, ASTs; +inherited attribute childIndex::Integer occurs on ASTs; +inherited attribute childLayout::[(Integer, String)] occurs on ASTs; inherited attribute origText::String occurs on AST, ASTs; propagate origText on AST, ASTs; @@ -83,6 +85,13 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs end; top.defaultPreLayout = children.defaultPreLayout; top.defaultPostLayout = children.defaultPostLayout; + + -- Map of productions and child indices to default layout after the child + production attribute prodChildLayout::[(String, Integer, String)] with ++; + prodChildLayout := []; + + children.childIndex = 0; + children.childLayout = lookupAll(prodName, prodChildLayout); } aspect production terminalAST @@ -91,8 +100,10 @@ top::AST ::= terminalName::String lexeme::String location::Location top.unparseWithLayout = lexeme; top.matchingOriginLoc = just(location); + -- Map of terminal names to default layout after the terminal production attribute termPreLayout::[(String, String)] with ++; termPreLayout := []; + -- Map of terminal names to default layout before the terminal production attribute termPostLayout::[(String, String)] with ++; termPostLayout := []; @@ -110,7 +121,9 @@ top::ASTs ::= h::AST t::ASTs l1::Location <- h.matchingOriginLoc; l2::Location <- h2.matchingOriginLoc; return substring(l1.endIndex, l2.index, top.origText); - }, alt(h.defaultPostLayout, t.defaultPreLayout)) + }, + alt(lookup(top.childIndex, top.childLayout), + alt(h.defaultPostLayout, t.defaultPreLayout))) | nilAST() -> empty end); top.unparseWithLayout = @@ -131,6 +144,8 @@ top::ASTs ::= h::AST t::ASTs top.defaultPostLayout = alt( t.defaultPostLayout, if t.unparseWithLayout == "" then h.defaultPostLayout else empty); + t.childIndex = top.childIndex + 1; + t.childLayout = top.childLayout; } aspect production nilAST From 3331c5774394861d8b2c9e3c7be08b4edae7398a Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 7 Nov 2023 16:31:14 -0600 Subject: [PATCH 130/283] Finish implementation of concise function refactoring --- .../silver/compiler/refactor/ConciseFunctions.sv | 13 ++++++++++--- grammars/silver/compiler/refactor/Project.sv | 12 ++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/grammars/silver/compiler/refactor/ConciseFunctions.sv b/grammars/silver/compiler/refactor/ConciseFunctions.sv index 64a2849b2..5dff2644b 100644 --- a/grammars/silver/compiler/refactor/ConciseFunctions.sv +++ b/grammars/silver/compiler/refactor/ConciseFunctions.sv @@ -29,12 +29,11 @@ top::AGDcl ::= 'function' id::Name ns::FunctionSignature body::ProductionBody top.transforms <- case body of | productionBody(_, productionStmtsSnoc(productionStmtsNil(), returnDef(_, e, _)), _) - when top.config.refactorConciseFunctions -> + when top.config.refactorConciseFunctions && !e.hasImplicitDec -> rule on AGDcl of | a when getParsedOriginLocation(a) == getParsedOriginLocation(top) -> Silver_AGDcl { - -- TODO: Change this to actually be the right translation when concise functions are finished - global $Name{id} :: a = $Expr{new(e)}; + fun $Name{new(id)} $FunctionSignature{new(ns)} = $Expr{new(e)}; } end | _ -> fail() @@ -47,3 +46,11 @@ top::AGDcl ::= 'function' id::Name ns::FunctionSignature body::ProductionBody 'f -- This is a forwarding prod, we don't want to rewrite FFI functions like normal ones top.transforms := ns.transforms <+ body.transforms <+ ffidefs.transforms; } + +monoid attribute hasImplicitDec::Boolean with false, || occurs on + Expr, Exprs, ExprInhs, ExprInh, ExprLHSExpr, AppExprs, AnnoAppExprs, AppExpr, AssignExpr, PrimPatterns, PrimPattern; +propagate hasImplicitDec on + Expr, Exprs, ExprInhs, ExprInh, ExprLHSExpr, AppExprs, AnnoAppExprs, AppExpr, AssignExpr, PrimPatterns, PrimPattern; +aspect hasImplicitDec on top::Expr using <- of +| childReference(q) -> isDecorable(q.lookupValue.typeScheme.monoType, top.env) && top.finalType.isDecorated +end; diff --git a/grammars/silver/compiler/refactor/Project.sv b/grammars/silver/compiler/refactor/Project.sv index 94524c441..1924b5401 100644 --- a/grammars/silver/compiler/refactor/Project.sv +++ b/grammars/silver/compiler/refactor/Project.sv @@ -22,9 +22,20 @@ imports silver:compiler:modification:defaultattr; imports silver:compiler:modification:list; imports silver:compiler:modification:copper_mda; +imports silver:compiler:extension:concisefunctions; + imports silver:rewrite; imports silver:langutil:unparse; +aspect production nonterminalAST +top::AST ::= prodName::String children::ASTs annotations::NamedASTs +{ + prodChildLayout <- [ + ("silver:compiler:extension:concisefunctions:shortFunctionDcl", 1, " "), + ("silver:compiler:extension:concisefunctions:shortFunctionDcl", 3, "\n ") + ]; +} + aspect production terminalAST top::AST ::= _ _ _ { @@ -33,6 +44,7 @@ top::AST ::= _ _ _ ]; termPostLayout <- [ ("silver:compiler:definition:core:Global_kwd", " "), + ("silver:compiler:extension:concisefunctions:Fun_kwd", " "), ("silver:compiler:definition:core:Comma_t", " "), ("silver:compiler:definition:core:Equal_t", " ") ]; From 99f7a402f225e613e5862c90401f4e068f5222ae Mon Sep 17 00:00:00 2001 From: unironically Date: Tue, 7 Nov 2023 19:21:39 -0600 Subject: [PATCH 131/283] Giving 'fun' token the lexer class Keyword --- grammars/silver/compiler/extension/concisefunctions/Syntax.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv index 01d6b4334..9455b4425 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -1,6 +1,6 @@ grammar silver:compiler:extension:concisefunctions; -terminal Fun_kwd 'fun'; +terminal Fun_kwd 'fun' lexer classes {Keyword}; {-- - Concise function declarations - these forward to globals with lambda expressions From c9395488fe48a54fa6ab83ef872b85c278d3e03e Mon Sep 17 00:00:00 2001 From: unironically Date: Tue, 7 Nov 2023 19:27:11 -0600 Subject: [PATCH 132/283] Giving 'fun' token the [actual] lexer class Keyword --- grammars/silver/compiler/extension/concisefunctions/Syntax.sv | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv index 9455b4425..83a590ebc 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -1,6 +1,8 @@ grammar silver:compiler:extension:concisefunctions; -terminal Fun_kwd 'fun' lexer classes {Keyword}; +imports silver:langutil:lsp as lsp; + +terminal Fun_kwd 'fun' lexer classes {lsp:Keyword}; {-- - Concise function declarations - these forward to globals with lambda expressions From bcd499cfc4b7a959f6eeed587ea525abe3f70c4e Mon Sep 17 00:00:00 2001 From: unironically Date: Tue, 7 Nov 2023 22:24:58 -0600 Subject: [PATCH 133/283] Fixed lexer class for 'fun' token. Added another subset test --- .../silver/compiler/extension/concisefunctions/Syntax.sv | 6 ++---- test/silver_features/ConciseFunctions.sv | 2 ++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv index 83a590ebc..34f2be2e3 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -1,8 +1,6 @@ grammar silver:compiler:extension:concisefunctions; -imports silver:langutil:lsp as lsp; - -terminal Fun_kwd 'fun' lexer classes {lsp:Keyword}; +terminal Fun_kwd 'fun' lexer classes {KEYWORD}; {-- - Concise function declarations - these forward to globals with lambda expressions @@ -22,7 +20,7 @@ top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' forwards to globalValueDclConcrete ( - 'global', @id, '::', ns.cl, '=>', + 'global', @id, '::', ns.cl, '=>', funTypeExpr ('(', psignature(presentSignatureLhs(ns.lhs.tyExpr), '::=', rhs.tyExprs), ')'), '=', lambda_c('\', rhs.toLamRHS, '->', @e), ';' ); diff --git a/test/silver_features/ConciseFunctions.sv b/test/silver_features/ConciseFunctions.sv index 39a41e316..8ef967bc8 100644 --- a/test/silver_features/ConciseFunctions.sv +++ b/test/silver_features/ConciseFunctions.sv @@ -43,10 +43,12 @@ fun getVal attribute val i occurs on a => Integer ::= thing::Decorated a with i global bnd::Decorated TestBinding = decorate testBinding ("a", 5) with {inhKey = "key";}; equalityTest(getVal(bnd), 5, Integer, silver_tests); +equalityTest(getVal2(bnd), 5, Integer, silver_tests); equalityTest(getKey(bnd), "a", String, silver_tests); equalityTest(getInhKey(bnd), "key", String, silver_tests); {- subset constraint -} fun getInhKey2 {inhKey} subset i => String ::= x::Decorated TestBinding with i = x.inhKey; +fun getVal2 {inhKey} subset i, attribute val i occurs on a => Integer ::= thing::Decorated a with i = thing.val; equalityTest(getInhKey2(bnd), "key", String, silver_tests); \ No newline at end of file From 14e14aecd735f4b022f619e0e1f68ef142a58fd6 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Sat, 11 Nov 2023 18:44:10 -0600 Subject: [PATCH 134/283] Initial attempt at preserving indentation in refactoring --- .../silver/compiler/refactor/BuildProcess.sv | 2 +- grammars/silver/compiler/refactor/Project.sv | 15 ++-- grammars/silver/langutil/unparse/Unparse.sv | 86 ++++++++++++++----- tutorials/dc/BetterPP.sv | 13 ++- 4 files changed, 77 insertions(+), 39 deletions(-) diff --git a/grammars/silver/compiler/refactor/BuildProcess.sv b/grammars/silver/compiler/refactor/BuildProcess.sv index 163656ab7..24097323d 100644 --- a/grammars/silver/compiler/refactor/BuildProcess.sv +++ b/grammars/silver/compiler/refactor/BuildProcess.sv @@ -76,7 +76,7 @@ IO<()> ::= r::Decorated RootSpec do { let fullPath::String = r.grammarSource ++ item.1; text::String <- readFile(fullPath); - let newText::String = unparse(text, item.2); + let newText::String = unparse(100, text, item.2); when_(text != newText, writeFile(fullPath, newText)); }), r.transformedFiles); diff --git a/grammars/silver/compiler/refactor/Project.sv b/grammars/silver/compiler/refactor/Project.sv index 1924b5401..dfb299c59 100644 --- a/grammars/silver/compiler/refactor/Project.sv +++ b/grammars/silver/compiler/refactor/Project.sv @@ -25,14 +25,15 @@ imports silver:compiler:modification:copper_mda; imports silver:compiler:extension:concisefunctions; imports silver:rewrite; +imports silver:langutil:pp; imports silver:langutil:unparse; aspect production nonterminalAST top::AST ::= prodName::String children::ASTs annotations::NamedASTs { prodChildLayout <- [ - ("silver:compiler:extension:concisefunctions:shortFunctionDcl", 1, " "), - ("silver:compiler:extension:concisefunctions:shortFunctionDcl", 3, "\n ") + ("silver:compiler:extension:concisefunctions:shortFunctionDcl", 1, pp" "), + ("silver:compiler:extension:concisefunctions:shortFunctionDcl", 3, line()) ]; } @@ -40,12 +41,12 @@ aspect production terminalAST top::AST ::= _ _ _ { termPreLayout <- [ - ("silver:compiler:definition:core:Equal_t", " ") + ("silver:compiler:definition:core:Equal_t", pp" ") ]; termPostLayout <- [ - ("silver:compiler:definition:core:Global_kwd", " "), - ("silver:compiler:extension:concisefunctions:Fun_kwd", " "), - ("silver:compiler:definition:core:Comma_t", " "), - ("silver:compiler:definition:core:Equal_t", " ") + ("silver:compiler:definition:core:Global_kwd", pp" "), + ("silver:compiler:extension:concisefunctions:Fun_kwd", pp" "), + ("silver:compiler:definition:core:Comma_t", pp" "), + ("silver:compiler:definition:core:Equal_t", pp" ") ]; } diff --git a/grammars/silver/langutil/unparse/Unparse.sv b/grammars/silver/langutil/unparse/Unparse.sv index da35f6eab..d28b285da 100644 --- a/grammars/silver/langutil/unparse/Unparse.sv +++ b/grammars/silver/langutil/unparse/Unparse.sv @@ -2,6 +2,7 @@ grammar silver:langutil:unparse; imports silver:reflect:util; imports silver:langutil; +imports silver:langutil:pp; @{-- - Unparse a tree, preserving layout from its parse tree via origin tracking. @@ -18,16 +19,22 @@ imports silver:langutil; - @return The unparse of the tree, with layout from origText inserted in unchanged portions of the tree. -} function unparse -String ::= origText::String tree::a +String ::= width::Integer origText::String tree::a { local ast::AST = reflect(tree); ast.origText = origText; ast.parseTree = just(getParseTree(tree)); + ast.indent = fromMaybe(countIndent(preLayout), layoutIndent(preLayout)); local astLoc::Location = ast.matchingOriginLoc.fromJust; - return - substring(0, astLoc.index, origText) ++ - ast.unparseWithLayout ++ - substring(astLoc.endIndex, length(origText), origText); + + local preLayout::String = substring(0, astLoc.index, origText); + local postLayout::String = substring(astLoc.endIndex, length(origText), origText); + + return show(width, + text(preLayout) ++ + maybeNest(ast.indent, + ast.unparseWithLayout ++ + layoutPP(ast.indent, postLayout))); } function getParseTree @@ -42,12 +49,12 @@ AST ::= ast::a end; } -synthesized attribute unparseWithLayout::String occurs on AST, ASTs; +synthesized attribute unparseWithLayout::Document occurs on AST, ASTs; synthesized attribute matchingOriginLoc::Maybe occurs on AST; -synthesized attribute defaultPreLayout::Maybe occurs on AST, ASTs; -synthesized attribute defaultPostLayout::Maybe occurs on AST, ASTs; +synthesized attribute defaultPreLayout::Maybe occurs on AST, ASTs; +synthesized attribute defaultPostLayout::Maybe occurs on AST, ASTs; inherited attribute childIndex::Integer occurs on ASTs; -inherited attribute childLayout::[(Integer, String)] occurs on ASTs; +inherited attribute childLayout::[(Integer, Document)] occurs on ASTs; inherited attribute origText::String occurs on AST, ASTs; propagate origText on AST, ASTs; @@ -56,6 +63,8 @@ inherited attribute parseTree::Maybe; attribute parseTree occurs on AST; attribute parseTree occurs on ASTs; +inherited attribute indent::Integer occurs on AST, ASTs; + aspect default production top::AST ::= { @@ -83,11 +92,12 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs | nonterminalAST(p, c, _) when prodName == p -> just(c) | _ -> nothing() end; + children.indent = top.indent; top.defaultPreLayout = children.defaultPreLayout; top.defaultPostLayout = children.defaultPostLayout; -- Map of productions and child indices to default layout after the child - production attribute prodChildLayout::[(String, Integer, String)] with ++; + production attribute prodChildLayout::[(String, Integer, Document)] with ++; prodChildLayout := []; children.childIndex = 0; @@ -97,14 +107,14 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs aspect production terminalAST top::AST ::= terminalName::String lexeme::String location::Location { - top.unparseWithLayout = lexeme; + top.unparseWithLayout = text(lexeme); top.matchingOriginLoc = just(location); -- Map of terminal names to default layout after the terminal - production attribute termPreLayout::[(String, String)] with ++; + production attribute termPreLayout::[(String, Document)] with ++; termPreLayout := []; -- Map of terminal names to default layout before the terminal - production attribute termPostLayout::[(String, String)] with ++; + production attribute termPostLayout::[(String, Document)] with ++; termPostLayout := []; top.defaultPreLayout = lookup(terminalName, termPreLayout); @@ -114,22 +124,28 @@ top::AST ::= terminalName::String lexeme::String location::Location aspect production consAST top::ASTs ::= h::AST t::ASTs { - local layoutStr::String = fromMaybe("", + local origLayout::Maybe = case t of - | consAST(h2, _) -> alt( + | consAST(h2, _) -> do { l1::Location <- h.matchingOriginLoc; l2::Location <- h2.matchingOriginLoc; return substring(l1.endIndex, l2.index, top.origText); - }, - alt(lookup(top.childIndex, top.childLayout), - alt(h.defaultPostLayout, t.defaultPreLayout))) + } | nilAST() -> empty - end); + end; + h.indent = top.indent; + t.indent = fromMaybe(top.indent, bind(origLayout, layoutIndent)); top.unparseWithLayout = h.unparseWithLayout ++ - layoutStr ++ - t.unparseWithLayout; + maybeNest( + if top.parseTree.isJust then t.indent - top.indent else 2, + fromMaybe(pp"", + alt( + map(layoutPP(t.indent, _), origLayout), + alt(lookup(top.childIndex, top.childLayout), + alt(h.defaultPostLayout, t.defaultPreLayout)))) ++ + t.unparseWithLayout); h.parseTree = case top.parseTree of | just(consAST(a, _)) -> just(a) @@ -143,7 +159,7 @@ top::ASTs ::= h::AST t::ASTs top.defaultPreLayout = h.defaultPreLayout; top.defaultPostLayout = alt( t.defaultPostLayout, - if t.unparseWithLayout == "" then h.defaultPostLayout else empty); + if t.unparseWithLayout == pp"" then h.defaultPostLayout else empty); t.childIndex = top.childIndex + 1; t.childLayout = top.childLayout; } @@ -151,7 +167,31 @@ top::ASTs ::= h::AST t::ASTs aspect production nilAST top::ASTs ::= { - top.unparseWithLayout = ""; + top.unparseWithLayout = pp""; top.defaultPreLayout = nothing(); top.defaultPostLayout = nothing(); } + +-- Count the number of spaces at the start of a line +fun countIndent Integer ::= s::String = length(takeWhile(eq(" ", _), explode("", s))); + +fun layoutIndent Maybe ::= layoutStr::String = + case explode("\n", layoutStr) of + | [] -> nothing() + | [_] -> nothing() + | lines -> just(countIndent(last(lines))) + end; + +fun layoutPP Document ::= indent::Integer layoutStr::String = + concat( + case explode("\n", layoutStr) of + | [] -> [] + | pre :: lines -> text(pre) :: + map(\ l::String -> + maybeNest( + countIndent(l) - indent, + realLine() ++ text(concat(dropWhile(eq(" ", _), explode("", l))))), + lines) + end); + +fun maybeNest Document ::= n::Integer d::Document = if n == 0 then d else nest(n, d); diff --git a/tutorials/dc/BetterPP.sv b/tutorials/dc/BetterPP.sv index 218718e60..c564d3e52 100644 --- a/tutorials/dc/BetterPP.sv +++ b/tutorials/dc/BetterPP.sv @@ -27,14 +27,11 @@ inherited attribute leftOrRight :: String occurs on Expr ; "right". Otherwise "none". -} -function wrapInParens -Boolean ::= enclosingPrecedence::Integer thisPrecedence::Integer - thisPosition::String opAssociativity::String -{ - return enclosingPrecedence > thisPrecedence || - (enclosingPrecedence == thisPrecedence && - thisPosition != opAssociativity) ; -} +fun wrapInParens Boolean ::= enclosingPrecedence::Integer thisPrecedence::Integer + thisPosition::String opAssociativity::String = + enclosingPrecedence > thisPrecedence || + (enclosingPrecedence == thisPrecedence && + thisPosition != opAssociativity); aspect production root r::Root ::= e::Expr From 12b4ed4ea83bd2224648ff4d3042ffaab81db9b2 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 14 Nov 2023 15:26:25 -0600 Subject: [PATCH 135/283] Add a way to specify default indent for a child --- grammars/silver/compiler/refactor/Project.sv | 3 +++ grammars/silver/langutil/unparse/Unparse.sv | 16 ++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/grammars/silver/compiler/refactor/Project.sv b/grammars/silver/compiler/refactor/Project.sv index dfb299c59..402db2cef 100644 --- a/grammars/silver/compiler/refactor/Project.sv +++ b/grammars/silver/compiler/refactor/Project.sv @@ -35,6 +35,9 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs ("silver:compiler:extension:concisefunctions:shortFunctionDcl", 1, pp" "), ("silver:compiler:extension:concisefunctions:shortFunctionDcl", 3, line()) ]; + prodChildIndent <- [ + ("silver:compiler:extension:concisefunctions:shortFunctionDcl", 4, 2) + ]; } aspect production terminalAST diff --git a/grammars/silver/langutil/unparse/Unparse.sv b/grammars/silver/langutil/unparse/Unparse.sv index d28b285da..b4466aaa7 100644 --- a/grammars/silver/langutil/unparse/Unparse.sv +++ b/grammars/silver/langutil/unparse/Unparse.sv @@ -55,6 +55,8 @@ synthesized attribute defaultPreLayout::Maybe occurs on AST, ASTs; synthesized attribute defaultPostLayout::Maybe occurs on AST, ASTs; inherited attribute childIndex::Integer occurs on ASTs; inherited attribute childLayout::[(Integer, Document)] occurs on ASTs; +inherited attribute childIndent::[(Integer, Integer)] occurs on ASTs; +propagate childLayout, childIndent on ASTs; inherited attribute origText::String occurs on AST, ASTs; propagate origText on AST, ASTs; @@ -96,12 +98,17 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs top.defaultPreLayout = children.defaultPreLayout; top.defaultPostLayout = children.defaultPostLayout; + children.childIndex = 0; + -- Map of productions and child indices to default layout after the child production attribute prodChildLayout::[(String, Integer, Document)] with ++; prodChildLayout := []; - - children.childIndex = 0; children.childLayout = lookupAll(prodName, prodChildLayout); + + -- Map of productions and child indices to default indentation in the child + production attribute prodChildIndent::[(String, Integer, Integer)] with ++; + prodChildIndent := []; + children.childIndent = lookupAll(prodName, prodChildIndent); } aspect production terminalAST @@ -139,7 +146,9 @@ top::ASTs ::= h::AST t::ASTs top.unparseWithLayout = h.unparseWithLayout ++ maybeNest( - if top.parseTree.isJust then t.indent - top.indent else 2, + if top.parseTree.isJust + then t.indent - top.indent + else fromMaybe(0, lookup(t.childIndex, top.childIndent)), fromMaybe(pp"", alt( map(layoutPP(t.indent, _), origLayout), @@ -161,7 +170,6 @@ top::ASTs ::= h::AST t::ASTs t.defaultPostLayout, if t.unparseWithLayout == pp"" then h.defaultPostLayout else empty); t.childIndex = top.childIndex + 1; - t.childLayout = top.childLayout; } aspect production nilAST From 93a83419ad3cbc92b48595177c73ea702ec5be80 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 14 Nov 2023 18:07:38 -0600 Subject: [PATCH 136/283] Compute layout and indent on parse tree AST --- grammars/silver/langutil/unparse/Unparse.sv | 112 +++++++++++--------- 1 file changed, 59 insertions(+), 53 deletions(-) diff --git a/grammars/silver/langutil/unparse/Unparse.sv b/grammars/silver/langutil/unparse/Unparse.sv index b4466aaa7..1eff2fb0f 100644 --- a/grammars/silver/langutil/unparse/Unparse.sv +++ b/grammars/silver/langutil/unparse/Unparse.sv @@ -21,20 +21,21 @@ imports silver:langutil:pp; function unparse String ::= width::Integer origText::String tree::a { + local parseTree::AST = getParseTree(tree); + parseTree.origText = origText; + local ast::AST = reflect(tree); ast.origText = origText; - ast.parseTree = just(getParseTree(tree)); - ast.indent = fromMaybe(countIndent(preLayout), layoutIndent(preLayout)); - local astLoc::Location = ast.matchingOriginLoc.fromJust; + ast.parseTree = just(parseTree); - local preLayout::String = substring(0, astLoc.index, origText); - local postLayout::String = substring(astLoc.endIndex, length(origText), origText); + local preLayout::String = substring(0, parseTree.originLoc.index, origText); + local postLayout::String = substring(parseTree.originLoc.endIndex, length(origText), origText); return show(width, text(preLayout) ++ - maybeNest(ast.indent, + maybeNest(parseTree.indent, ast.unparseWithLayout ++ - layoutPP(ast.indent, postLayout))); + layoutPP(parseTree.indent, postLayout))); } function getParseTree @@ -49,8 +50,21 @@ AST ::= ast::a end; } +-- Attributes computed on parseTree +inherited attribute origText::String occurs on AST, ASTs; +propagate origText on AST, ASTs; + +synthesized attribute originLoc::Location occurs on AST; +synthesized attribute indent::Integer occurs on AST; +synthesized attribute origNest::Integer occurs on ASTs; +synthesized attribute origLayoutPP::Document occurs on ASTs; + +-- Attributes computed on the unparse AST +inherited attribute parseTree::Maybe; -- This is like a destruct attribute except it's a Maybe +attribute parseTree occurs on AST; +attribute parseTree occurs on ASTs; + synthesized attribute unparseWithLayout::Document occurs on AST, ASTs; -synthesized attribute matchingOriginLoc::Maybe occurs on AST; synthesized attribute defaultPreLayout::Maybe occurs on AST, ASTs; synthesized attribute defaultPostLayout::Maybe occurs on AST, ASTs; inherited attribute childIndex::Integer occurs on ASTs; @@ -58,20 +72,12 @@ inherited attribute childLayout::[(Integer, Document)] occurs on ASTs; inherited attribute childIndent::[(Integer, Integer)] occurs on ASTs; propagate childLayout, childIndent on ASTs; -inherited attribute origText::String occurs on AST, ASTs; -propagate origText on AST, ASTs; - -inherited attribute parseTree::Maybe; -attribute parseTree occurs on AST; -attribute parseTree occurs on ASTs; - -inherited attribute indent::Integer occurs on AST, ASTs; - aspect default production top::AST ::= { + top.originLoc = error(genericShow(top) ++ " cannot appear in a parse tree"); + top.indent = countIndent(head(drop(top.originLoc.line - 1, explode("\n", top.origText)))); top.unparseWithLayout = error("Can't unparse " ++ genericShow(top)); - top.matchingOriginLoc = nothing(); top.defaultPreLayout = nothing(); top.defaultPostLayout = nothing(); } @@ -79,22 +85,22 @@ top::AST ::= aspect production nonterminalAST top::AST ::= prodName::String children::ASTs annotations::NamedASTs { + -- On parseTree top.unparseWithLayout = children.unparseWithLayout; - top.matchingOriginLoc = do { - tree :: AST <- top.parseTree; - return - case getParsedOriginLocation(tree) of - | just(l) -> l - | nothing() -> - error("Tree does not have a parsed origin: " ++ showOriginInfoChain(tree)) - end; - }; + top.originLoc = + case getParsedOriginLocation(top) of + | just(l) -> l + | nothing() -> error("Tree does not have a parsed origin: " ++ showOriginInfoChain(top)) + end; + + -- On unparse AST + local parseTree::AST = getParseTree(top); + parseTree.origText = top.origText; children.parseTree = - case fromMaybe(getParseTree(top), top.parseTree) of + case fromMaybe(parseTree, top.parseTree) of | nonterminalAST(p, c, _) when prodName == p -> just(c) | _ -> nothing() end; - children.indent = top.indent; top.defaultPreLayout = children.defaultPreLayout; top.defaultPostLayout = children.defaultPostLayout; @@ -114,8 +120,9 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs aspect production terminalAST top::AST ::= terminalName::String lexeme::String location::Location { + top.originLoc = location; + top.unparseWithLayout = text(lexeme); - top.matchingOriginLoc = just(location); -- Map of terminal names to default layout after the terminal production attribute termPreLayout::[(String, Document)] with ++; @@ -131,29 +138,32 @@ top::AST ::= terminalName::String lexeme::String location::Location aspect production consAST top::ASTs ::= h::AST t::ASTs { - local origLayout::Maybe = + -- On parseTree + top.origLayoutPP = case t of | consAST(h2, _) -> - do { - l1::Location <- h.matchingOriginLoc; - l2::Location <- h2.matchingOriginLoc; - return substring(l1.endIndex, l2.index, top.origText); - } - | nilAST() -> empty + layoutPP(h2.indent, + substring(h.originLoc.endIndex, h2.originLoc.index, top.origText)) + | nilAST() -> pp"" end; - h.indent = top.indent; - t.indent = fromMaybe(top.indent, bind(origLayout, layoutIndent)); + top.origNest = + case t of + | consAST(h2, _) -> h2.indent - h.indent + | nilAST() -> 0 + end; + + -- On unparse AST top.unparseWithLayout = h.unparseWithLayout ++ maybeNest( - if top.parseTree.isJust - then t.indent - top.indent - else fromMaybe(0, lookup(t.childIndex, top.childIndent)), + fromMaybe(0, + alt(map((.origNest), top.parseTree), + lookup(t.childIndex, top.childIndent))), fromMaybe(pp"", - alt( - map(layoutPP(t.indent, _), origLayout), + alt(map((.origLayoutPP), top.parseTree), alt(lookup(top.childIndex, top.childLayout), - alt(h.defaultPostLayout, t.defaultPreLayout)))) ++ + alt(case t of consAST(_, _) -> h.defaultPostLayout | _ -> empty end, + t.defaultPreLayout)))) ++ t.unparseWithLayout); h.parseTree = case top.parseTree of @@ -168,13 +178,16 @@ top::ASTs ::= h::AST t::ASTs top.defaultPreLayout = h.defaultPreLayout; top.defaultPostLayout = alt( t.defaultPostLayout, - if t.unparseWithLayout == pp"" then h.defaultPostLayout else empty); + case t of nilAST() -> h.defaultPostLayout | _ -> empty end); t.childIndex = top.childIndex + 1; } aspect production nilAST top::ASTs ::= { + top.origLayoutPP = pp""; + top.origNest = 0; + top.unparseWithLayout = pp""; top.defaultPreLayout = nothing(); top.defaultPostLayout = nothing(); @@ -183,13 +196,6 @@ top::ASTs ::= -- Count the number of spaces at the start of a line fun countIndent Integer ::= s::String = length(takeWhile(eq(" ", _), explode("", s))); -fun layoutIndent Maybe ::= layoutStr::String = - case explode("\n", layoutStr) of - | [] -> nothing() - | [_] -> nothing() - | lines -> just(countIndent(last(lines))) - end; - fun layoutPP Document ::= indent::Integer layoutStr::String = concat( case explode("\n", layoutStr) of From 9e4cd7d8172e580dfa8ae95a1ecd163ddf094c4c Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 15 Nov 2023 16:45:29 -0600 Subject: [PATCH 137/283] FIx crash in Document library with realLine, for now force all enclosing groups to wrap lines --- grammars/silver/langutil/pp/Document.sv | 10 +++++++--- test/stdlib/pplib/PrettyTests.sv | 8 ++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/grammars/silver/langutil/pp/Document.sv b/grammars/silver/langutil/pp/Document.sv index 267f1ce52..46fbd0d46 100644 --- a/grammars/silver/langutil/pp/Document.sv +++ b/grammars/silver/langutil/pp/Document.sv @@ -322,13 +322,17 @@ abstract production realLine top::Document ::= { -- I'm not 100% on this combinator - top.outPosition = top.inPosition + (top.inRemaining - top.outRemaining); - top.outDq = top.inDq; + + -- For now, force all enclosing groups to be vertical. + local pr :: Pair> [Boolean]> = prune(top.width + 1, top.inDq); + + top.outPosition = top.indent; + top.outDq = pr.fst; top.outCHorizontals = top.inCHorizontals; top.outRemaining = top.width - top.indent; top.result = "\n" ++ replicate(top.indent, " "); - top.horizontals = []; + top.horizontals = pr.snd; } -------------------------------------------------------------------------------- diff --git a/test/stdlib/pplib/PrettyTests.sv b/test/stdlib/pplib/PrettyTests.sv index 61fd657cb..7d9d71dce 100644 --- a/test/stdlib/pplib/PrettyTests.sv +++ b/test/stdlib/pplib/PrettyTests.sv @@ -92,7 +92,7 @@ equalityTest ( "\n" ++ show(25, doc6), "\n(cons (list foo bar baz) (cons (hello equalityTest ( "\n" ++ show(80, doc6), "\n(cons (list foo bar baz) (cons (hello world) (more qwerty)))", String, core_tests ) ; global doc7 :: Document = - group(ppConcat([text(" 1234567890"), realLine(), text(" 1234567890"), line(), text("1234567890")])); + group(ppConcat([text(" 1234567890"), realLine(), group(ppConcat([text(" 1234567890"), line(), text("1234567890")]))])); equalityTest ( "\n" ++ show(22, doc7), "\n 1234567890\n 1234567890 1234567890", String, core_tests ) ; equalityTest ( "\n" ++ show(21, doc7), "\n 1234567890\n 1234567890\n1234567890", String, core_tests ) ; @@ -151,4 +151,8 @@ equalityTest ( pp"abc\ndef", cat(cat(text("abc"), realLine()), text("def")), Doc equalityTest ( pp"""abc def""", cat(cat(text("abc"), realLine()), text("def")), Document, core_tests ); -equalityTest ( show(0, pp"abc${123} ${just(3.14)}"), "abc123 just(3.14)", String, core_tests ); +equalityTest ( show(100, group(cat(line(), cat(realLine(), text(";"))))), "\n\n;", String, core_tests ); + +equalityTest ( show(100, group(group(pp"a" ++ line() ++ pp"b") ++ realLine() ++ group(pp"c" ++ line() ++ pp"d"))), "a b\nc d", String, core_tests ); +equalityTest ( show(100, group(group(pp"a" ++ realLine() ++ pp"b") ++ line() ++ group(pp"c" ++ line() ++ pp"d"))), "a\nb\nc d", String, core_tests ); +equalityTest ( show(100, group(group(pp"a" ++ line() ++ pp"b") ++ line() ++ group(pp"c" ++ realLine() ++ pp"d"))), "a b\nc\nd", String, core_tests ); From 32ac062df3fa4976f70a9cd8bcae2de36fd83ce9 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 15 Nov 2023 16:46:45 -0600 Subject: [PATCH 138/283] Group the unparse of each production --- grammars/silver/langutil/unparse/Unparse.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/langutil/unparse/Unparse.sv b/grammars/silver/langutil/unparse/Unparse.sv index 1eff2fb0f..d57b619f5 100644 --- a/grammars/silver/langutil/unparse/Unparse.sv +++ b/grammars/silver/langutil/unparse/Unparse.sv @@ -86,7 +86,7 @@ aspect production nonterminalAST top::AST ::= prodName::String children::ASTs annotations::NamedASTs { -- On parseTree - top.unparseWithLayout = children.unparseWithLayout; + top.unparseWithLayout = group(children.unparseWithLayout); top.originLoc = case getParsedOriginLocation(top) of | just(l) -> l From 785b4ff6dc1cbc928c4e59b1898e9157e9c29638 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 15 Nov 2023 18:51:24 -0600 Subject: [PATCH 139/283] Make unparse return a Document --- grammars/silver/compiler/refactor/BuildProcess.sv | 2 +- grammars/silver/langutil/unparse/Unparse.sv | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/grammars/silver/compiler/refactor/BuildProcess.sv b/grammars/silver/compiler/refactor/BuildProcess.sv index 24097323d..72565e90a 100644 --- a/grammars/silver/compiler/refactor/BuildProcess.sv +++ b/grammars/silver/compiler/refactor/BuildProcess.sv @@ -76,7 +76,7 @@ IO<()> ::= r::Decorated RootSpec do { let fullPath::String = r.grammarSource ++ item.1; text::String <- readFile(fullPath); - let newText::String = unparse(100, text, item.2); + let newText::String = show(100, unparse(text, item.2)); when_(text != newText, writeFile(fullPath, newText)); }), r.transformedFiles); diff --git a/grammars/silver/langutil/unparse/Unparse.sv b/grammars/silver/langutil/unparse/Unparse.sv index d57b619f5..4fa03e104 100644 --- a/grammars/silver/langutil/unparse/Unparse.sv +++ b/grammars/silver/langutil/unparse/Unparse.sv @@ -19,7 +19,7 @@ imports silver:langutil:pp; - @return The unparse of the tree, with layout from origText inserted in unchanged portions of the tree. -} function unparse -String ::= width::Integer origText::String tree::a +Document ::= origText::String tree::a { local parseTree::AST = getParseTree(tree); parseTree.origText = origText; @@ -31,11 +31,11 @@ String ::= width::Integer origText::String tree::a local preLayout::String = substring(0, parseTree.originLoc.index, origText); local postLayout::String = substring(parseTree.originLoc.endIndex, length(origText), origText); - return show(width, + return text(preLayout) ++ maybeNest(parseTree.indent, ast.unparseWithLayout ++ - layoutPP(parseTree.indent, postLayout))); + layoutPP(parseTree.indent, postLayout)); } function getParseTree From 6ef36300c42d1a9e655a4475999a9ea558554f18 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 16 Nov 2023 11:27:39 -0600 Subject: [PATCH 140/283] Add utility --- grammars/silver/core/List.sv | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/grammars/silver/core/List.sv b/grammars/silver/core/List.sv index 0ce9fe788..26dee3cb1 100644 --- a/grammars/silver/core/List.sv +++ b/grammars/silver/core/List.sv @@ -484,6 +484,13 @@ function unzip3 else (head(l).1 :: rest.1, head(l).2 :: rest.2, head(l).3 :: rest.3); } +global enumerate :: ([(Integer, a)] ::= [a]) = enumerateFrom(0, _); +fun enumerateFrom [(Integer, a)] ::= i::Integer l::[a] = + case l of + | h :: t -> (i, h) :: enumerateFrom(i + 1, t) + | [] -> [] + end; + function reverse [a] ::= lst::[a] { From deedfead1b9b20e84ca1a69b4a6ec4950b084b0f Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 16 Nov 2023 11:42:38 -0600 Subject: [PATCH 141/283] Optimization, store line indents in a map --- grammars/silver/langutil/unparse/Unparse.sv | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/grammars/silver/langutil/unparse/Unparse.sv b/grammars/silver/langutil/unparse/Unparse.sv index 4fa03e104..b4af7d4dd 100644 --- a/grammars/silver/langutil/unparse/Unparse.sv +++ b/grammars/silver/langutil/unparse/Unparse.sv @@ -3,6 +3,7 @@ grammar silver:langutil:unparse; imports silver:reflect:util; imports silver:langutil; imports silver:langutil:pp; +imports silver:util:treemap as map; @{-- - Unparse a tree, preserving layout from its parse tree via origin tracking. @@ -23,9 +24,11 @@ Document ::= origText::String tree::a { local parseTree::AST = getParseTree(tree); parseTree.origText = origText; + parseTree.lineIndent = map:fromList(enumerate(map(countIndent, explode("\n", origText)))); local ast::AST = reflect(tree); ast.origText = origText; + ast.lineIndent = parseTree.lineIndent; ast.parseTree = just(parseTree); local preLayout::String = substring(0, parseTree.originLoc.index, origText); @@ -52,17 +55,19 @@ AST ::= ast::a -- Attributes computed on parseTree inherited attribute origText::String occurs on AST, ASTs; -propagate origText on AST, ASTs; +inherited attribute lineIndent::map:Map occurs on AST, ASTs; +propagate origText, lineIndent on AST, ASTs; synthesized attribute originLoc::Location occurs on AST; synthesized attribute indent::Integer occurs on AST; +flowtype indent {lineIndent} on AST; synthesized attribute origNest::Integer occurs on ASTs; synthesized attribute origLayoutPP::Document occurs on ASTs; -- Attributes computed on the unparse AST inherited attribute parseTree::Maybe; -- This is like a destruct attribute except it's a Maybe -attribute parseTree occurs on AST; -attribute parseTree occurs on ASTs; +attribute parseTree occurs on AST; +attribute parseTree occurs on ASTs; synthesized attribute unparseWithLayout::Document occurs on AST, ASTs; synthesized attribute defaultPreLayout::Maybe occurs on AST, ASTs; @@ -76,7 +81,11 @@ aspect default production top::AST ::= { top.originLoc = error(genericShow(top) ++ " cannot appear in a parse tree"); - top.indent = countIndent(head(drop(top.originLoc.line - 1, explode("\n", top.origText)))); + top.indent = + case map:lookup(top.originLoc.line - 1, top.lineIndent) of + | i :: _ -> i + | [] -> error(s"Line ${toString(top.originLoc.line)} out of bounds for supplied text!") + end; top.unparseWithLayout = error("Can't unparse " ++ genericShow(top)); top.defaultPreLayout = nothing(); top.defaultPostLayout = nothing(); @@ -96,6 +105,7 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs -- On unparse AST local parseTree::AST = getParseTree(top); parseTree.origText = top.origText; + parseTree.lineIndent = top.lineIndent; children.parseTree = case fromMaybe(parseTree, top.parseTree) of | nonterminalAST(p, c, _) when prodName == p -> just(c) From befaa611a0c43609e41bcb07c7b4ef6f273ba1b9 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 17 Nov 2023 11:34:08 -0600 Subject: [PATCH 142/283] Don't crash with negative indent --- grammars/silver/langutil/pp/Document.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grammars/silver/langutil/pp/Document.sv b/grammars/silver/langutil/pp/Document.sv index 46fbd0d46..cf388404f 100644 --- a/grammars/silver/langutil/pp/Document.sv +++ b/grammars/silver/langutil/pp/Document.sv @@ -253,7 +253,7 @@ top::Document ::= top.outCHorizontals = top.inCHorizontals; top.outRemaining = if horizontal then top.inRemaining - 1 else top.width - top.indent; - top.result = if horizontal then " " else "\n" ++ replicate(top.indent, " "); + top.result = if horizontal then " " else "\n" ++ replicate(max(0, top.indent), " "); top.horizontals = pr.snd; } @@ -331,7 +331,7 @@ top::Document ::= top.outCHorizontals = top.inCHorizontals; top.outRemaining = top.width - top.indent; - top.result = "\n" ++ replicate(top.indent, " "); + top.result = "\n" ++ replicate(max(0, top.indent), " "); top.horizontals = pr.snd; } From 4a80cd70b4f0d7242c95dc7e509334943e5d50d6 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 17 Nov 2023 16:38:47 -0600 Subject: [PATCH 143/283] Handle continued indentation better, with box in Document pp library --- grammars/silver/langutil/unparse/Unparse.sv | 23 +++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/grammars/silver/langutil/unparse/Unparse.sv b/grammars/silver/langutil/unparse/Unparse.sv index b4af7d4dd..038a2c863 100644 --- a/grammars/silver/langutil/unparse/Unparse.sv +++ b/grammars/silver/langutil/unparse/Unparse.sv @@ -56,18 +56,21 @@ AST ::= ast::a -- Attributes computed on parseTree inherited attribute origText::String occurs on AST, ASTs; inherited attribute lineIndent::map:Map occurs on AST, ASTs; +inherited attribute initialIndent::Integer occurs on ASTs; propagate origText, lineIndent on AST, ASTs; synthesized attribute originLoc::Location occurs on AST; synthesized attribute indent::Integer occurs on AST; flowtype indent {lineIndent} on AST; +monoid attribute startColumns::[Integer] occurs on ASTs; +propagate startColumns on ASTs; synthesized attribute origNest::Integer occurs on ASTs; synthesized attribute origLayoutPP::Document occurs on ASTs; -- Attributes computed on the unparse AST inherited attribute parseTree::Maybe; -- This is like a destruct attribute except it's a Maybe attribute parseTree occurs on AST; -attribute parseTree occurs on ASTs; +attribute parseTree occurs on ASTs; synthesized attribute unparseWithLayout::Document occurs on AST, ASTs; synthesized attribute defaultPreLayout::Maybe occurs on AST, ASTs; @@ -95,12 +98,17 @@ aspect production nonterminalAST top::AST ::= prodName::String children::ASTs annotations::NamedASTs { -- On parseTree - top.unparseWithLayout = group(children.unparseWithLayout); + local isBox::Boolean = all(map(gte(_, top.originLoc.column), children.startColumns)); + top.unparseWithLayout = + if isBox + then box(group(children.unparseWithLayout)) + else group(children.unparseWithLayout); top.originLoc = case getParsedOriginLocation(top) of | just(l) -> l | nothing() -> error("Tree does not have a parsed origin: " ++ showOriginInfoChain(top)) end; + children.initialIndent = if isBox then top.originLoc.column else top.indent; -- On unparse AST local parseTree::AST = getParseTree(top); @@ -149,6 +157,7 @@ aspect production consAST top::ASTs ::= h::AST t::ASTs { -- On parseTree + top.startColumns <- [h.originLoc.column]; top.origLayoutPP = case t of | consAST(h2, _) -> @@ -158,8 +167,14 @@ top::ASTs ::= h::AST t::ASTs end; top.origNest = case t of - | consAST(h2, _) -> h2.indent - h.indent - | nilAST() -> 0 + | consAST(h2, _) when h2.originLoc.line > h.originLoc.line -> + h2.indent - top.initialIndent + | _ -> 0 + end; + t.initialIndent = + case t of + | consAST(h2, _) when h2.originLoc.line > h.originLoc.line -> h2.indent + | _ -> top.initialIndent end; -- On unparse AST From e168cccfede911e43a974f11091e4936ab919be8 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 17 Nov 2023 16:45:00 -0600 Subject: [PATCH 144/283] Separate functions for unparsing whole files vs fragments of files --- .../silver/compiler/refactor/BuildProcess.sv | 2 +- grammars/silver/langutil/unparse/Unparse.sv | 29 +++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/grammars/silver/compiler/refactor/BuildProcess.sv b/grammars/silver/compiler/refactor/BuildProcess.sv index 72565e90a..c73d4e6d5 100644 --- a/grammars/silver/compiler/refactor/BuildProcess.sv +++ b/grammars/silver/compiler/refactor/BuildProcess.sv @@ -76,7 +76,7 @@ IO<()> ::= r::Decorated RootSpec do { let fullPath::String = r.grammarSource ++ item.1; text::String <- readFile(fullPath); - let newText::String = show(100, unparse(text, item.2)); + let newText::String = show(100, unparseFile(text, item.2)); when_(text != newText, writeFile(fullPath, newText)); }), r.transformedFiles); diff --git a/grammars/silver/langutil/unparse/Unparse.sv b/grammars/silver/langutil/unparse/Unparse.sv index 038a2c863..20734d78b 100644 --- a/grammars/silver/langutil/unparse/Unparse.sv +++ b/grammars/silver/langutil/unparse/Unparse.sv @@ -14,12 +14,14 @@ imports silver:util:treemap as map; - This is intended for use in e.g. refactoring tools, where transformations can be applied - on the tree, but one would like to turn the tree back into a string without affecting - layout in otherwise-unchanged portions of the tree. + - + - Layout preceeding and following the root of the tree is included in the output. - - - @param origText The original text that was parsed to create the origin of tree. + - @param origText The original text of the file that was parsed to create the origin of tree. - @param tree The concrete syntax tree to unparse. - @return The unparse of the tree, with layout from origText inserted in unchanged portions of the tree. -} -function unparse +function unparseFile Document ::= origText::String tree::a { local parseTree::AST = getParseTree(tree); @@ -41,6 +43,29 @@ Document ::= origText::String tree::a layoutPP(parseTree.indent, postLayout)); } +@{-- + - Like unparseFile, but intended for unparsing a tree corresponding to a fragment of a file. + - Layout preceeding and following the root of the tree is not included. + - + - @param origText The original text of the file that was parsed to create the origin of tree. + - @param tree The concrete syntax tree to unparse. + - @return The unparse of the tree, with layout from origText inserted in unchanged portions of the tree. + -} +function unparseFragment +Document ::= origText::String tree::a +{ + local parseTree::AST = getParseTree(tree); + parseTree.origText = origText; + parseTree.lineIndent = map:fromList(enumerate(map(countIndent, explode("\n", origText)))); + + local ast::AST = reflect(tree); + ast.origText = origText; + ast.lineIndent = parseTree.lineIndent; + ast.parseTree = just(parseTree); + + return ast.unparseWithLayout; +} + function getParseTree AST ::= ast::a { From a19afd4cfc333de0ddae387f21aae336d62dcb30 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 17 Nov 2023 17:53:17 -0600 Subject: [PATCH 145/283] Fix bug with introducing boxes inappropriately --- grammars/silver/langutil/unparse/Unparse.sv | 30 +++++++++++++-------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/grammars/silver/langutil/unparse/Unparse.sv b/grammars/silver/langutil/unparse/Unparse.sv index 20734d78b..b357a6791 100644 --- a/grammars/silver/langutil/unparse/Unparse.sv +++ b/grammars/silver/langutil/unparse/Unparse.sv @@ -27,6 +27,7 @@ Document ::= origText::String tree::a local parseTree::AST = getParseTree(tree); parseTree.origText = origText; parseTree.lineIndent = map:fromList(enumerate(map(countIndent, explode("\n", origText)))); + parseTree.initialIndent = parseTree.indent; local ast::AST = reflect(tree); ast.origText = origText; @@ -57,6 +58,7 @@ Document ::= origText::String tree::a local parseTree::AST = getParseTree(tree); parseTree.origText = origText; parseTree.lineIndent = map:fromList(enumerate(map(countIndent, explode("\n", origText)))); + parseTree.initialIndent = parseTree.indent; local ast::AST = reflect(tree); ast.origText = origText; @@ -81,20 +83,21 @@ AST ::= ast::a -- Attributes computed on parseTree inherited attribute origText::String occurs on AST, ASTs; inherited attribute lineIndent::map:Map occurs on AST, ASTs; -inherited attribute initialIndent::Integer occurs on ASTs; +inherited attribute initialIndent::Integer occurs on AST, ASTs; propagate origText, lineIndent on AST, ASTs; synthesized attribute originLoc::Location occurs on AST; synthesized attribute indent::Integer occurs on AST; flowtype indent {lineIndent} on AST; -monoid attribute startColumns::[Integer] occurs on ASTs; -propagate startColumns on ASTs; +monoid attribute indents::[Integer] occurs on ASTs, AST; +propagate indents on ASTs, AST; +synthesized attribute isBox::Boolean occurs on AST; synthesized attribute origNest::Integer occurs on ASTs; synthesized attribute origLayoutPP::Document occurs on ASTs; -- Attributes computed on the unparse AST inherited attribute parseTree::Maybe; -- This is like a destruct attribute except it's a Maybe -attribute parseTree occurs on AST; +attribute parseTree occurs on AST; attribute parseTree occurs on ASTs; synthesized attribute unparseWithLayout::Document occurs on AST, ASTs; @@ -114,6 +117,7 @@ top::AST ::= | i :: _ -> i | [] -> error(s"Line ${toString(top.originLoc.line)} out of bounds for supplied text!") end; + top.indents <- [top.indent]; top.unparseWithLayout = error("Can't unparse " ++ genericShow(top)); top.defaultPreLayout = nothing(); top.defaultPostLayout = nothing(); @@ -123,22 +127,26 @@ aspect production nonterminalAST top::AST ::= prodName::String children::ASTs annotations::NamedASTs { -- On parseTree - local isBox::Boolean = all(map(gte(_, top.originLoc.column), children.startColumns)); - top.unparseWithLayout = - if isBox - then box(group(children.unparseWithLayout)) - else group(children.unparseWithLayout); top.originLoc = case getParsedOriginLocation(top) of | just(l) -> l | nothing() -> error("Tree does not have a parsed origin: " ++ showOriginInfoChain(top)) end; - children.initialIndent = if isBox then top.originLoc.column else top.indent; + top.isBox = + top.originLoc.endLine > top.originLoc.line && + all(map(\ i::Integer -> i == top.indent || i >= top.originLoc.column, children.indents)); + children.initialIndent = if top.isBox then top.originLoc.column else top.initialIndent; -- On unparse AST + top.unparseWithLayout = + if fromMaybe(false, map((.isBox), top.parseTree)) + then box(group(children.unparseWithLayout)) + else group(children.unparseWithLayout); + local parseTree::AST = getParseTree(top); parseTree.origText = top.origText; parseTree.lineIndent = top.lineIndent; + parseTree.initialIndent = parseTree.indent; children.parseTree = case fromMaybe(parseTree, top.parseTree) of | nonterminalAST(p, c, _) when prodName == p -> just(c) @@ -182,7 +190,6 @@ aspect production consAST top::ASTs ::= h::AST t::ASTs { -- On parseTree - top.startColumns <- [h.originLoc.column]; top.origLayoutPP = case t of | consAST(h2, _) -> @@ -196,6 +203,7 @@ top::ASTs ::= h::AST t::ASTs h2.indent - top.initialIndent | _ -> 0 end; + h.initialIndent = top.initialIndent; t.initialIndent = case t of | consAST(h2, _) when h2.originLoc.line > h.originLoc.line -> h2.indent From 865c7aff9bcd20b6d510def866ee700da8aa4c6f Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 17 Nov 2023 17:55:03 -0600 Subject: [PATCH 146/283] Fix flow errors --- grammars/silver/langutil/unparse/Unparse.sv | 2 ++ 1 file changed, 2 insertions(+) diff --git a/grammars/silver/langutil/unparse/Unparse.sv b/grammars/silver/langutil/unparse/Unparse.sv index b357a6791..685e93532 100644 --- a/grammars/silver/langutil/unparse/Unparse.sv +++ b/grammars/silver/langutil/unparse/Unparse.sv @@ -91,6 +91,7 @@ synthesized attribute indent::Integer occurs on AST; flowtype indent {lineIndent} on AST; monoid attribute indents::[Integer] occurs on ASTs, AST; propagate indents on ASTs, AST; +flowtype indents {lineIndent} on AST, ASTs; synthesized attribute isBox::Boolean occurs on AST; synthesized attribute origNest::Integer occurs on ASTs; synthesized attribute origLayoutPP::Document occurs on ASTs; @@ -118,6 +119,7 @@ top::AST ::= | [] -> error(s"Line ${toString(top.originLoc.line)} out of bounds for supplied text!") end; top.indents <- [top.indent]; + top.isBox = false; top.unparseWithLayout = error("Can't unparse " ++ genericShow(top)); top.defaultPreLayout = nothing(); top.defaultPostLayout = nothing(); From 1147a0c039d1e921ad862c57e0a84779ae51306c Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 20 Nov 2023 13:37:15 -0600 Subject: [PATCH 147/283] Support finer-grained control of child group insertion --- grammars/silver/compiler/refactor/Project.sv | 6 +- grammars/silver/langutil/unparse/Unparse.sv | 60 +++++++++++++++----- 2 files changed, 50 insertions(+), 16 deletions(-) diff --git a/grammars/silver/compiler/refactor/Project.sv b/grammars/silver/compiler/refactor/Project.sv index 402db2cef..449d4cd4a 100644 --- a/grammars/silver/compiler/refactor/Project.sv +++ b/grammars/silver/compiler/refactor/Project.sv @@ -32,12 +32,16 @@ aspect production nonterminalAST top::AST ::= prodName::String children::ASTs annotations::NamedASTs { prodChildLayout <- [ - ("silver:compiler:extension:concisefunctions:shortFunctionDcl", 1, pp" "), + ("silver:compiler:extension:concisefunctions:shortFunctionDcl", 1, line()), ("silver:compiler:extension:concisefunctions:shortFunctionDcl", 3, line()) ]; prodChildIndent <- [ ("silver:compiler:extension:concisefunctions:shortFunctionDcl", 4, 2) ]; + prodChildGroup <- [ + ("silver:compiler:extension:concisefunctions:shortFunctionDcl", 0, 2), + ("silver:compiler:extension:concisefunctions:shortFunctionDcl", 3, 5) + ]; } aspect production terminalAST diff --git a/grammars/silver/langutil/unparse/Unparse.sv b/grammars/silver/langutil/unparse/Unparse.sv index 685e93532..3ef3ceb24 100644 --- a/grammars/silver/langutil/unparse/Unparse.sv +++ b/grammars/silver/langutil/unparse/Unparse.sv @@ -107,7 +107,11 @@ synthesized attribute defaultPostLayout::Maybe occurs on AST, ASTs; inherited attribute childIndex::Integer occurs on ASTs; inherited attribute childLayout::[(Integer, Document)] occurs on ASTs; inherited attribute childIndent::[(Integer, Integer)] occurs on ASTs; -propagate childLayout, childIndent on ASTs; +inherited attribute childGroup::[(Integer, Integer)] occurs on ASTs; +propagate childLayout, childIndent, childGroup on ASTs; + +inherited attribute currentGroup::Maybe occurs on ASTs; +synthesized attribute groupUnparse::Document occurs on ASTs; aspect default production top::AST ::= @@ -142,8 +146,8 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs -- On unparse AST top.unparseWithLayout = if fromMaybe(false, map((.isBox), top.parseTree)) - then box(group(children.unparseWithLayout)) - else group(children.unparseWithLayout); + then box(children.unparseWithLayout) + else children.unparseWithLayout; local parseTree::AST = getParseTree(top); parseTree.origText = top.origText; @@ -168,6 +172,12 @@ top::AST ::= prodName::String children::ASTs annotations::NamedASTs production attribute prodChildIndent::[(String, Integer, Integer)] with ++; prodChildIndent := []; children.childIndent = lookupAll(prodName, prodChildIndent); + + -- Map of productions to start/end indices of children that should be grouped + production attribute prodChildGroup::[(String, Integer, Integer)] with ++; + prodChildGroup := []; + children.childGroup = lookupAll(prodName, prodChildGroup); + children.currentGroup = nothing(); } aspect production terminalAST @@ -213,18 +223,6 @@ top::ASTs ::= h::AST t::ASTs end; -- On unparse AST - top.unparseWithLayout = - h.unparseWithLayout ++ - maybeNest( - fromMaybe(0, - alt(map((.origNest), top.parseTree), - lookup(t.childIndex, top.childIndent))), - fromMaybe(pp"", - alt(map((.origLayoutPP), top.parseTree), - alt(lookup(top.childIndex, top.childLayout), - alt(case t of consAST(_, _) -> h.defaultPostLayout | _ -> empty end, - t.defaultPreLayout)))) ++ - t.unparseWithLayout); h.parseTree = case top.parseTree of | just(consAST(a, _)) -> just(a) @@ -240,6 +238,37 @@ top::ASTs ::= h::AST t::ASTs t.defaultPostLayout, case t of nilAST() -> h.defaultPostLayout | _ -> empty end); t.childIndex = top.childIndex + 1; + + local nestAmount::Integer = + fromMaybe(0, + alt(map((.origNest), top.parseTree), + lookup(t.childIndex, top.childIndent))); + local thisLayout::Document = + fromMaybe(pp"", + alt(map((.origLayoutPP), top.parseTree), + alt(lookup(top.childIndex, top.childLayout), + alt(case t of consAST(_, _) -> h.defaultPostLayout | _ -> empty end, + t.defaultPreLayout)))); + + -- These should be mutually exclusive: + local endGroup::Boolean = top.currentGroup == just(top.childIndex); + local inGroup::Maybe = if endGroup then empty else top.currentGroup; + local newGroup::Maybe = lookup(top.childIndex, top.childGroup); + t.currentGroup = + if top.currentGroup.isJust && newGroup.isJust + then error("Overlapping groups!") + else alt(inGroup, newGroup); + top.unparseWithLayout = + if t.currentGroup.isJust + then + (if newGroup.isJust then group(top.groupUnparse) else pp"") ++ + maybeNest(nestAmount, t.unparseWithLayout) + else + (if endGroup then pp"" else h.unparseWithLayout) ++ + maybeNest(nestAmount, thisLayout ++ t.unparseWithLayout); + top.groupUnparse = + h.unparseWithLayout ++ + if endGroup then pp"" else maybeNest(nestAmount, thisLayout ++ t.groupUnparse); } aspect production nilAST @@ -249,6 +278,7 @@ top::ASTs ::= top.origNest = 0; top.unparseWithLayout = pp""; + top.groupUnparse = error("Group end index ${toString(top.currentGroup.fromJust)} out of bounds"); top.defaultPreLayout = nothing(); top.defaultPostLayout = nothing(); } From 88d91891b42ecc5c9ac6961d0c0abedbfc2eb920 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 20 Nov 2023 20:01:57 -0600 Subject: [PATCH 148/283] Fix bugs with handling newlines --- grammars/silver/langutil/unparse/Unparse.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grammars/silver/langutil/unparse/Unparse.sv b/grammars/silver/langutil/unparse/Unparse.sv index 3ef3ceb24..6e6a7e081 100644 --- a/grammars/silver/langutil/unparse/Unparse.sv +++ b/grammars/silver/langutil/unparse/Unparse.sv @@ -38,7 +38,7 @@ Document ::= origText::String tree::a local postLayout::String = substring(parseTree.originLoc.endIndex, length(origText), origText); return - text(preLayout) ++ + layoutPP(0, preLayout) ++ maybeNest(parseTree.indent, ast.unparseWithLayout ++ layoutPP(parseTree.indent, postLayout)); @@ -185,7 +185,7 @@ top::AST ::= terminalName::String lexeme::String location::Location { top.originLoc = location; - top.unparseWithLayout = text(lexeme); + top.unparseWithLayout = ppImplode(realLine(), map(text, explode("\n", lexeme))); -- Map of terminal names to default layout after the terminal production attribute termPreLayout::[(String, Document)] with ++; From b774a0f82a14a7cdae0dedfe52372f125dd32280 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 20 Nov 2023 20:18:11 -0600 Subject: [PATCH 149/283] Add comment --- grammars/silver/compiler/refactor/Project.sv | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/grammars/silver/compiler/refactor/Project.sv b/grammars/silver/compiler/refactor/Project.sv index 449d4cd4a..4d0faea8a 100644 --- a/grammars/silver/compiler/refactor/Project.sv +++ b/grammars/silver/compiler/refactor/Project.sv @@ -28,6 +28,10 @@ imports silver:rewrite; imports silver:langutil:pp; imports silver:langutil:unparse; +-- Here we specify how layout/indentation should be handled for productions that are +-- introduced as the result of a transformation, and thus don't have layout from the +-- original CST. + aspect production nonterminalAST top::AST ::= prodName::String children::ASTs annotations::NamedASTs { From 312ec1e341fba0b0cd24c534594a64f15a1447c2 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 30 Nov 2023 20:10:00 -0600 Subject: [PATCH 150/283] Add utilities for use in debugger, to check whether a child/local is decorable --- .../translation/java/core/FunctionDcl.sv | 14 +++++++ .../translation/java/core/NamedSignature.sv | 5 +++ .../translation/java/core/NonTerminalDcl.sv | 10 +++++ .../translation/java/core/ProductionBody.sv | 9 +++++ .../translation/java/core/ProductionDcl.sv | 14 +++++++ runtime/java/src/common/DecoratedNode.java | 38 ++++++++++++++++++- runtime/java/src/common/Node.java | 20 +++++++++- 7 files changed, 107 insertions(+), 3 deletions(-) diff --git a/grammars/silver/compiler/translation/java/core/FunctionDcl.sv b/grammars/silver/compiler/translation/java/core/FunctionDcl.sv index ca086fa0a..38bef5900 100644 --- a/grammars/silver/compiler/translation/java/core/FunctionDcl.sv +++ b/grammars/silver/compiler/translation/java/core/FunctionDcl.sv @@ -79,6 +79,7 @@ ${makeIndexDcls(0, whatSig.inputElements)} public static final common.Lazy[][] childInheritedAttributes = new common.Lazy[${toString(length(whatSig.inputElements))}][]; + public static final boolean[] localDecorable = new boolean[num_local_attrs]; public static final common.Lazy[] localAttributes = new common.Lazy[num_local_attrs]; public static final common.Lazy[] localDecSites = new common.Lazy[num_local_attrs]; public static final common.Lazy[][] localInheritedAttributes = new common.Lazy[num_local_attrs][]; @@ -101,6 +102,14 @@ ${whatSig.childDecls} ${contexts.contextMemberDeclTrans} + @Override + public boolean isChildDecorable(final int index) { + switch(index) { +${implode("", map(makeChildDecorableCase(env, _), whatSig.inputElements))} + default: return false; + } + } + @Override public Object getChild(final int index) { switch(index) { @@ -142,6 +151,11 @@ ${flatMap(makeInhOccursContextAccess(whatSig.freeVariables, whatSig.contextInhOc return childInheritedAttributes[key]; } + @Override + public boolean isLocalDecorable(final int key) { + return localDecorable[key]; + } + @Override public common.Lazy getLocal(final int key) { return localAttributes[key]; diff --git a/grammars/silver/compiler/translation/java/core/NamedSignature.sv b/grammars/silver/compiler/translation/java/core/NamedSignature.sv index 4cfe96307..ed52dbe6a 100644 --- a/grammars/silver/compiler/translation/java/core/NamedSignature.sv +++ b/grammars/silver/compiler/translation/java/core/NamedSignature.sv @@ -325,6 +325,11 @@ String ::= n::NamedSignatureElement { return s"\t\t\tcase i_${n.elementName}: return child_${n.elementName};\n"; } +function makeChildDecorableCase +String ::= env::Env n::NamedSignatureElement +{ + return s"\t\t\tcase i_${n.elementName}: return ${toString(isDecorable(n.typerep, env))};\n"; +} function makeChildDecSiteAccessCase String ::= env::Env flowEnv::FlowEnv lhsNtName::String prodName::String n::NamedSignatureElement { diff --git a/grammars/silver/compiler/translation/java/core/NonTerminalDcl.sv b/grammars/silver/compiler/translation/java/core/NonTerminalDcl.sv index d0ba3fd4f..127dfd8f4 100644 --- a/grammars/silver/compiler/translation/java/core/NonTerminalDcl.sv +++ b/grammars/silver/compiler/translation/java/core/NonTerminalDcl.sv @@ -132,6 +132,11 @@ ${if quals.data then "" else s""" return ref.getNode().getNumberOfChildren(); } + @Override + public boolean isChildDecorable(final int child) { + return ref.getNode().isChildDecorable(child); + } + @Override public Object getChild(final int child) { return ref.getNode().getChild(child); @@ -164,6 +169,11 @@ ${if quals.data then "" else s""" throw new common.exceptions.SilverInternalError("Decoration site wrapper node should never be directly decorated!"); } + @Override + public boolean isLocalDecorable(final int child) { + throw new common.exceptions.SilverInternalError("Decoration site wrapper node should never be directly decorated!"); + } + @Override public String getNameOfLocalAttr(final int index) { throw new common.exceptions.SilverInternalError("Decoration site wrapper node should never be directly decorated!"); diff --git a/grammars/silver/compiler/translation/java/core/ProductionBody.sv b/grammars/silver/compiler/translation/java/core/ProductionBody.sv index 539f69dcc..ea1622038 100644 --- a/grammars/silver/compiler/translation/java/core/ProductionBody.sv +++ b/grammars/silver/compiler/translation/java/core/ProductionBody.sv @@ -117,6 +117,10 @@ top::ProductionStmt ::= 'local' 'attribute' a::Name '::' te::TypeExpr ';' else ""; top.setupInh <- s"\t\t${top.frame.className}.occurs_local[${ugh_dcl_hack.attrOccursInitIndex}] = \"${fName}\";\n"; + top.setupInh <- + if isDecorable(te.typerep, top.env) + then s"\t\t${top.frame.className}.localDecorable[${ugh_dcl_hack.attrOccursInitIndex}] = true;\n" + else ""; top.translation = case lookupLocalUniqueRefs(fName, top.flowEnv), lookupLocalRefDecSite(fName, top.flowEnv) of @@ -147,6 +151,10 @@ top::ProductionStmt ::= 'production' 'attribute' a::Name '::' te::TypeExpr ';' else ""; top.setupInh <- s"\t\t${top.frame.className}.occurs_local[${ugh_dcl_hack.attrOccursInitIndex}] = \"${fName}\";\n"; + top.setupInh <- + if isDecorable(te.typerep, top.env) + then s"\t\t${top.frame.className}.localDecorable[${ugh_dcl_hack.attrOccursInitIndex}] = true;\n" + else ""; top.translation = case lookupLocalUniqueRefs(fName, top.flowEnv), lookupLocalRefDecSite(fName, top.flowEnv) of @@ -172,6 +180,7 @@ top::ProductionStmt ::= 'forward' 'production' 'attribute' a::Name ';' s"\t\t${top.frame.className}.localInheritedAttributes[${ugh_dcl_hack.attrOccursInitIndex}] = new common.Lazy[${makeNTName(top.frame.lhsNtName)}.num_inh_attrs];\n"; top.setupInh <- s"\t\t${top.frame.className}.occurs_local[${ugh_dcl_hack.attrOccursInitIndex}] = \"${fName}\";\n"; + top.setupInh <- s"\t\t${top.frame.className}.localDecorable[${ugh_dcl_hack.attrOccursInitIndex}] = true;\n"; -- Decoration through a remote reference has no effect, since all inhs are supplied here via a forward parent top.translation = ""; diff --git a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv index 6281eea14..52dad2a1e 100644 --- a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv +++ b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv @@ -82,6 +82,7 @@ ${makeIndexDcls(0, namedSig.inputElements)} public static final common.Lazy[] synthesizedAttributes = new common.Lazy[${fnnt}.num_syn_attrs]; public static final common.Lazy[][] childInheritedAttributes = new common.Lazy[${toString(length(namedSig.inputElements))}][]; + public static final boolean[] localDecorable = new boolean[num_local_attrs]; public static final common.Lazy[] localAttributes = new common.Lazy[num_local_attrs]; public static final common.Lazy[] localDecSites = new common.Lazy[num_local_attrs]; public static final common.Lazy[][] localInheritedAttributes = new common.Lazy[num_local_attrs][]; @@ -127,6 +128,14 @@ ${namedSig.childDecls} ${contexts.contextMemberDeclTrans} + @Override + public boolean isChildDecorable(final int index) { + switch(index) { +${implode("", map(makeChildDecorableCase(body.env, _), namedSig.inputElements))} + default: return false; + } + } + @Override public Object getChild(final int index) { switch(index) { @@ -217,6 +226,11 @@ ${if isData then "" else s""" return localIsForward[key]; }"""} + @Override + public boolean isLocalDecorable(final int key) { + return localDecorable[key]; + } + @Override public common.Lazy getLocal(final int key) { return localAttributes[key]; diff --git a/runtime/java/src/common/DecoratedNode.java b/runtime/java/src/common/DecoratedNode.java index ba5916cb1..c3b9510ed 100644 --- a/runtime/java/src/common/DecoratedNode.java +++ b/runtime/java/src/common/DecoratedNode.java @@ -285,6 +285,23 @@ public final Node getNode() { return self; } + /** + * Returns the child of this DecoratedNode, decorating it if needed. + * + * This may be useful for debugging/reflection but is not used in the translation; + * prefer calling childAsIs/childDecorated directly for performance. + * + * @param child The number of the child to obtain. + * @return The value of the child. + */ + public Object child(final int child) { + if(self.isChildDecorable(child)) { + return childDecorated(child); + } else { + return childAsIs(child); + } + } + /** * Returns the child of this DecoratedNode, without potentially decorating it. * @@ -325,7 +342,7 @@ public DecoratedNode childDecorated(final int child) { * Separate function to keep {@link #childDecorated} small and inlineable. * This is, after all, the "slow path." */ - private final DecoratedNode obtainDecoratedChild(final int child) { + private final DecoratedNode obtainDecoratedChild(final int child) { Lazy decSite = self.getChildDecSite(child); if(decSite == null) { return createDecoratedChild(child); @@ -343,6 +360,7 @@ private final DecoratedNode obtainDecoratedChild(final int child) { * @return The decorated value of the child. */ public final DecoratedNode createDecoratedChild(final int child) { + assert self.isChildDecorable(child); if(childCreated[child]) { throw new SilverInternalError("Decorated child " + child + " created more than once in " + getDebugID()); } @@ -351,6 +369,23 @@ public final DecoratedNode createDecoratedChild(final int child) { return result; } + /** + * Returns the value of a local, decorating it if needed. + * + * This may be useful for debugging/reflection but is not used in the translation; + * prefer calling localAsIs/localDecorated directly for performance. + * + * @param attribute The index of the local to obtain. + * @return The value of the local. + */ + public Object local(final int attribute) { + if(self.isLocalDecorable(attribute)) { + return localDecorated(attribute); + } else { + return localAsIs(attribute); + } + } + /** * Get the value of a local, caching it for re-use. * @@ -440,6 +475,7 @@ private final DecoratedNode obtainDecoratedLocal(final int attribute) { * @return The decorated value of the local. */ public final DecoratedNode evalLocalDecorated(final int attribute) { + assert self.isLocalDecorable(attribute); if(localCreated[attribute]) { throw new SilverInternalError("Decorated local '" + self.getNameOfLocalAttr(attribute) + "' created more than once in " + getDebugID()); } diff --git a/runtime/java/src/common/Node.java b/runtime/java/src/common/Node.java index ac5a9cb17..da06c4fe4 100644 --- a/runtime/java/src/common/Node.java +++ b/runtime/java/src/common/Node.java @@ -160,6 +160,14 @@ private final SilverException handleUndecorateError(final DecoratedNode context, */ public abstract int getNumberOfChildren(); + /** + * Determine if the child should be automatically decorated. + * + * @param child A number in the range 0 - getNumberofChildren() + * @return True if the child has a decorable type in the signature. + */ + public abstract boolean isChildDecorable(final int child); + /** * Access a (raw) child of this Node. * @@ -196,6 +204,14 @@ private final SilverException handleUndecorateError(final DecoratedNode context, * @return The number of local and production attributes that occur on this production */ public abstract int getNumberOfLocalAttrs(); + + /** + * Determine if the local should be automatically decorated. + * + * @param index The index of a local or production attribute on this Node + * @return True if the local is declared with a decorable type. + */ + public abstract boolean isLocalDecorable(final int index); /** * Used for debugging, stack traces especially. @@ -206,7 +222,7 @@ private final SilverException handleUndecorateError(final DecoratedNode context, public abstract String getNameOfLocalAttr(final int index); /** - * @param name The index of a local or production attribute on this Node + * @param index The index of a local or production attribute on this Node * @return A Lazy to evaluate on a decorated form of this Node, to get the value of the attribute */ public abstract Lazy getLocal(final int index); @@ -227,7 +243,7 @@ private final SilverException handleUndecorateError(final DecoratedNode context, public abstract boolean getLocalIsForward(final int index); /** - * @param key The index for a local, to retrieve inherited attributes for. + * @param index The index for a local, to retrieve inherited attributes for. * @return An array containing the inherited attributes supplied to that local */ public abstract Lazy[] getLocalInheritedAttributes(final int index); From 78bdc5c04d71a99801a4d87a72161eee4b04899e Mon Sep 17 00:00:00 2001 From: unironically Date: Thu, 7 Dec 2023 10:08:33 -0600 Subject: [PATCH 151/283] Concice function documentation --- grammars/silver/compiler/extension/doc/core/AGDcl.sv | 10 ++++++++++ .../compiler/extension/doc/core/DocumentedAGDcl.sv | 1 + 2 files changed, 11 insertions(+) diff --git a/grammars/silver/compiler/extension/doc/core/AGDcl.sv b/grammars/silver/compiler/extension/doc/core/AGDcl.sv index 8d1a58a4b..c2daa26f8 100644 --- a/grammars/silver/compiler/extension/doc/core/AGDcl.sv +++ b/grammars/silver/compiler/extension/doc/core/AGDcl.sv @@ -8,6 +8,7 @@ imports silver:compiler:modification:copper; imports silver:compiler:modification:copper_mda; imports silver:compiler:definition:flow:syntax; imports silver:compiler:modification:collection; +imports silver:compiler:extension:concisefunctions; @@{- @warning INTENDED TO BE INTERFERED WITH like .pp. -} synthesized attribute docUnparse::String occurs on AGDcl; @@ -23,6 +24,15 @@ top::AGDcl ::= 'function' id::Name ns::FunctionSignature body::ProductionBody top.docs := [mkUndocumentedItem(top.docForName, top)]; } +aspect production shortFunctionDcl +top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' +{ + top.docForName = id.name; + top.docUnparse = "`fun " ++ id.name ++ "`   (`" ++ ns.unparse ++ "`)"; + top.docDcls := [(id.name, docDclInfo(id.name, sourceLocation=id.nameLoc, sourceGrammar=top.grammarName))]; + top.docs := [mkUndocumentedItem(top.docForName, top)]; +} + aspect production aspectFunctionDcl top::AGDcl ::= 'aspect' 'function' id::QName ns::AspectFunctionSignature body::ProductionBody { diff --git a/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv b/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv index 548074061..e5297cb01 100644 --- a/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv +++ b/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv @@ -61,6 +61,7 @@ top::AGDcl ::= comment::DocComment_t dcl::AGDcl | nonterminalDcl(_, _, _, tl, _, _) -> (just(getFreeTypeNames(tl.freeVariables)), "nonterminal") | attributeDclInh(_, _, _, tl, _, _, _) -> (just(getFreeTypeNames(tl.freeVariables)), "attribute") | attributeDclSyn(_, _, _, tl, _, _, _) -> (just(getFreeTypeNames(tl.freeVariables)), "attribute") + | shortFunctionDcl (_, _, ns, _, _, _) -> (just(ns.argNames), "function") | _ -> (just([]), if isDoubleComment then "standalone" else "other") end; From 9147b5f177c58a80adf84d6d3a79a6692c4ce28e Mon Sep 17 00:00:00 2001 From: unironically Date: Thu, 7 Dec 2023 11:44:04 -0600 Subject: [PATCH 152/283] Filling in MWDA equations --- grammars/silver/compiler/extension/concisefunctions/Syntax.sv | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv index 34f2be2e3..1f61470c9 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -11,13 +11,15 @@ terminal Fun_kwd 'fun' lexer classes {KEYWORD}; concrete production shortFunctionDcl top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' { - propagate moduleNames; + propagate moduleNames, grammarName, env, flowEnv; top.unparse = "fun " ++ id.unparse ++ ns.unparse ++ " = " ++ e.unparse ++ ";"; local rhs::ProductionRHS = ns.rhs; rhs.env = top.env; + ns.signatureName = top.grammarName ++ ":" ++ id.name; + forwards to globalValueDclConcrete ( 'global', @id, '::', ns.cl, '=>', From 2e695085155d451f443f0035f8ddff19c8eae65f Mon Sep 17 00:00:00 2001 From: unironically Date: Thu, 7 Dec 2023 12:13:12 -0600 Subject: [PATCH 153/283] Removing env from propagate --- grammars/silver/compiler/extension/concisefunctions/Syntax.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv index 1f61470c9..a5db349f9 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -11,7 +11,7 @@ terminal Fun_kwd 'fun' lexer classes {KEYWORD}; concrete production shortFunctionDcl top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' { - propagate moduleNames, grammarName, env, flowEnv; + propagate moduleNames, grammarName, flowEnv; top.unparse = "fun " ++ id.unparse ++ ns.unparse ++ " = " ++ e.unparse ++ ";"; From 1e5565c345162f4035dc5801347a19e2a0449a7d Mon Sep 17 00:00:00 2001 From: unironically Date: Thu, 7 Dec 2023 12:32:32 -0600 Subject: [PATCH 154/283] Setting the env attribute of ns --- grammars/silver/compiler/extension/concisefunctions/Syntax.sv | 1 + 1 file changed, 1 insertion(+) diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv index a5db349f9..6642fef1d 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -19,6 +19,7 @@ top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' rhs.env = top.env; ns.signatureName = top.grammarName ++ ":" ++ id.name; + ns.env = top.env; forwards to globalValueDclConcrete ( From ef2adbaf59b0715c4e7d2d1ec19d569037c2afa8 Mon Sep 17 00:00:00 2001 From: unironically Date: Thu, 7 Dec 2023 17:17:10 -0600 Subject: [PATCH 155/283] Removed redundant env definition --- grammars/silver/compiler/extension/concisefunctions/Syntax.sv | 1 - 1 file changed, 1 deletion(-) diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv index 6642fef1d..08b20481f 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -16,7 +16,6 @@ top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' top.unparse = "fun " ++ id.unparse ++ ns.unparse ++ " = " ++ e.unparse ++ ";"; local rhs::ProductionRHS = ns.rhs; - rhs.env = top.env; ns.signatureName = top.grammarName ++ ":" ++ id.name; ns.env = top.env; From a06fa053416ebd34731719750abe87baac0ec1d4 Mon Sep 17 00:00:00 2001 From: unironically Date: Thu, 7 Dec 2023 17:36:28 -0600 Subject: [PATCH 156/283] Added back not-so redundant env definition --- grammars/silver/compiler/extension/concisefunctions/Syntax.sv | 1 + 1 file changed, 1 insertion(+) diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv index 08b20481f..1bf2f7d84 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -19,6 +19,7 @@ top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' ns.signatureName = top.grammarName ++ ":" ++ id.name; ns.env = top.env; + rhs.env = top.env; forwards to globalValueDclConcrete ( From 56c1a290777c122d64936edbce299ee2a5bfe491 Mon Sep 17 00:00:00 2001 From: unironically Date: Thu, 7 Dec 2023 19:10:55 -0600 Subject: [PATCH 157/283] Added comment to attribute definitions for docgen --- grammars/silver/compiler/extension/concisefunctions/Syntax.sv | 2 ++ 1 file changed, 2 insertions(+) diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv index 1bf2f7d84..a87eefd19 100644 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv @@ -17,8 +17,10 @@ top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' local rhs::ProductionRHS = ns.rhs; + -- The following two lines are only needed for doc generation ns.signatureName = top.grammarName ++ ":" ++ id.name; ns.env = top.env; + rhs.env = top.env; forwards to From d9da014b4790b227bd9eec4a293116594b06fcbb Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 21 Dec 2023 14:59:03 -0600 Subject: [PATCH 158/283] Turn concise functions into a modification --- .../compiler/analysis/uniqueness/Project.sv | 1 + .../compiler/definition/core/Project.sv | 1 + .../compiler/definition/flow/env/Expr.sv | 3 + .../definition/flow/env/FunctionDcl.sv | 20 ++++- .../compiler/definition/flow/env/Root.sv | 1 + .../extension/concisefunctions/Project.sv | 8 -- .../extension/concisefunctions/Syntax.sv | 87 ------------------- .../compiler/extension/doc/core/AGDcl.sv | 2 +- .../extension/implicit_monads/Lambda.sv | 12 +++ .../extension/implicit_monads/Project.sv | 3 +- grammars/silver/compiler/host/Project.sv | 4 +- .../concisefunctions/ConciseFunctions.sv | 70 +++++++++++++++ .../modification/concisefunctions/DclInfo.sv | 42 +++++++++ .../modification/concisefunctions/Project.sv | 13 +++ .../concisefunctions/java/ConciseFunctions.sv | 77 ++++++++++++++++ .../concisefunctions/java/Project.sv | 9 ++ grammars/silver/compiler/refactor/Project.sv | 15 ++-- grammars/silver/core/Location.sv | 2 +- 18 files changed, 261 insertions(+), 109 deletions(-) delete mode 100644 grammars/silver/compiler/extension/concisefunctions/Project.sv delete mode 100644 grammars/silver/compiler/extension/concisefunctions/Syntax.sv create mode 100644 grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv create mode 100644 grammars/silver/compiler/modification/concisefunctions/DclInfo.sv create mode 100644 grammars/silver/compiler/modification/concisefunctions/Project.sv create mode 100644 grammars/silver/compiler/modification/concisefunctions/java/ConciseFunctions.sv create mode 100644 grammars/silver/compiler/modification/concisefunctions/java/Project.sv diff --git a/grammars/silver/compiler/analysis/uniqueness/Project.sv b/grammars/silver/compiler/analysis/uniqueness/Project.sv index f83ccb423..1ff53205e 100644 --- a/grammars/silver/compiler/analysis/uniqueness/Project.sv +++ b/grammars/silver/compiler/analysis/uniqueness/Project.sv @@ -19,4 +19,5 @@ imports silver:compiler:modification:copper_mda; imports silver:compiler:modification:collection; imports silver:compiler:modification:defaultattr; imports silver:compiler:modification:ffi; +imports silver:compiler:modification:concisefunctions; diff --git a/grammars/silver/compiler/definition/core/Project.sv b/grammars/silver/compiler/definition/core/Project.sv index bbd13459c..56e850a34 100644 --- a/grammars/silver/compiler/definition/core/Project.sv +++ b/grammars/silver/compiler/definition/core/Project.sv @@ -31,6 +31,7 @@ option silver:compiler:modification:copper; option silver:compiler:modification:defaultattr; option silver:compiler:modification:collection; option silver:compiler:modification:copper_mda; +option silver:compiler:modification:concisefunctions; -- The list extension doesn't need to be an option here, -- it only needs to be one of silver:compiler:definition:type diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index e09c2ad76..ba79abdb0 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -3,11 +3,14 @@ grammar silver:compiler:definition:flow:env; import silver:compiler:definition:type:syntax; import silver:compiler:definition:type; import silver:compiler:analysis:typechecking:core; + +-- TODO: Extension/modification flow stuff should maybe be moved into these grammars import silver:compiler:modification:copper; import silver:compiler:modification:primitivepattern; import silver:compiler:extension:patternmatching only Arrow_kwd, Vbar_kwd; -- TODO remove import silver:compiler:modification:let_fix; import silver:compiler:modification:lambda_fn; +import silver:compiler:modification:concisefunctions; import silver:compiler:driver:util only isExportedBy; diff --git a/grammars/silver/compiler/definition/flow/env/FunctionDcl.sv b/grammars/silver/compiler/definition/flow/env/FunctionDcl.sv index 7411c6c68..b62714f4b 100644 --- a/grammars/silver/compiler/definition/flow/env/FunctionDcl.sv +++ b/grammars/silver/compiler/definition/flow/env/FunctionDcl.sv @@ -1,9 +1,10 @@ grammar silver:compiler:definition:flow:env; import silver:compiler:definition:type only typerep; -import silver:compiler:definition:flow:driver only ProductionGraph, FlowType, constructFunctionGraph; +import silver:compiler:definition:flow:driver only ProductionGraph, FlowType, constructFunctionGraph, constructAnonymousGraph; import silver:compiler:driver:util only RootSpec; -- actually we just want the occurrences import silver:compiler:definition:type:syntax; -- actually we just want the occurrences +import silver:compiler:modification:concisefunctions; attribute flowEnv occurs on FunctionSignature, FunctionLHS; propagate flowEnv on FunctionSignature, FunctionLHS; @@ -36,3 +37,20 @@ top::AGDcl ::= 'aspect' 'function' id::QName ns::AspectFunctionSignature body::P constructFunctionGraph(namedSig, top.flowEnv, top.env, myProds, myFlow); } +aspect production shortFunctionDcl +top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' +{ + e.decSiteVertexInfo = nothing(); + e.alwaysDecorated = false; + + -- oh no again! + local myFlow :: EnvTree = head(searchEnvTree(top.grammarName, top.compiledGrammars)).grammarFlowTypes; + local myProds :: EnvTree = head(searchEnvTree(top.grammarName, top.compiledGrammars)).productionFlowGraphs; + + production myFlowGraph :: ProductionGraph = + constructAnonymousGraph(e.flowDefs, top.env, myProds, myFlow); + + top.flowDefs <- flatMap( + \ ie::NamedSignatureElement -> occursContextDeps(namedSig, top.env, ie.typerep, rhsVertexType(ie.elementName)), + namedSig.inputElements); +} diff --git a/grammars/silver/compiler/definition/flow/env/Root.sv b/grammars/silver/compiler/definition/flow/env/Root.sv index 3219b4401..e70026866 100644 --- a/grammars/silver/compiler/definition/flow/env/Root.sv +++ b/grammars/silver/compiler/definition/flow/env/Root.sv @@ -5,6 +5,7 @@ import silver:compiler:definition:concrete_syntax; import silver:compiler:modification:defaultattr; import silver:compiler:modification:collection; import silver:compiler:modification:copper; +import silver:compiler:modification:concisefunctions; attribute flowDefs, refDefs, specDefs, flowEnv occurs on Root, AGDcls, AGDcl, Grammar; flowtype flowDefs {decorate} on Root, AGDcls, AGDcl, Grammar; diff --git a/grammars/silver/compiler/extension/concisefunctions/Project.sv b/grammars/silver/compiler/extension/concisefunctions/Project.sv deleted file mode 100644 index ee259e8ad..000000000 --- a/grammars/silver/compiler/extension/concisefunctions/Project.sv +++ /dev/null @@ -1,8 +0,0 @@ -grammar silver:compiler:extension:concisefunctions; - -imports silver:compiler:definition:core; -imports silver:compiler:modification:lambda_fn; -imports silver:compiler:definition:type:syntax hiding Arrow_t; -- We use lambda_fn:Arrow_t -imports silver:compiler:definition:type; -imports silver:compiler:definition:env; -imports silver:compiler:definition:flow:env; \ No newline at end of file diff --git a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv b/grammars/silver/compiler/extension/concisefunctions/Syntax.sv deleted file mode 100644 index a87eefd19..000000000 --- a/grammars/silver/compiler/extension/concisefunctions/Syntax.sv +++ /dev/null @@ -1,87 +0,0 @@ -grammar silver:compiler:extension:concisefunctions; - -terminal Fun_kwd 'fun' lexer classes {KEYWORD}; - -{-- - - Concise function declarations - these forward to globals with lambda expressions - - @param id The name of the concise function - - @param ns The signature of the function - - @param e The expression that serves as the body of the function - -} -concrete production shortFunctionDcl -top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' -{ - propagate moduleNames, grammarName, flowEnv; - - top.unparse = "fun " ++ id.unparse ++ ns.unparse ++ " = " ++ e.unparse ++ ";"; - - local rhs::ProductionRHS = ns.rhs; - - -- The following two lines are only needed for doc generation - ns.signatureName = top.grammarName ++ ":" ++ id.name; - ns.env = top.env; - - rhs.env = top.env; - - forwards to - globalValueDclConcrete ( - 'global', @id, '::', ns.cl, '=>', - funTypeExpr ('(', psignature(presentSignatureLhs(ns.lhs.tyExpr), '::=', rhs.tyExprs), ')'), - '=', lambda_c('\', rhs.toLamRHS, '->', @e), ';' - ); -} - -synthesized attribute cl::ConstraintList occurs on FunctionSignature; -synthesized attribute lhs::FunctionLHS occurs on FunctionSignature; -synthesized attribute rhs::ProductionRHS occurs on FunctionSignature; - -aspect production functionSignature -top::FunctionSignature ::= cl::ConstraintList '=>' lhs::FunctionLHS '::=' rhs::ProductionRHS -{ - top.cl = cl; - top.lhs = lhs; - top.rhs = rhs; -} - -aspect production functionSignatureNoCL -top::FunctionSignature ::= lhs::FunctionLHS '::=' rhs::ProductionRHS -{ - top.cl = nilConstraint(); - top.lhs = lhs; - top.rhs = rhs; -} - -synthesized attribute tyExpr::TypeExpr occurs on FunctionLHS; - -aspect production functionLHS -top::FunctionLHS ::= t::TypeExpr -{ - top.tyExpr = t; -} - -synthesized attribute toLamRHS::LambdaRHS occurs on ProductionRHS; -synthesized attribute tyExprs::TypeExprs occurs on ProductionRHS; - -aspect production productionRHSNil -top::ProductionRHS ::= -{ - top.toLamRHS = lambdaRHSNil(); - top.tyExprs = typeListNone(); -} - -aspect production productionRHSCons -top::ProductionRHS ::= h::ProductionRHSElem t::ProductionRHS -{ - top.toLamRHS = lambdaRHSCons(h.toLamRHSElem, t.toLamRHS); - top.tyExprs = typeListCons(h.tyExpr, t.tyExprs); -} - -synthesized attribute toLamRHSElem::LambdaRHSElem occurs on ProductionRHSElem; -attribute tyExpr occurs on ProductionRHSElem; - -aspect production productionRHSElem -top::ProductionRHSElem ::= id::Name '::' t::TypeExpr -{ - top.toLamRHSElem = lambdaRHSElemIdTy(id, '::', t); - top.tyExpr = t; -} \ No newline at end of file diff --git a/grammars/silver/compiler/extension/doc/core/AGDcl.sv b/grammars/silver/compiler/extension/doc/core/AGDcl.sv index c2daa26f8..990813e74 100644 --- a/grammars/silver/compiler/extension/doc/core/AGDcl.sv +++ b/grammars/silver/compiler/extension/doc/core/AGDcl.sv @@ -8,7 +8,7 @@ imports silver:compiler:modification:copper; imports silver:compiler:modification:copper_mda; imports silver:compiler:definition:flow:syntax; imports silver:compiler:modification:collection; -imports silver:compiler:extension:concisefunctions; +imports silver:compiler:modification:concisefunctions; @@{- @warning INTENDED TO BE INTERFERED WITH like .pp. -} synthesized attribute docUnparse::String occurs on AGDcl; diff --git a/grammars/silver/compiler/extension/implicit_monads/Lambda.sv b/grammars/silver/compiler/extension/implicit_monads/Lambda.sv index 36e1ee24a..f9b3db9e4 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Lambda.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Lambda.sv @@ -27,3 +27,15 @@ top::Expr ::= q::Decorated! QName else []; top.monadRewritten = baseExpr(new(q)); } + +aspect production shortFunParamReference +top::Expr ::= q::Decorated! QName +{ + top.merrors := []; + propagate mDownSubst, mUpSubst; + top.mtyperep = q.lookupValue.typeScheme.monoType; + top.monadicNames = if top.monadicallyUsed + then [baseExpr(new(q))] + else []; + top.monadRewritten = baseExpr(new(q)); +} diff --git a/grammars/silver/compiler/extension/implicit_monads/Project.sv b/grammars/silver/compiler/extension/implicit_monads/Project.sv index c542f9274..5788b1179 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Project.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Project.sv @@ -20,4 +20,5 @@ imports silver:compiler:modification:list; imports silver:compiler:modification:lambda_fn; imports silver:compiler:modification:let_fix; imports silver:compiler:modification:primitivepattern; -imports silver:compiler:modification:copper; \ No newline at end of file +imports silver:compiler:modification:copper; +imports silver:compiler:modification:concisefunctions; diff --git a/grammars/silver/compiler/host/Project.sv b/grammars/silver/compiler/host/Project.sv index b76bdda10..7ec09dc24 100644 --- a/grammars/silver/compiler/host/Project.sv +++ b/grammars/silver/compiler/host/Project.sv @@ -17,6 +17,7 @@ exports silver:compiler:host:core; -- These are explicitly annotated as "options" within the core host language exports silver:compiler:modification:let_fix; exports silver:compiler:modification:lambda_fn; +exports silver:compiler:modification:concisefunctions; exports silver:compiler:modification:collection; exports silver:compiler:modification:primitivepattern; exports silver:compiler:modification:ffi; @@ -50,7 +51,6 @@ exports silver:compiler:extension:attrsection; exports silver:compiler:extension:implicit_monads; exports silver:compiler:extension:data; exports silver:compiler:extension:deriving; -exports silver:compiler:extension:concisefunctions; -- Other generally useful stuff: exports silver:compiler:translation:java; @@ -58,4 +58,4 @@ exports silver:compiler:driver; exports silver:compiler:analysis:warnings:flow; exports silver:compiler:analysis:warnings:exporting; exports silver:compiler:langserver; -exports silver:compiler:refactor; +--exports silver:compiler:refactor; diff --git a/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv b/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv new file mode 100644 index 000000000..02065d003 --- /dev/null +++ b/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv @@ -0,0 +1,70 @@ +grammar silver:compiler:modification:concisefunctions; + +import silver:util:treeset as ts; + +terminal Fun_kwd 'fun' lexer classes {KEYWORD}; + +{-- + - Concise function declarations - these are conceptually similar to globals with lambda expressions + - @param id The name of the concise function + - @param ns The signature of the function + - @param e The expression that serves as the body of the function + -} +concrete production shortFunctionDcl +top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' +{ + top.unparse = "fun " ++ id.unparse ++ ns.unparse ++ " = " ++ e.unparse ++ ";"; + + propagate grammarName, compiledGrammars, config, errors; + + production fName :: String = top.grammarName ++ ":" ++ id.name; + production namedSig :: NamedSignature = ns.namedSignature; + + top.defs := [shortFunDef(top.grammarName, id.nameLoc, namedSig)]; + + e.downSubst = emptySubst(); + e.finalSubst = e.upSubst; + + top.errors <- + if length(getValueDclAll(fName, top.env)) > 1 + then [errFromOrigin(id, "Value '" ++ fName ++ "' is already bound.")] + else []; + + production attribute sigDefs :: [Def] with ++; + sigDefs := ns.shortFunctionDefs; + + production attribute allLexicalTyVars :: [String]; + allLexicalTyVars = nub(ns.lexicalTypeVariables); + sigDefs <- addNewLexicalTyVars(top.grammarName, ns.lexicalTyVarKinds, allLexicalTyVars); + + ns.signatureName = fName; + ns.env = newScopeEnv(sigDefs, top.env); + + e.env = occursEnv(ns.occursDefs, newScopeEnv(sigDefs ++ ns.constraintDefs, top.env)); + + e.frame = functionContext(namedSig, myFlowGraph, sourceGrammar=top.grammarName); + e.originRules = []; + e.isRoot = true; +} + +monoid attribute shortFunctionDefs::[Def] occurs on FunctionSignature, ProductionRHS, ProductionRHSElem; +propagate shortFunctionDefs on FunctionSignature, ProductionRHS; + +aspect shortFunctionDefs on top::ProductionRHSElem using := of +| productionRHSElem(id, _, t) -> [shortFunParamDef(top.grammarName, id.nameLoc, id.name, t.typerep)] +| productionRHSElemType(_) -> [] +end; + +abstract production shortFunParamReference +top::Expr ::= q::Decorated! QName +{ + undecorates to baseExpr(q); + top.unparse = q.unparse; + + propagate errors; + top.freeVars := ts:fromList([q.name]); + + top.typerep = q.lookupValue.typeScheme.monoType; + + propagate downSubst, upSubst; +} diff --git a/grammars/silver/compiler/modification/concisefunctions/DclInfo.sv b/grammars/silver/compiler/modification/concisefunctions/DclInfo.sv new file mode 100644 index 000000000..340aec11b --- /dev/null +++ b/grammars/silver/compiler/modification/concisefunctions/DclInfo.sv @@ -0,0 +1,42 @@ +grammar silver:compiler:modification:concisefunctions; + +abstract production shortFunDcl +top::ValueDclInfo ::= ns::NamedSignature +{ + propagate isEqual; + top.fullName = ns.fullName; + + top.namedSignature = ns; + top.typeScheme = ns.typeScheme; + + top.refDispatcher = functionReference; -- Same API + top.defDispatcher = errorValueDef; -- should be impossible (never in scope at production level?) + top.defLHSDispatcher = errorDefLHS; -- ditto + top.transDefLHSDispatcher = errorTransAttrDefLHS; +} + +abstract production shortFunParamDcl +top::ValueDclInfo ::= fn::String ty::Type +{ + top.fullName = fn; + propagate isEqual; + + top.typeScheme = monoType(ty); + + top.refDispatcher = shortFunParamReference; + top.defDispatcher = errorValueDef; -- should be impossible (never in scope at production level?) + top.defLHSDispatcher = errorDefLHS; -- ditto + top.transDefLHSDispatcher = errorTransAttrDefLHS; +} + +function shortFunDef +Def ::= sg::String sl::Location ns::NamedSignature +{ + return valueDef(defaultEnvItem(shortFunDcl(ns,sourceGrammar=sg,sourceLocation=sl))); +} + +function shortFunParamDef +Def ::= sg::String sl::Location fn::String ty::Type +{ + return valueDef(defaultEnvItem(shortFunParamDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); +} diff --git a/grammars/silver/compiler/modification/concisefunctions/Project.sv b/grammars/silver/compiler/modification/concisefunctions/Project.sv new file mode 100644 index 000000000..492334576 --- /dev/null +++ b/grammars/silver/compiler/modification/concisefunctions/Project.sv @@ -0,0 +1,13 @@ +grammar silver:compiler:modification:concisefunctions; + +imports silver:compiler:definition:core; +imports silver:compiler:modification:lambda_fn; +imports silver:compiler:definition:type:syntax hiding Arrow_t; -- We use lambda_fn:Arrow_t +imports silver:compiler:definition:type; +imports silver:compiler:definition:env; +imports silver:compiler:definition:flow:env; +imports silver:compiler:definition:flow:driver only ProductionGraph, FlowType, constructAnonymousGraph; +imports silver:compiler:analysis:typechecking:core; +imports silver:compiler:driver:util; + +exports silver:compiler:modification:concisefunctions:java with silver:compiler:translation:java:core; diff --git a/grammars/silver/compiler/modification/concisefunctions/java/ConciseFunctions.sv b/grammars/silver/compiler/modification/concisefunctions/java/ConciseFunctions.sv new file mode 100644 index 000000000..a7294c3d1 --- /dev/null +++ b/grammars/silver/compiler/modification/concisefunctions/java/ConciseFunctions.sv @@ -0,0 +1,77 @@ +grammar silver:compiler:modification:concisefunctions:java; + +aspect production shortFunctionDcl +top::AGDcl ::= _ id::Name ns::FunctionSignature '=' e::Expr ';' +{ + local className :: String = "P" ++ id.name; + local commaIfArgs :: String = if length(namedSig.contexts) + length(namedSig.inputElements) != 0 then "," else ""; + + local contexts::Contexts = foldContexts(namedSig.contexts); + contexts.boundVariables = namedSig.freeVariables; + + -- This mirrors normal function translation, except that it doesn't inherit from Node. + top.genFiles := [(className ++ ".java", s""" +package ${makeName(top.grammarName)}; + +import silver.core.*; + +// ${ns.unparse} +public final class ${className} { + + public static ${namedSig.outputElement.typerep.transType} invoke(final common.OriginContext originCtx ${commaIfArgs} ${namedSig.javaSignature}) { + final common.DecoratedNode context = common.TopNode.singleton; + try { + //${e.unparse} + return ${e.translation}; + } catch(Throwable t) { + throw new common.exceptions.TraceException("Error while evaluating function ${namedSig.fullName}", t); + } + } + +${if null(namedSig.contexts) -- Can only use a singleton when there aren't contexts. + then s""" + public static final common.NodeFactory<${namedSig.outputElement.typerep.transCovariantType}> factory = new Factory(); +""" else s""" + public static final common.NodeFactory<${namedSig.outputElement.typerep.transCovariantType}> getFactory(${contexts.contextParamTrans}) { + return new Factory(${implode(", ", map(\ c::Context -> decorate c with {boundVariables = namedSig.freeVariables;}.contextRefElem, namedSig.contexts))}); + } +"""} + + public static final class Factory extends common.NodeFactory<${namedSig.outputElement.typerep.transType}> { +${contexts.contextMemberDeclTrans} + + public Factory(${contexts.contextParamTrans}) { +${contexts.contextInitTrans} + } + + @Override + public final ${namedSig.outputElement.typerep.transType} invoke(final common.OriginContext originCtx, final Object[] children, final Object[] namedNotApplicable) { + return ${className}.invoke(${implode(", ", + ["originCtx"] ++ + map(\ c::Context -> decorate c with {boundVariables = namedSig.freeVariables;}.contextRefElem, namedSig.contexts) ++ + unpackChildren(0, namedSig.inputElements))}); + } + + @Override + public final common.AppTypeRep getType() { +${makeTyVarDecls(3, namedSig.typerep.freeVariables)} + return ${transFreshTypeRep(namedSig.typerep)}; + } + + @Override + public final String toString() { + return "${fName}"; + } + }; + +} +""")]; +} + +aspect production shortFunParamReference +top::Expr ::= q::Decorated! QName +{ + top.translation = s"common.Util.<${top.finalType.transType}>demand(${top.lazyTranslation})"; + top.lazyTranslation = "c_" ++ q.lookupValue.fullName; + top.initTransDecSites := ""; +} diff --git a/grammars/silver/compiler/modification/concisefunctions/java/Project.sv b/grammars/silver/compiler/modification/concisefunctions/java/Project.sv new file mode 100644 index 000000000..250a1720c --- /dev/null +++ b/grammars/silver/compiler/modification/concisefunctions/java/Project.sv @@ -0,0 +1,9 @@ +grammar silver:compiler:modification:concisefunctions:java; + +imports silver:compiler:definition:core; +imports silver:compiler:definition:env; +imports silver:compiler:definition:type; +imports silver:compiler:translation:java; +imports silver:compiler:analysis:typechecking:core; +imports silver:compiler:modification:concisefunctions; + diff --git a/grammars/silver/compiler/refactor/Project.sv b/grammars/silver/compiler/refactor/Project.sv index 4d0faea8a..f614504de 100644 --- a/grammars/silver/compiler/refactor/Project.sv +++ b/grammars/silver/compiler/refactor/Project.sv @@ -14,6 +14,7 @@ imports silver:compiler:analysis:typechecking:core; imports silver:compiler:modification:let_fix; imports silver:compiler:modification:lambda_fn; +imports silver:compiler:modification:concisefunctions; imports silver:compiler:modification:collection; imports silver:compiler:modification:primitivepattern; imports silver:compiler:modification:ffi; @@ -22,8 +23,6 @@ imports silver:compiler:modification:defaultattr; imports silver:compiler:modification:list; imports silver:compiler:modification:copper_mda; -imports silver:compiler:extension:concisefunctions; - imports silver:rewrite; imports silver:langutil:pp; imports silver:langutil:unparse; @@ -36,15 +35,15 @@ aspect production nonterminalAST top::AST ::= prodName::String children::ASTs annotations::NamedASTs { prodChildLayout <- [ - ("silver:compiler:extension:concisefunctions:shortFunctionDcl", 1, line()), - ("silver:compiler:extension:concisefunctions:shortFunctionDcl", 3, line()) + ("silver:compiler:modification:concisefunctions:shortFunctionDcl", 1, line()), + ("silver:compiler:modification:concisefunctions:shortFunctionDcl", 3, line()) ]; prodChildIndent <- [ - ("silver:compiler:extension:concisefunctions:shortFunctionDcl", 4, 2) + ("silver:compiler:modification:concisefunctions:shortFunctionDcl", 4, 2) ]; prodChildGroup <- [ - ("silver:compiler:extension:concisefunctions:shortFunctionDcl", 0, 2), - ("silver:compiler:extension:concisefunctions:shortFunctionDcl", 3, 5) + ("silver:compiler:modification:concisefunctions:shortFunctionDcl", 0, 2), + ("silver:compiler:modification:concisefunctions:shortFunctionDcl", 3, 5) ]; } @@ -56,7 +55,7 @@ top::AST ::= _ _ _ ]; termPostLayout <- [ ("silver:compiler:definition:core:Global_kwd", pp" "), - ("silver:compiler:extension:concisefunctions:Fun_kwd", pp" "), + ("silver:compiler:modification:concisefunctions:Fun_kwd", pp" "), ("silver:compiler:definition:core:Comma_t", pp" "), ("silver:compiler:definition:core:Equal_t", pp" ") ]; diff --git a/grammars/silver/core/Location.sv b/grammars/silver/core/Location.sv index ec57d6888..006e5fd7d 100644 --- a/grammars/silver/core/Location.sv +++ b/grammars/silver/core/Location.sv @@ -105,7 +105,7 @@ Location ::= parent::Location child::Location linesOffset::Integer firstLineCols @{-- - A helper constructor for location information, for built-in locations - - - @param module The name of the extension/modifcation/module defining the location + - @param module The name of the extension/modification/module defining the location -} function builtinLoc Location ::= module::String From 0ccba1eb5847cc29844608543756dee2ba9f8cbe Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 21 Dec 2023 15:10:59 -0600 Subject: [PATCH 159/283] Re-enable refactor grammar --- grammars/silver/compiler/host/Project.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/compiler/host/Project.sv b/grammars/silver/compiler/host/Project.sv index 7ec09dc24..82adc01b4 100644 --- a/grammars/silver/compiler/host/Project.sv +++ b/grammars/silver/compiler/host/Project.sv @@ -58,4 +58,4 @@ exports silver:compiler:driver; exports silver:compiler:analysis:warnings:flow; exports silver:compiler:analysis:warnings:exporting; exports silver:compiler:langserver; ---exports silver:compiler:refactor; +exports silver:compiler:refactor; From 91fc188aa90b25e7f3affd79ac6e94266b359a3b Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 21 Dec 2023 16:33:12 -0600 Subject: [PATCH 160/283] Fix type constraint env bugs --- .../concisefunctions/ConciseFunctions.sv | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv b/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv index 02065d003..c946c1d0c 100644 --- a/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv +++ b/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv @@ -22,8 +22,13 @@ top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' top.defs := [shortFunDef(top.grammarName, id.nameLoc, namedSig)]; + local errCheck1 :: TypeCheck = check(e.typerep, namedSig.outputElement.typerep); + e.downSubst = emptySubst(); - e.finalSubst = e.upSubst; + errCheck1.downSubst = e.upSubst; + + e.finalSubst = errCheck1.upSubst; + errCheck1.finalSubst = errCheck1.upSubst; top.errors <- if length(getValueDclAll(fName, top.env)) > 1 @@ -40,7 +45,7 @@ top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' ns.signatureName = fName; ns.env = newScopeEnv(sigDefs, top.env); - e.env = occursEnv(ns.occursDefs, newScopeEnv(sigDefs ++ ns.constraintDefs, top.env)); + e.env = occursEnv(ns.shortFunctionOccursDefs, newScopeEnv(sigDefs ++ ns.shortFunctionConstraintDefs, top.env)); e.frame = functionContext(namedSig, myFlowGraph, sourceGrammar=top.grammarName); e.originRules = []; @@ -48,8 +53,24 @@ top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' } monoid attribute shortFunctionDefs::[Def] occurs on FunctionSignature, ProductionRHS, ProductionRHSElem; +synthesized attribute shortFunctionConstraintDefs::[Def] occurs on FunctionSignature; +synthesized attribute shortFunctionOccursDefs::[OccursDclInfo] occurs on FunctionSignature; propagate shortFunctionDefs on FunctionSignature, ProductionRHS; +aspect production functionSignature +top::FunctionSignature ::= cl::ConstraintList '=>' lhs::FunctionLHS '::=' rhs::ProductionRHS +{ + -- Need to override constraintPos + production clGlobal::ConstraintList = new(cl); + clGlobal.env = top.env; + clGlobal.flowEnv = top.flowEnv; + clGlobal.grammarName = top.grammarName; + clGlobal.constraintPos = globalPos(top.namedSignature.freeVariables, sourceGrammar=top.grammarName); + + top.shortFunctionConstraintDefs = clGlobal.defs; + top.shortFunctionOccursDefs = clGlobal.occursDefs; +} + aspect shortFunctionDefs on top::ProductionRHSElem using := of | productionRHSElem(id, _, t) -> [shortFunParamDef(top.grammarName, id.nameLoc, id.name, t.typerep)] | productionRHSElemType(_) -> [] From 5a24defa5624d4f67c5ac96afcc946be031bd281 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 20 Nov 2023 14:00:57 -0600 Subject: [PATCH 161/283] Automated refactor to use concise functions --- .../analysis/uniqueness/UniqueRefSite.sv | 8 +- .../analysis/warnings/exporting/Graph.sv | 22 +- .../compiler/analysis/warnings/flow/Inh.sv | 104 ++-- .../compiler/analysis/warnings/flow/MWDA.sv | 7 +- .../analysis/warnings/flow/MwdaFlag.sv | 27 +- .../silver/compiler/composed/Default/Main.sv | 1 + .../definition/concrete_syntax/ast/CstAst.sv | 6 +- .../definition/concrete_syntax/ast/Syntax.sv | 38 +- .../silver/compiler/definition/core/AGDcl.sv | 15 +- .../silver/compiler/definition/core/Expr.sv | 50 +- .../compiler/definition/core/ModuleStmts.sv | 7 +- .../silver/compiler/definition/core/QName.sv | 19 +- .../silver/compiler/definition/env/Defs.sv | 190 +++---- .../silver/compiler/definition/env/Env.sv | 138 ++---- .../silver/compiler/definition/env/EnvItem.sv | 7 +- .../silver/compiler/definition/env/EnvTree.sv | 43 +- .../compiler/definition/env/NamedSignature.sv | 19 +- .../compiler/definition/flow/ast/Flow.sv | 20 +- .../compiler/definition/flow/ast/Vertex.sv | 18 +- .../definition/flow/driver/DumpGraph.sv | 28 +- .../definition/flow/driver/FlowGraph.sv | 47 +- .../definition/flow/driver/FlowTypes.sv | 55 +- .../definition/flow/driver/ProductionGraph.sv | 115 ++--- .../definition/flow/driver/StitchPoint.sv | 31 +- .../compiler/definition/flow/env/FlowEnv.sv | 175 ++----- .../definition/flow/env/ProductionBody.sv | 14 +- .../compiler/definition/type/Helpers.sv | 21 +- .../definition/type/PrettyPrinting.sv | 32 +- .../compiler/definition/type/Substitutions.sv | 119 ++--- .../silver/compiler/definition/type/Type.sv | 18 +- .../compiler/definition/type/Unification.sv | 16 +- .../definition/type/syntax/AspectDcl.sv | 8 +- .../silver/compiler/driver/BuildProcess.sv | 86 ++-- grammars/silver/compiler/driver/Command.sv | 37 +- .../silver/compiler/driver/CompileFiles.sv | 38 +- .../silver/compiler/driver/CompileGrammar.sv | 70 +-- .../compiler/driver/CompileInterface.sv | 20 +- .../silver/compiler/driver/DriverAction.sv | 21 +- .../silver/compiler/driver/util/BuildEnv.sv | 6 +- .../compiler/driver/util/Compilation.sv | 7 +- .../compiler/driver/util/DriverAction.sv | 7 +- .../compiler/driver/util/ModuleGraph.sv | 41 +- .../silver/compiler/driver/util/RootSpec.sv | 14 +- grammars/silver/compiler/driver/util/Util.sv | 20 +- .../extension/convenience/Children.sv | 7 +- .../compiler/extension/convenience/Lists.sv | 11 +- .../convenienceaspects/AbstractSyntax.sv | 91 ++-- .../compiler/extension/deriving/Derive.sv | 16 +- .../extension/doc/core/CommentItem.sv | 14 +- .../compiler/extension/doc/core/DocConfig.sv | 109 ++-- .../extension/doc/core/DocumentedAGDcl.sv | 28 +- .../compiler/extension/doc/core/RootSpec.sv | 51 +- .../extension/doc/core/doclang/DclComment.sv | 22 +- .../compiler/extension/easyterminal/Env.sv | 14 +- .../extension/implicit_monads/Case.sv | 28 +- .../extension/implicit_monads/DclInfo.sv | 28 +- .../extension/implicit_monads/Expr.sv | 55 +- .../implicit_monads/ProductionBody.sv | 17 +- .../extension/implicit_monads/Util.sv | 175 +++---- .../extension/patternmatching/Case.sv | 239 ++++----- .../extension/patternmatching/PatternTypes.sv | 15 +- .../extension/strategyattr/StrategyExpr.sv | 32 +- .../compiler/extension/testing/Helper.sv | 30 +- .../compiler/extension/testing/WrongCode.sv | 7 +- .../compiler/extension/treegen/Arbitrary.sv | 7 +- .../compiler/langserver/ReferenceLocations.sv | 64 +-- .../compiler/metatranslation/Translation.sv | 12 +- .../modification/collection/DclInfo.sv | 21 +- .../collection/java/Collection.sv | 6 +- .../modification/copper/BuildProcess.sv | 9 +- .../compiler/modification/copper/Env.sv | 71 +-- .../modification/copper_mda/Analysis.sv | 11 +- .../modification/defaultattr/DefaultAttr.sv | 7 +- .../modification/ffi/java/FunctionDcl.sv | 11 +- .../compiler/modification/ffi/util/FFIUtil.sv | 34 +- .../modification/lambda_fn/DclInfo.sv | 8 +- .../compiler/modification/let_fix/DclInfo.sv | 8 +- .../compiler/modification/let_fix/java/Let.sv | 13 +- .../modification/primitivepattern/Types.sv | 17 +- .../silver/compiler/refactor/BuildProcess.sv | 7 +- .../translation/java/core/ClassDcl.sv | 6 +- .../compiler/translation/java/core/Expr.sv | 39 +- .../translation/java/core/NamedSignature.sv | 95 ++-- .../compiler/translation/java/core/Project.sv | 55 +- .../translation/java/core/RootSpec.sv | 7 +- .../translation/java/driver/BuildProcess.sv | 27 +- .../compiler/translation/java/type/Context.sv | 6 +- grammars/silver/core/Alternative.sv | 6 +- grammars/silver/core/Applicative.sv | 28 +- grammars/silver/core/Apply.sv | 27 +- grammars/silver/core/Bind.sv | 22 +- grammars/silver/core/DivisionRing.sv | 8 +- grammars/silver/core/Either.sv | 21 +- grammars/silver/core/EuclideanRing.sv | 28 +- grammars/silver/core/Function.sv | 63 +-- grammars/silver/core/Functor.sv | 20 +- grammars/silver/core/Group.sv | 14 +- grammars/silver/core/IO.sv | 12 +- grammars/silver/core/IOMisc.sv | 12 +- grammars/silver/core/IOToken.sv | 12 +- grammars/silver/core/List.sv | 469 ++++++------------ grammars/silver/core/Location.sv | 20 +- grammars/silver/core/Maybe.sv | 52 +- grammars/silver/core/Monad.sv | 17 +- grammars/silver/core/Monoid.sv | 27 +- grammars/silver/core/Ord.sv | 24 +- grammars/silver/core/Origins.sv | 133 ++--- grammars/silver/core/Pair.sv | 51 +- grammars/silver/core/ParseResult.sv | 7 +- grammars/silver/core/Ring.sv | 14 +- grammars/silver/core/String.sv | 43 +- grammars/silver/core/TerminalId.sv | 14 +- grammars/silver/langutil/Message.sv | 31 +- grammars/silver/langutil/Origins.sv | 69 +-- grammars/silver/langutil/pp/Document.sv | 103 +--- grammars/silver/langutil/unparse/Unparse.sv | 18 +- grammars/silver/reflect/Util.sv | 13 +- grammars/silver/reflect/util/Util.sv | 14 +- grammars/silver/regex/AbstractSyntax.sv | 58 +-- grammars/silver/regex/Matching.sv | 6 +- grammars/silver/rewrite/Strategy.sv | 7 +- grammars/silver/util/deque/Deque.sv | 6 +- grammars/silver/util/graph/Graph.sv | 6 +- grammars/silver/util/random/Util.sv | 31 +- grammars/silver/util/treemap/TreeMap.sv | 12 +- grammars/silver/util/treeset/TreeSet.sv | 12 +- 126 files changed, 1565 insertions(+), 3280 deletions(-) diff --git a/grammars/silver/compiler/analysis/uniqueness/UniqueRefSite.sv b/grammars/silver/compiler/analysis/uniqueness/UniqueRefSite.sv index d9e41f1ca..f0cbe5b2b 100644 --- a/grammars/silver/compiler/analysis/uniqueness/UniqueRefSite.sv +++ b/grammars/silver/compiler/analysis/uniqueness/UniqueRefSite.sv @@ -24,11 +24,9 @@ top::UniqueRefSite ::= {} -- Append lists of references, ignoring duplicate refs to the same ref site -function unionMutuallyExclusiveRefs -[(String, UniqueRefSite)] ::= rs1::[(String, UniqueRefSite)] rs2::[(String, UniqueRefSite)] -{ - return rs1 ++ filter(\ r::(String, UniqueRefSite) -> !lookup(r.1, rs1).isJust, rs2); -} +fun unionMutuallyExclusiveRefs +[(String, UniqueRefSite)] ::= rs1::[(String, UniqueRefSite)] rs2::[(String, UniqueRefSite)] = + rs1 ++ filter(\ r::(String, UniqueRefSite) -> !lookup(r.1, rs1).isJust, rs2); -- Compare unique ref sites based on ref set. -- Source location doesn't matter, and we should never be comparing unique ref sites from different grammars. diff --git a/grammars/silver/compiler/analysis/warnings/exporting/Graph.sv b/grammars/silver/compiler/analysis/warnings/exporting/Graph.sv index 0b19fd0e6..a81fa93a8 100644 --- a/grammars/silver/compiler/analysis/warnings/exporting/Graph.sv +++ b/grammars/silver/compiler/analysis/warnings/exporting/Graph.sv @@ -73,35 +73,25 @@ top::DriverAction ::= specs::[Decorated RootSpec] top.order = 0; } -function generateDotGraph -String ::= specs::[Decorated RootSpec] -{ - return case specs of +fun generateDotGraph String ::= specs::[Decorated RootSpec] = + case specs of | [] -> "" | h::t -> "\"" ++ h.declaredName ++ "\"[label=\"" ++ h.declaredName ++ "\"];\n" ++ implode("", map(makeDotArrow(h.declaredName, _), h.moduleNames)) ++ generateDotGraph(t) end; -} -function generateDotExportGraph -String ::= specs::[Decorated RootSpec] -{ - return case specs of +fun generateDotExportGraph String ::= specs::[Decorated RootSpec] = + case specs of | [] -> "" | h::t -> "\"" ++ h.declaredName ++ "\"[label=\"" ++ h.declaredName ++ "\"];\n" ++ implode("", map(makeDotArrow(h.declaredName, _), computeOptionalDeps([h.declaredName], h.compiledGrammars))) ++ generateDotExportGraph(t) end; -} -function makeDotArrow -String ::= f::String t::String -{ - -- A heuristic to try to make the graph more readable... - return if t == "silver:core" then "" +fun makeDotArrow String ::= f::String t::String = + if t == "silver:core" then "" else "\"" ++ f ++ "\" -> \"" ++ t ++ "\";\n"; -} diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index b0d12f7d5..a250aae5c 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -172,11 +172,9 @@ function checkEqDeps | subtermSynVertex(parent, termProdName, sigName, attrName) -> [] end; } -function checkAllEqDeps -[Message] ::= v::[FlowVertex] config::Decorated CmdArgs prodName::String flowEnv::FlowEnv realEnv::Env anonResolve::[Pair] -{ - return flatMap(checkEqDeps(_, config, prodName, flowEnv, realEnv, anonResolve), v); -} +fun checkAllEqDeps +[Message] ::= v::[FlowVertex] config::Decorated CmdArgs prodName::String flowEnv::FlowEnv realEnv::Env anonResolve::[Pair] = + flatMap(checkEqDeps(_, config, prodName, flowEnv, realEnv, anonResolve), v); {-- - Look up flow types, either from the flow environment (for a nonterminal) or the occurs-on contexts (for a type var). @@ -967,15 +965,12 @@ top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr } -function toAnonInhs -[String] ::= vs::[FlowVertex] vertex::String -{ - return filterMap(\ v::FlowVertex -> +fun toAnonInhs [String] ::= vs::[FlowVertex] vertex::String = + filterMap(\ v::FlowVertex -> case v of | anonInhVertex(n, inh) when n == vertex -> just(inh) | _ -> nothing() end, vs); -} inherited attribute receivedDeps :: [FlowVertex] occurs on VarBinders, VarBinder, PrimPatterns, PrimPattern; propagate receivedDeps on VarBinders, VarBinder, PrimPatterns, PrimPattern; @@ -1012,61 +1007,50 @@ top::VarBinder ::= n::Name } -- Is this there an equation for this inh attr on any decoration site for this child? -function remoteProdMissingInhEq -Boolean ::= prodName::String sigName::String attrName::String flowEnv::FlowEnv -{ - return !any(unzipWith( +fun remoteProdMissingInhEq +Boolean ::= prodName::String sigName::String attrName::String flowEnv::FlowEnv = !any(unzipWith( vertexHasInhEq(_, _, attrName, flowEnv), lookupAllDecSites(prodName, rhsVertexType(sigName), flowEnv))); -} -- Find all decoration sites productions/vertices for this vertex -function lookupAllDecSites -[(String, VertexType)] ::= prodName::String vt::VertexType flowEnv::FlowEnv -{ - return - (prodName, vt) :: - case vt of - | lhsVertexType_real() -> [] - | rhsVertexType(sigName) -> - flatMap(lookupAllDecSites(prodName, _, flowEnv), lookupRefDecSite(prodName, sigName, flowEnv)) - | localVertexType(fName) -> - flatMap(lookupAllDecSites(prodName, _, flowEnv), lookupLocalRefDecSite(fName, flowEnv)) - | transAttrVertexType(rhsVertexType(sigName), transAttr) -> - flatMap(lookupAllDecSites(prodName, _, flowEnv), lookupTransRefDecSite(prodName, sigName, transAttr, flowEnv)) - | transAttrVertexType(localVertexType(fName), transAttr) -> - flatMap(lookupAllDecSites(prodName, _, flowEnv), lookupLocalTransRefDecSite(fName, transAttr, flowEnv)) - | transAttrVertexType(_, _) -> [] - | anonVertexType(fName) -> [] - | forwardVertexType_real() -> [] - | subtermVertexType(_, remoteProdName, sigName) -> - lookupAllDecSites(remoteProdName, rhsVertexType(sigName), flowEnv) - end; -} +fun lookupAllDecSites [(String, VertexType)] ::= prodName::String vt::VertexType flowEnv::FlowEnv = + (prodName, vt) :: + case vt of + | lhsVertexType_real() -> [] + | rhsVertexType(sigName) -> + flatMap(lookupAllDecSites(prodName, _, flowEnv), lookupRefDecSite(prodName, sigName, flowEnv)) + | localVertexType(fName) -> + flatMap(lookupAllDecSites(prodName, _, flowEnv), lookupLocalRefDecSite(fName, flowEnv)) + | transAttrVertexType(rhsVertexType(sigName), transAttr) -> + flatMap(lookupAllDecSites(prodName, _, flowEnv), lookupTransRefDecSite(prodName, sigName, transAttr, flowEnv)) + | transAttrVertexType(localVertexType(fName), transAttr) -> + flatMap(lookupAllDecSites(prodName, _, flowEnv), lookupLocalTransRefDecSite(fName, transAttr, flowEnv)) + | transAttrVertexType(_, _) -> [] + | anonVertexType(fName) -> [] + | forwardVertexType_real() -> [] + | subtermVertexType(_, remoteProdName, sigName) -> + lookupAllDecSites(remoteProdName, rhsVertexType(sigName), flowEnv) + end; -function vertexHasInhEq -Boolean ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv -{ - return - case vt of - | rhsVertexType(sigName) -> !null(lookupInh(prodName, sigName, attrName, flowEnv)) - | localVertexType(fName) -> !null(lookupLocalInh(prodName, fName, attrName, flowEnv)) - | transAttrVertexType(rhsVertexType(sigName), transAttr) -> - !null(lookupInh(prodName, sigName, s"${transAttr}.${attrName}", flowEnv)) - | transAttrVertexType(localVertexType(fName), transAttr) -> - !null(lookupLocalInh(prodName, fName, s"${transAttr}.${attrName}", flowEnv)) - | transAttrVertexType(_, _) -> false - | anonVertexType(fName) -> !null(lookupLocalInh(prodName, fName, attrName, flowEnv)) - | subtermVertexType(_, remoteProdName, sigName) -> - vertexHasInhEq(remoteProdName, rhsVertexType(sigName), attrName, flowEnv) - -- This is a tricky case since we don't know what decorated this prod. - -- checkEqDeps can count on missing LHS inh eqs being caught as flow issues elsewhere, - -- but here we are remotely looking for equations that might not be the direct dependency of - -- anything in the prod flow graph. - | lhsVertexType_real() -> false -- Shouldn't ever be directly needed, since the LHS is never the dec site for another vertex. - | forwardVertexType_real() -> false -- Same as LHS, but we can check this if e.g. forwarding to a child. - end; -} +fun vertexHasInhEq Boolean ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv = + case vt of + | rhsVertexType(sigName) -> !null(lookupInh(prodName, sigName, attrName, flowEnv)) + | localVertexType(fName) -> !null(lookupLocalInh(prodName, fName, attrName, flowEnv)) + | transAttrVertexType(rhsVertexType(sigName), transAttr) -> + !null(lookupInh(prodName, sigName, s"${transAttr}.${attrName}", flowEnv)) + | transAttrVertexType(localVertexType(fName), transAttr) -> + !null(lookupLocalInh(prodName, fName, s"${transAttr}.${attrName}", flowEnv)) + | transAttrVertexType(_, _) -> false + | anonVertexType(fName) -> !null(lookupLocalInh(prodName, fName, attrName, flowEnv)) + | subtermVertexType(_, remoteProdName, sigName) -> + vertexHasInhEq(remoteProdName, rhsVertexType(sigName), attrName, flowEnv) + -- This is a tricky case since we don't know what decorated this prod. + -- checkEqDeps can count on missing LHS inh eqs being caught as flow issues elsewhere, + -- but here we are remotely looking for equations that might not be the direct dependency of + -- anything in the prod flow graph. + | lhsVertexType_real() -> false -- Shouldn't ever be directly needed, since the LHS is never the dec site for another vertex. + | forwardVertexType_real() -> false -- Same as LHS, but we can check this if e.g. forwarding to a child. + end; -- In places where we solve a synthesized attribute occurs-on context, -- check that the actual deps for the attribute do not exceed the one specified for the context. diff --git a/grammars/silver/compiler/analysis/warnings/flow/MWDA.sv b/grammars/silver/compiler/analysis/warnings/flow/MWDA.sv index 79be8e5b7..710e9a645 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/MWDA.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/MWDA.sv @@ -32,14 +32,11 @@ imports silver:compiler:modification:defaultattr; imports silver:compiler:modification:primitivepattern; imports silver:compiler:modification:copper only parserAttributeDefLHS; -function isForwardProdAttr -Boolean ::= a::String e::Env -{ - return case getValueDclAll(a, e) of +fun isForwardProdAttr Boolean ::= a::String e::Env = + case getValueDclAll(a, e) of | d :: _ -> d.hasForward | _ -> false end; -} diff --git a/grammars/silver/compiler/analysis/warnings/flow/MwdaFlag.sv b/grammars/silver/compiler/analysis/warnings/flow/MwdaFlag.sv index 088b98737..7d6ffb62d 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/MwdaFlag.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/MwdaFlag.sv @@ -39,24 +39,15 @@ Either ::= args::[String] flagParser=flag(mwdaFlag))]; } -function mwdaWrn -Message ::= config::Decorated CmdArgs l::Location m::String -{ - return - if config.errorMwda - then err(l, m) - else wrn(l, m); -} +fun mwdaWrn Message ::= config::Decorated CmdArgs l::Location m::String = + if config.errorMwda + then err(l, m) + else wrn(l, m); -function mwdaWrnFromOrigin +fun mwdaWrnFromOrigin attribute config occurs on a => -Message ::= a::Decorated a with {config} m::String -{ - return mwdaWrn(a.config, getParsedOriginLocationOrFallback(a), m); -} +Message ::= a::Decorated a with {config} m::String = + mwdaWrn(a.config, getParsedOriginLocationOrFallback(a), m); -function mwdaWrnAmbientOrigin -Message ::= config::Decorated CmdArgs m::String -{ - return mwdaWrn(config, getParsedOriginLocationOrFallback(ambientOrigin()), m); -} +fun mwdaWrnAmbientOrigin Message ::= config::Decorated CmdArgs m::String = + mwdaWrn(config, getParsedOriginLocationOrFallback(ambientOrigin()), m); diff --git a/grammars/silver/compiler/composed/Default/Main.sv b/grammars/silver/compiler/composed/Default/Main.sv index d99bbb7c8..9aab052ee 100644 --- a/grammars/silver/compiler/composed/Default/Main.sv +++ b/grammars/silver/compiler/composed/Default/Main.sv @@ -6,6 +6,7 @@ parser svParse::Root { silver:compiler:host; } +-- TODO: Change to a concise function function main IOVal ::= args::[String] ioin::IOToken { diff --git a/grammars/silver/compiler/definition/concrete_syntax/ast/CstAst.sv b/grammars/silver/compiler/definition/concrete_syntax/ast/CstAst.sv index 0ee0f1973..a3c21b5cc 100644 --- a/grammars/silver/compiler/definition/concrete_syntax/ast/CstAst.sv +++ b/grammars/silver/compiler/definition/concrete_syntax/ast/CstAst.sv @@ -145,11 +145,7 @@ Assumptions we make about initial Syntax: 1. All type parameter lists are the appropriate length. (Silver type checking) -} -function makeCopperName -String ::= str::String -{ - return makeIdName(str); -} +fun makeCopperName String ::= str::String = makeIdName(str); -- Compute an environment containg the layout for a given list of items function buildLayoutEnv diff --git a/grammars/silver/compiler/definition/concrete_syntax/ast/Syntax.sv b/grammars/silver/compiler/definition/concrete_syntax/ast/Syntax.sv index 892e2c54e..781cd3440 100644 --- a/grammars/silver/compiler/definition/concrete_syntax/ast/Syntax.sv +++ b/grammars/silver/compiler/definition/concrete_syntax/ast/Syntax.sv @@ -324,13 +324,10 @@ top::SyntaxDcl ::= ns::NamedSignature modifiers::SyntaxProductionModifiers ]; } -function fetchChildren -String ::= i::Integer ns::[NamedSignatureElement] -{ - return if null(ns) then "" +fun fetchChildren String ::= i::Integer ns::[NamedSignatureElement] = + if null(ns) then "" else if null(tail(ns)) then "_children[" ++ toString(i) ++ "]" else "_children[" ++ toString(i) ++ "], " ++ fetchChildren(i + 1, tail(ns)); -} function insertLocationAnnotation String ::= ns::NamedSignature @@ -344,25 +341,18 @@ String ::= ns::NamedSignature } -function lookupStrings -[[a]] ::= t::[String] e::EnvTree -{ - return map(searchEnvTree(_, e), t); -} -function checkRHS -[String] ::= pn::String rhs::[Type] refs::[[Decorated SyntaxDcl]] -{ - return if null(rhs) then [] - else (if length(head(refs)) == 1 then - case head(head(refs)) of - | syntaxNonterminal(_,_,_,_,_) -> [] - | syntaxTerminal(_,_,_) -> [] - | _ -> ["parameter " ++ head(rhs).typeName ++ " of production " ++ pn ++ " is not syntax."] - end - else ["Terminal " ++ head(rhs).typeName ++ " was referenced but " ++ - "this grammar was not included in this parser. (Referenced from RHS of " ++ pn ++ ")"]) - ++ checkRHS(pn, tail(rhs), tail(refs)); -} +fun lookupStrings [[a]] ::= t::[String] e::EnvTree = map(searchEnvTree(_, e), t); +fun checkRHS [String] ::= pn::String rhs::[Type] refs::[[Decorated SyntaxDcl]] = + if null(rhs) then [] + else (if length(head(refs)) == 1 then + case head(head(refs)) of + | syntaxNonterminal(_,_,_,_,_) -> [] + | syntaxTerminal(_,_,_) -> [] + | _ -> ["parameter " ++ head(rhs).typeName ++ " of production " ++ pn ++ " is not syntax."] + end + else ["Terminal " ++ head(rhs).typeName ++ " was referenced but " ++ + "this grammar was not included in this parser. (Referenced from RHS of " ++ pn ++ ")"]) + ++ checkRHS(pn, tail(rhs), tail(refs)); {-- - A lexer class. Copper doesn't take these, so we'll have to translate away diff --git a/grammars/silver/compiler/definition/core/AGDcl.sv b/grammars/silver/compiler/definition/core/AGDcl.sv index b5f3d9136..97d06899d 100644 --- a/grammars/silver/compiler/definition/core/AGDcl.sv +++ b/grammars/silver/compiler/definition/core/AGDcl.sv @@ -93,15 +93,12 @@ top::AGDcl ::= propagate moduleNames, defs, occursDefs, jarName; } -function warnIfMultJarName -[Message] ::= n1::Maybe n2::Maybe -{ - return if n1.isJust && n2.isJust - then [wrnFromOrigin(ambientOrigin(), - "Duplicate specification of jar name: " ++ - n1.fromJust ++ " and " ++ n2.fromJust)] - else []; -} +fun warnIfMultJarName [Message] ::= n1::Maybe n2::Maybe = + if n1.isJust && n2.isJust + then [wrnFromOrigin(ambientOrigin(), + "Duplicate specification of jar name: " ++ + n1.fromJust ++ " and " ++ n2.fromJust)] + else []; -- All AGDcls have their own file, or modification. None here. diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index a2457b31c..55448a8b2 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -1170,14 +1170,10 @@ top::AnnoAppExprs ::= top.annoIndexSupplied = []; } -function reorderedAnnoAppExprs -[Decorated Expr] ::= d::Decorated AnnoAppExprs -{ - -- This is an annoyingly poor quality implementation - return map(snd, sortBy(reorderedLte, zip(d.annoIndexSupplied, d.exprs))); -} -function reorderedLte -Boolean ::= l::(Integer, Decorated Expr) r::(Integer, Decorated Expr) { return l.fst <= r.fst; } +fun reorderedAnnoAppExprs [Decorated Expr] ::= d::Decorated AnnoAppExprs = + map(snd, sortBy(reorderedLte, zip(d.annoIndexSupplied, d.exprs))); +fun reorderedLte Boolean ::= l::(Integer, Decorated Expr) r::(Integer, Decorated Expr) = + l.fst <= r.fst; function extractNamedArg (Maybe<(String, Type)>, [(String, Type)]) ::= n::String l::[(String, Type)] @@ -1190,46 +1186,30 @@ function extractNamedArg else (recurse.fst, head(l) :: recurse.snd); } -function findNamedArgType -Integer ::= s::String l::[(String, Type)] z::Integer -{ - return if null(l) then -1 - else if s == head(l).fst then z - else findNamedArgType(s, tail(l), z+1); -} +fun findNamedArgType Integer ::= s::String l::[(String, Type)] z::Integer = + if null(l) then -1 +else if s == head(l).fst then z +else findNamedArgType(s, tail(l), z+1); {-- - Utility for other modules to create function invocations. - This makes no assumptions, use it any way you wish! -} -function mkStrFunctionInvocation -Expr ::= e::String es::[Expr] -{ - return mkFullFunctionInvocation(baseExpr(qName(e)), es, []); -} -function mkFunctionInvocation -Expr ::= e::Expr es::[Expr] -{ - return mkFullFunctionInvocation(e, es, []); -} -function mkFullFunctionInvocation -Expr ::= e::Expr es::[Expr] ans::[Pair] -{ - return application(e, '(', +fun mkStrFunctionInvocation Expr ::= e::String es::[Expr] = + mkFullFunctionInvocation(baseExpr(qName(e)), es, []); +fun mkFunctionInvocation Expr ::= e::Expr es::[Expr] = mkFullFunctionInvocation(e, es, []); +fun mkFullFunctionInvocation Expr ::= e::Expr es::[Expr] ans::[Pair] = + application(e, '(', foldl(snocAppExprs(_, ',', _), emptyAppExprs(), map(presentAppExpr, es)), ',', foldl(snocAnnoAppExprs(_, ',', _), emptyAnnoAppExprs(), map(mkAnnoExpr, ans)), ')'); -} -- Internal helper function -function mkAnnoExpr -AnnoExpr ::= p::Pair -{ - return annoExpr(qName(p.fst), '=', presentAppExpr(p.snd)); -} +fun mkAnnoExpr AnnoExpr ::= p::Pair = + annoExpr(qName(p.fst), '=', presentAppExpr(p.snd)); {-- - Note on the use of the 'decorated here' (@) operator with already-decorated expressions: diff --git a/grammars/silver/compiler/definition/core/ModuleStmts.sv b/grammars/silver/compiler/definition/core/ModuleStmts.sv index 2f42aea5a..c7b913944 100644 --- a/grammars/silver/compiler/definition/core/ModuleStmts.sv +++ b/grammars/silver/compiler/definition/core/ModuleStmts.sv @@ -113,16 +113,13 @@ top::ModuleExportedDefs ::= compiledGrammars::EnvTree gramma if null(rs) then [errFromOrigin(ambientOrigin(), "Grammar '" ++ gram ++ "' cannot be found.")] ++ recurse.errors else recurse.errors; } -function triggeredGrammars -[String] ::= grammarDependencies::[String] trig::[[String]] -{ - return if null(trig) then +fun triggeredGrammars [String] ::= grammarDependencies::[String] trig::[[String]] = + if null(trig) then [] else if contains(head(tail(head(trig))), grammarDependencies) then head(head(trig)) :: triggeredGrammars(grammarDependencies, tail(trig)) else triggeredGrammars(grammarDependencies, tail(trig)); -} -------------- -- ImportStmts diff --git a/grammars/silver/compiler/definition/core/QName.sv b/grammars/silver/compiler/definition/core/QName.sv index b8d46b070..3bcdfdac5 100644 --- a/grammars/silver/compiler/definition/core/QName.sv +++ b/grammars/silver/compiler/definition/core/QName.sv @@ -111,13 +111,11 @@ top::QNameLookup ::= msg::[Message] top.errors := msg; } -function printPossibilities +fun printPossibilities attribute fullName {} occurs on a, annotation sourceLocation occurs on a => -String ::= lst::[a] -{ - return implode("\n", map(dclinfo2possibility, lst)); -} +String ::= lst::[a] = + implode("\n", map(dclinfo2possibility, lst)); function dclinfo2possibility attribute fullName {} occurs on a, annotation sourceLocation occurs on a => @@ -252,10 +250,7 @@ top::QNameAttrOccur ::= at::QName - `occ` is a mapped list of occurrence declarations for the corresponding attribute - we return only those `at` which have a non-empty element in `occ` -} -function zipFilterDcls -[AttributeDclInfo] ::= at::[AttributeDclInfo] occ::[[OccursDclInfo]] -{ - return if null(at) then [] - else if null(head(occ)) then zipFilterDcls(tail(at), tail(occ)) - else head(at) :: zipFilterDcls(tail(at), tail(occ)); -} +fun zipFilterDcls [AttributeDclInfo] ::= at::[AttributeDclInfo] occ::[[OccursDclInfo]] = + if null(at) then [] +else if null(head(occ)) then zipFilterDcls(tail(at), tail(occ)) +else head(at) :: zipFilterDcls(tail(at), tail(occ)); diff --git a/grammars/silver/compiler/definition/env/Defs.sv b/grammars/silver/compiler/definition/env/Defs.sv index 54e745ea0..baa1cee73 100644 --- a/grammars/silver/compiler/definition/env/Defs.sv +++ b/grammars/silver/compiler/definition/env/Defs.sv @@ -120,140 +120,68 @@ top::Def ::= d::InstDclInfo top.instList = [d]; } -function childDef -Def ::= sg::String sl::Location fn::String ty::Type -{ - return valueDef(defaultEnvItem(childDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); -} -function lhsDef -Def ::= sg::String sl::Location fn::String ty::Type -{ - return valueDef(defaultEnvItem(lhsDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); -} -function localDef -Def ::= sg::String sl::Location fn::String ty::Type isForward::Boolean -{ - return valueDef(defaultEnvItem(localDcl(fn,ty,isForward,sourceGrammar=sg,sourceLocation=sl))); -} -function prodDef -Def ::= sg::String sl::Location ns::NamedSignature hasForward::Boolean -{ - return prodDclDef(defaultEnvItem(prodDcl(ns,hasForward,sourceGrammar=sg,sourceLocation=sl))); -} -function funDef -Def ::= sg::String sl::Location ns::NamedSignature -{ - return valueDef(defaultEnvItem(funDcl(ns,sourceGrammar=sg,sourceLocation=sl))); -} -function globalDef -Def ::= sg::String sl::Location fn::String bound::[TyVar] contexts::[Context] ty::Type -{ - return valueDef(defaultEnvItem(globalValueDcl(fn, bound, contexts, ty,sourceGrammar=sg,sourceLocation=sl))); -} -function classMemberDef -Def ::= sg::String sl::Location fn::String bound::[TyVar] head::Context contexts::[Context] ty::Type -{ - return valueDef(defaultEnvItem(classMemberDcl(fn,bound,head,contexts,ty,sourceGrammar=sg,sourceLocation=sl))); -} -function ntDef -Def ::= sg::String sl::Location fn::String ks::[Kind] data::Boolean closed::Boolean tracked::Boolean -{ - return typeDef(defaultEnvItem(ntDcl(fn,ks,data,closed,tracked,sourceGrammar=sg,sourceLocation=sl))); -} -function termDef -Def ::= sg::String sl::Location fn::String regex::r:Regex easyName::Maybe genRepeatProb::Maybe -{ - -- Terminals are also in the value namespace as terminal identifiers - return typeValueDef( +fun childDef Def ::= sg::String sl::Location fn::String ty::Type = + valueDef(defaultEnvItem(childDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); +fun lhsDef Def ::= sg::String sl::Location fn::String ty::Type = + valueDef(defaultEnvItem(lhsDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); +fun localDef Def ::= sg::String sl::Location fn::String ty::Type isForward::Boolean = + valueDef(defaultEnvItem(localDcl(fn,ty,isForward,sourceGrammar=sg,sourceLocation=sl))); +fun prodDef Def ::= sg::String sl::Location ns::NamedSignature hasForward::Boolean = + prodDclDef(defaultEnvItem(prodDcl(ns,hasForward,sourceGrammar=sg,sourceLocation=sl))); +fun funDef Def ::= sg::String sl::Location ns::NamedSignature = + valueDef(defaultEnvItem(funDcl(ns,sourceGrammar=sg,sourceLocation=sl))); +fun globalDef +Def ::= sg::String sl::Location fn::String bound::[TyVar] contexts::[Context] ty::Type = + valueDef(defaultEnvItem(globalValueDcl(fn, bound, contexts, ty,sourceGrammar=sg,sourceLocation=sl))); +fun classMemberDef +Def ::= sg::String sl::Location fn::String bound::[TyVar] head::Context contexts::[Context] ty::Type = + valueDef(defaultEnvItem(classMemberDcl(fn,bound,head,contexts,ty,sourceGrammar=sg,sourceLocation=sl))); +fun ntDef +Def ::= sg::String sl::Location fn::String ks::[Kind] data::Boolean closed::Boolean tracked::Boolean = + typeDef(defaultEnvItem(ntDcl(fn,ks,data,closed,tracked,sourceGrammar=sg,sourceLocation=sl))); +fun termDef +Def ::= sg::String sl::Location fn::String regex::r:Regex easyName::Maybe genRepeatProb::Maybe = + typeValueDef( defaultEnvItem(termDcl(fn,regex,easyName,genRepeatProb,sourceGrammar=sg,sourceLocation=sl)), defaultEnvItem(termIdDcl(fn,sourceGrammar=sg,sourceLocation=sl))); -} -function lexTyVarDef -Def ::= sg::String sl::Location fn::String tv::TyVar -{ - return typeDef(defaultEnvItem(lexTyVarDcl(fn,false,tv,sourceGrammar=sg,sourceLocation=sl))); -} -function aspectLexTyVarDef -Def ::= sg::String sl::Location fn::String tv::TyVar -{ - return typeDef(defaultEnvItem(lexTyVarDcl(fn,true,tv,sourceGrammar=sg,sourceLocation=sl))); -} -function typeAliasDef -Def ::= sg::String sl::Location fn::String mentionedAliases::[String] bound::[TyVar] ty::Type -{ - return typeDef(defaultEnvItem(typeAliasDcl(fn,mentionedAliases,bound,ty,sourceGrammar=sg,sourceLocation=sl))); -} -function synDef -Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type -{ - return attrDef(defaultEnvItem(synDcl(fn,bound,ty,sourceGrammar=sg,sourceLocation=sl))); -} -function inhDef -Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type -{ - return attrDef(defaultEnvItem(inhDcl(fn,bound,ty,sourceGrammar=sg,sourceLocation=sl))); -} -function transDef -Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type -{ - return attrDef(defaultEnvItem(transDcl(fn,bound,ty,sourceGrammar=sg,sourceLocation=sl))); -} -function prodOccursDef -Def ::= sg::String sl::Location ns::NamedSignature dcls::[Def] -{ - return paDef(paDcl(ns,dcls,sourceGrammar=sg,sourceLocation=sl)); -} -function forwardDef -Def ::= sg::String sl::Location ty::Type -{ - return valueDef(defaultEnvItem(forwardDcl(ty,sourceGrammar=sg,sourceLocation=sl))); -} +fun lexTyVarDef Def ::= sg::String sl::Location fn::String tv::TyVar = + typeDef(defaultEnvItem(lexTyVarDcl(fn,false,tv,sourceGrammar=sg,sourceLocation=sl))); +fun aspectLexTyVarDef Def ::= sg::String sl::Location fn::String tv::TyVar = + typeDef(defaultEnvItem(lexTyVarDcl(fn,true,tv,sourceGrammar=sg,sourceLocation=sl))); +fun typeAliasDef +Def ::= sg::String sl::Location fn::String mentionedAliases::[String] bound::[TyVar] ty::Type = + typeDef(defaultEnvItem(typeAliasDcl(fn,mentionedAliases,bound,ty,sourceGrammar=sg,sourceLocation=sl))); +fun synDef Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type = + attrDef(defaultEnvItem(synDcl(fn,bound,ty,sourceGrammar=sg,sourceLocation=sl))); +fun inhDef Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type = + attrDef(defaultEnvItem(inhDcl(fn,bound,ty,sourceGrammar=sg,sourceLocation=sl))); +fun transDef Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type = + attrDef(defaultEnvItem(transDcl(fn,bound,ty,sourceGrammar=sg,sourceLocation=sl))); +fun prodOccursDef Def ::= sg::String sl::Location ns::NamedSignature dcls::[Def] = + paDef(paDcl(ns,dcls,sourceGrammar=sg,sourceLocation=sl)); +fun forwardDef Def ::= sg::String sl::Location ty::Type = + valueDef(defaultEnvItem(forwardDcl(ty,sourceGrammar=sg,sourceLocation=sl))); -- These aliased functions are used for aspects. -function aliasedLhsDef -Def ::= sg::String sl::Location fn::String ty::Type alias::String -{ - return valueDef(onlyRenamedEnvItem(alias, lhsDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); -} -function aliasedChildDef -Def ::= sg::String sl::Location fn::String ty::Type alias::String -{ - return valueDef(onlyRenamedEnvItem(alias, childDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); -} -function annoDef -Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type -{ - return attrDef(defaultEnvItem(annoDcl(fn,bound,ty,sourceGrammar=sg,sourceLocation=sl))); -} -function classDef -Def ::= sg::String sl::Location fn::String supers::[Context] tv::TyVar k::Kind members::[Pair] -{ - return typeDef(defaultEnvItem(clsDcl(fn,supers,tv,k,members,sourceGrammar=sg,sourceLocation=sl))); -} -function instDef -Def ::= sg::String sl::Location fn::String bound::[TyVar] contexts::[Context] ty::Type definedMembers::[String] -{ - return tcInstDef(instDcl(fn,bound,contexts,ty,definedMembers,sourceGrammar=sg,sourceLocation=sl)); -} -function sigConstraintDef -Def ::= sg::String sl::Location fn::String ty::Type ns::NamedSignature -{ - return tcInstDef(sigConstraintDcl(fn,ty,ns,sourceGrammar=sg,sourceLocation=sl)); -} -function currentInstDef -Def ::= sg::String sl::Location fn::String ty::Type -{ - return tcInstDef(currentInstDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl)); -} -function instSuperDef -Def ::= sg::String sl::Location fn::String baseDcl::InstDclInfo -{ - return tcInstDef(instSuperDcl(fn,baseDcl,sourceGrammar=sg,sourceLocation=sl)); -} -function typeableSuperDef -Def ::= sg::String sl::Location baseDcl::InstDclInfo -{ - return tcInstDef(typeableSuperDcl(baseDcl,sourceGrammar=sg,sourceLocation=sl)); -} +fun aliasedLhsDef Def ::= sg::String sl::Location fn::String ty::Type alias::String = + valueDef(onlyRenamedEnvItem(alias, lhsDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); +fun aliasedChildDef Def ::= sg::String sl::Location fn::String ty::Type alias::String = + valueDef(onlyRenamedEnvItem(alias, childDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); +fun annoDef Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type = + attrDef(defaultEnvItem(annoDcl(fn,bound,ty,sourceGrammar=sg,sourceLocation=sl))); +fun classDef +Def ::= sg::String sl::Location fn::String supers::[Context] tv::TyVar k::Kind members::[Pair] = + typeDef(defaultEnvItem(clsDcl(fn,supers,tv,k,members,sourceGrammar=sg,sourceLocation=sl))); +fun instDef +Def ::= sg::String sl::Location fn::String bound::[TyVar] contexts::[Context] ty::Type definedMembers::[String] = + tcInstDef(instDcl(fn,bound,contexts,ty,definedMembers,sourceGrammar=sg,sourceLocation=sl)); +fun sigConstraintDef Def ::= sg::String sl::Location fn::String ty::Type ns::NamedSignature = + tcInstDef(sigConstraintDcl(fn,ty,ns,sourceGrammar=sg,sourceLocation=sl)); +fun currentInstDef Def ::= sg::String sl::Location fn::String ty::Type = + tcInstDef(currentInstDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl)); +fun instSuperDef Def ::= sg::String sl::Location fn::String baseDcl::InstDclInfo = + tcInstDef(instSuperDcl(fn,baseDcl,sourceGrammar=sg,sourceLocation=sl)); +fun typeableSuperDef Def ::= sg::String sl::Location baseDcl::InstDclInfo = + tcInstDef(typeableSuperDcl(baseDcl,sourceGrammar=sg,sourceLocation=sl)); -- I'm leaving "Defsironment" here just for the lols diff --git a/grammars/silver/compiler/definition/env/Env.sv b/grammars/silver/compiler/definition/env/Env.sv index 9df362c01..c44331ccc 100644 --- a/grammars/silver/compiler/definition/env/Env.sv +++ b/grammars/silver/compiler/definition/env/Env.sv @@ -43,11 +43,7 @@ top::Env ::= top.prodsForNtTree = [emptyEnvTree()]; } -function toEnv -Env ::= d::[Def] od::[OccursDclInfo] -{ - return occursEnv(od, newScopeEnv(d, emptyEnv())); -} +fun toEnv Env ::= d::[Def] od::[OccursDclInfo] = occursEnv(od, newScopeEnv(d, emptyEnv())); {-- - appendEnv exists because we do a weird scope swizzling. @@ -116,11 +112,7 @@ top::Env ::= d::[OccursDclInfo] e::Env --Environment query functions----------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- -function searchEnvAll -[a] ::= search::String e::[EnvTree] -{ - return flatMap(searchEnvTree(search, _), e); -} +fun searchEnvAll [a] ::= search::String e::[EnvTree] = flatMap(searchEnvTree(search, _), e); function searchEnv [a] ::= search::String e::[EnvTree] @@ -132,63 +124,27 @@ function searchEnv else found; } -function getValueDclInScope -[ValueDclInfo] ::= search::String e::Env -{ - return searchEnvTree(search, head(e.valueTree)); -} -function getValueDcl -[ValueDclInfo] ::= search::String e::Env -{ - return searchEnv(search, e.valueTree); -} -function getValueDclAll -[ValueDclInfo] ::= search::String e::Env -{ - return searchEnvAll(search, e.valueTree); -} +fun getValueDclInScope [ValueDclInfo] ::= search::String e::Env = + searchEnvTree(search, head(e.valueTree)); +fun getValueDcl [ValueDclInfo] ::= search::String e::Env = searchEnv(search, e.valueTree); +fun getValueDclAll [ValueDclInfo] ::= search::String e::Env = searchEnvAll(search, e.valueTree); -function getTypeDclInScope -[TypeDclInfo] ::= search::String e::Env -{ - return searchEnvTree(search, head(e.typeTree)); -} -function getTypeDcl -[TypeDclInfo] ::= search::String e::Env -{ - return searchEnv(search, e.typeTree); -} -function getTypeDclAll -[TypeDclInfo] ::= search::String e::Env -{ - return searchEnvAll(search, e.typeTree); -} +fun getTypeDclInScope [TypeDclInfo] ::= search::String e::Env = + searchEnvTree(search, head(e.typeTree)); +fun getTypeDcl [TypeDclInfo] ::= search::String e::Env = searchEnv(search, e.typeTree); +fun getTypeDclAll [TypeDclInfo] ::= search::String e::Env = searchEnvAll(search, e.typeTree); -function getAttrDclInScope -[AttributeDclInfo] ::= search::String e::Env -{ - return searchEnvTree(search, head(e.attrTree)); -} -function getAttrDcl -[AttributeDclInfo] ::= search::String e::Env -{ - return searchEnv(search, e.attrTree); -} -function getAttrDclAll -[AttributeDclInfo] ::= search::String e::Env -{ - return searchEnvAll(search, e.attrTree); -} +fun getAttrDclInScope [AttributeDclInfo] ::= search::String e::Env = + searchEnvTree(search, head(e.attrTree)); +fun getAttrDcl [AttributeDclInfo] ::= search::String e::Env = searchEnv(search, e.attrTree); +fun getAttrDclAll [AttributeDclInfo] ::= search::String e::Env = searchEnvAll(search, e.attrTree); {-- - Look up the short name of an attribute, - disambiguating based on some nonterminal on which it is known to occur. -} -function getOccuringAttrDcl -[AttributeDclInfo] ::= fnnt::String search::String e::Env -{ - return getOccuringAttrDclHelp(map((.attrOccurring), getAttrOccursOn(fnnt, e)), search, e.attrTree); -} +fun getOccuringAttrDcl [AttributeDclInfo] ::= fnnt::String search::String e::Env = + getOccuringAttrDclHelp(map((.attrOccurring), getAttrOccursOn(fnnt, e)), search, e.attrTree); function getOccuringAttrDclHelp [AttributeDclInfo] ::= allAttrs::[String] search::String e::[EnvTree] { @@ -202,21 +158,13 @@ function getOccuringAttrDclHelp else found; } -function getOccursDcl -[OccursDclInfo] ::= fnat::String fnnt::String e::Env -{ - -- retrieve all attribute Dcls on NT fnnt - return occursOnHelp(searchEnvTree(fnnt, e.occursTree), fnat); -} -function occursOnHelp -[OccursDclInfo] ::= i::[OccursDclInfo] fnat::String -{ - -- Inefficiency. Linear search for attribute on a nonterminal - return if null(i) then [] - else if head(i).attrOccurring == fnat - then head(i) :: occursOnHelp(tail(i), fnat) - else occursOnHelp(tail(i), fnat); -} +fun getOccursDcl [OccursDclInfo] ::= fnat::String fnnt::String e::Env = + occursOnHelp(searchEnvTree(fnnt, e.occursTree), fnat); +fun occursOnHelp [OccursDclInfo] ::= i::[OccursDclInfo] fnat::String = + if null(i) then [] + else if head(i).attrOccurring == fnat + then head(i) :: occursOnHelp(tail(i), fnat) + else occursOnHelp(tail(i), fnat); -- Determines whether a type is automatically promoted to a decorated type -- and whether a type may be supplied with inherited attributes. @@ -233,11 +181,8 @@ Boolean ::= t::Type e::Env end; } -function getProdAttrs -[ProductionAttrDclInfo] ::= fnprod::String e::Env -{ - return searchEnvTree(fnprod, e.prodOccursTree); -} +fun getProdAttrs [ProductionAttrDclInfo] ::= fnprod::String e::Env = + searchEnvTree(fnprod, e.prodOccursTree); {-- - Get all productions for a nonterminal known to local environment. @@ -252,11 +197,7 @@ function getProdAttrs - - to implement propagate on all the known non-forwarding productions of a nonterminal. - You should probably have a good reason for using this, and document it here if you do. -} -function getKnownProds -[ValueDclInfo] ::= fnnt::String e::Env -{ - return searchEnvAll(fnnt, e.prodsForNtTree); -} +fun getKnownProds [ValueDclInfo] ::= fnnt::String e::Env = searchEnvAll(fnnt, e.prodsForNtTree); -- The list of non-forwarding productions may contain productions from `options` not -- imported locally, and so we must consult the "flow environment" for that information: @@ -267,51 +208,39 @@ function getKnownProds - Obviously we can never know all attributes, but we generally don't need to for - any reason. -} -function getAttrOccursOn -[OccursDclInfo] ::= fnnt::String e::Env -{ - return searchEnvTree(fnnt, e.occursTree); -} +fun getAttrOccursOn [OccursDclInfo] ::= fnnt::String e::Env = searchEnvTree(fnnt, e.occursTree); {-- - Returns the names of all synthesized attributes known locally to occur on a nonterminal. -} -function getSynAttrsOn -[String] ::= fnnt::String e::Env -{ - return flatMap( +fun getSynAttrsOn [String] ::= fnnt::String e::Env = + flatMap( \ o::OccursDclInfo -> case getAttrDcl(o.attrOccurring, e) of | at :: _ when at.isSynthesized -> [o.attrOccurring] | _ -> [] end, getAttrOccursOn(fnnt, e)); -} {-- - Returns the names of all inherited attributes known locally to occur on a nonterminal. -} -function getInhAttrsOn -[String] ::= fnnt::String e::Env -{ - return flatMap( +fun getInhAttrsOn [String] ::= fnnt::String e::Env = + flatMap( \ o::OccursDclInfo -> case getAttrDcl(o.attrOccurring, e) of | at :: _ when at.isInherited -> [o.attrOccurring] | _ -> [] end, getAttrOccursOn(fnnt, e)); -} {-- - Returns the names of all inherited attributes known locally to occur on a nonterminal. - Also includes all inherited attributes occuring on translation attributes on the - nonterminal, when we want to treat these like inherited attributes. -} -function getInhAndInhOnTransAttrsOn -[String] ::= fnnt::String e::Env -{ - return flatMap( +fun getInhAndInhOnTransAttrsOn [String] ::= fnnt::String e::Env = + flatMap( \ o::OccursDclInfo -> case getAttrDcl(o.attrOccurring, e) of | at :: _ when at.isInherited -> [o.attrOccurring] @@ -322,7 +251,6 @@ function getInhAndInhOnTransAttrsOn | _ -> [] end, getAttrOccursOn(fnnt, e)); -} -- This ensure the annotation list is in the properly sorted order! function annotationsForNonterminal diff --git a/grammars/silver/compiler/definition/env/EnvItem.sv b/grammars/silver/compiler/definition/env/EnvItem.sv index 802164021..22f492741 100644 --- a/grammars/silver/compiler/definition/env/EnvItem.sv +++ b/grammars/silver/compiler/definition/env/EnvItem.sv @@ -96,12 +96,7 @@ EnvItem ::= di::a { return renamedEnvItem(fullNameToShort(di.fullName), di); } -function fullNameToShort -String ::= s::String -{ - -- Works just fine, even when lastIndexOf returns -1 - return substring(lastIndexOf(":", s) + 1, length(s), s); -} +fun fullNameToShort String ::= s::String = substring(lastIndexOf(":", s) + 1, length(s), s); global mapGetDcls :: ([a] ::= [EnvItem]) = map((.dcl), _); diff --git a/grammars/silver/compiler/definition/env/EnvTree.sv b/grammars/silver/compiler/definition/env/EnvTree.sv index 78b255e02..ebd3cf389 100644 --- a/grammars/silver/compiler/definition/env/EnvTree.sv +++ b/grammars/silver/compiler/definition/env/EnvTree.sv @@ -10,45 +10,22 @@ type EnvTree = rtm:Map; {-- - Look up function for maps. -} -function searchEnvTree -[a] ::= search::String et::EnvTree -{ - return rtm:lookup(search, et); -} +fun searchEnvTree [a] ::= search::String et::EnvTree = rtm:lookup(search, et); {-- - Standard environment constructor for a map. - Obey's EnvItem's rules for what names should appear for each item. -} -function buildTree -EnvTree ::= eis::[EnvItem] -{ - return directBuildTree(flatMap((.envContribs), eis)); -} +fun buildTree EnvTree ::= eis::[EnvItem] = directBuildTree(flatMap((.envContribs), eis)); {-- - Arbitrary environment constructor for a map. -} -function directBuildTree -EnvTree ::= eis::[Pair] -{ - return rtm:add(eis, rtm:empty()); -} - -function emptyEnvTree -EnvTree ::= -{ - return directBuildTree([]); -} - -function appendEnvTree -EnvTree ::= e1::EnvTree e2::EnvTree -{ - return rtm:add(rtm:toList(e1), e2); -} - -function consEnvTree -EnvTree ::= eis::[EnvItem] et::EnvTree -{ - return rtm:add(flatMap((.envContribs), eis), et); -} +fun directBuildTree EnvTree ::= eis::[Pair] = rtm:add(eis, rtm:empty()); + +fun emptyEnvTree EnvTree ::= = directBuildTree([]); + +fun appendEnvTree EnvTree ::= e1::EnvTree e2::EnvTree = rtm:add(rtm:toList(e1), e2); + +fun consEnvTree EnvTree ::= eis::[EnvItem] et::EnvTree = + rtm:add(flatMap((.envContribs), eis), et); diff --git a/grammars/silver/compiler/definition/env/NamedSignature.sv b/grammars/silver/compiler/definition/env/NamedSignature.sv index 2d0a24e8e..d04ec3dce 100644 --- a/grammars/silver/compiler/definition/env/NamedSignature.sv +++ b/grammars/silver/compiler/definition/env/NamedSignature.sv @@ -85,15 +85,12 @@ top::NamedSignature ::= fn::String ctxs::Contexts ty::Type - Used when an error occurs. e.g. aspecting a non-existant production. - Or, in contexts that have no valid signature, which maybe we should do something about... -} -function bogusNamedSignature -NamedSignature ::= -{ - return namedSignature("_NULL_", nilContext(), nilNamedSignatureElement(), bogusNamedSignatureElement(), nilNamedSignatureElement()); -} +fun bogusNamedSignature NamedSignature ::= = + namedSignature("_NULL_", nilContext(), nilNamedSignatureElement(), bogusNamedSignatureElement(), nilNamedSignatureElement()); {-- - - Represents a collection of NamedSignatureElements - -} + - Represents a collection of NamedSignatureElements + -} nonterminal NamedSignatureElements with elements, elementNames, elementShortNames, elementTypes, freeVariables, boundVariables; propagate boundVariables on NamedSignatureElements; @@ -168,13 +165,11 @@ Boolean ::= a::NamedSignatureElement b::NamedSignatureElement } -- This is a big of an awful pile. Related to annotations, for now. -function findNamedSigElem -Integer ::= s::String l::[NamedSignatureElement] z::Integer -{ - return if null(l) then -1 +fun findNamedSigElem +Integer ::= s::String l::[NamedSignatureElement] z::Integer = + if null(l) then -1 else if s == head(l).elementName then z else findNamedSigElem(s, tail(l), z+1); -} function findNamedSigElemType Type ::= n::String l::[NamedSignatureElement] diff --git a/grammars/silver/compiler/definition/flow/ast/Flow.sv b/grammars/silver/compiler/definition/flow/ast/Flow.sv index 68e067296..bcf1ee146 100644 --- a/grammars/silver/compiler/definition/flow/ast/Flow.sv +++ b/grammars/silver/compiler/definition/flow/ast/Flow.sv @@ -488,24 +488,15 @@ top::FlowDef ::= prod::String fName::String transAttr::String alwaysDec::Bool -- -function crossnames -String ::= a::String b::String -{ - return a ++ " @ " ++ b; -} +fun crossnames String ::= a::String b::String = a ++ " @ " ++ b; -- -- Used to get better error messages -function collectAnonOrigin -[Pair] ::= f::[FlowDef] -{ - return foldr(collectAnonOriginItem, [], f); -} -function collectAnonOriginItem -[Pair] ::= f::FlowDef rest::[Pair] -{ - return case f of +fun collectAnonOrigin [Pair] ::= f::[FlowDef] = + foldr(collectAnonOriginItem, [], f); +fun collectAnonOriginItem [Pair] ::= f::FlowDef rest::[Pair] = + case f of | anonEq(_, fN, _, _, l, _) -> -- Small hack to improve error messages. Ignore anonEq's that come from patterns if startsWith("__scrutinee", fN) @@ -513,4 +504,3 @@ function collectAnonOriginItem else (fN, l) :: rest | _ -> rest end; -} diff --git a/grammars/silver/compiler/definition/flow/ast/Vertex.sv b/grammars/silver/compiler/definition/flow/ast/Vertex.sv index 23867ae93..b647ea232 100644 --- a/grammars/silver/compiler/definition/flow/ast/Vertex.sv +++ b/grammars/silver/compiler/definition/flow/ast/Vertex.sv @@ -124,20 +124,8 @@ derive Eq, Ord on FlowVertex; -- The forward equation for this production. We do not care to distinguish it. -function forwardEqVertex -FlowVertex ::= -{ - return localEqVertex("forward"); -} +fun forwardEqVertex FlowVertex ::= = localEqVertex("forward"); -- An attribute on the forward node for this production -function forwardSynVertex -FlowVertex ::= attrName::String -{ - return localSynVertex("forward", attrName); -} -function forwardInhVertex -FlowVertex ::= attrName::String -{ - return localInhVertex("forward", attrName); -} +fun forwardSynVertex FlowVertex ::= attrName::String = localSynVertex("forward", attrName); +fun forwardInhVertex FlowVertex ::= attrName::String = localInhVertex("forward", attrName); diff --git a/grammars/silver/compiler/definition/flow/driver/DumpGraph.sv b/grammars/silver/compiler/definition/flow/driver/DumpGraph.sv index 2ea7f3b8d..ef1d85a30 100644 --- a/grammars/silver/compiler/definition/flow/driver/DumpGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/DumpGraph.sv @@ -88,27 +88,19 @@ String ::= flowTypes::[Pair] generateFlowDotGraph(tail(flowTypes)); } -function expandLabels -[String] ::= l::[Pair] -{ - return if null(l) then [] else head(l).fst :: head(l).snd :: expandLabels(tail(l)); -} +fun expandLabels [String] ::= l::[Pair] = + if null(l) then [] else head(l).fst :: head(l).snd :: expandLabels(tail(l)); function makeLabelDcls String ::= nt::String attr::String { local a :: String = substring(lastIndexOf(":", attr) + 1, length(attr), attr); return "\"" ++ nt ++ "/" ++ attr ++ "\"[label=\"" ++ a ++ "\"];\n"; } -function makeNtFlow -String ::= nt::String e::Pair -{ - return "\"" ++ nt ++ "/" ++ e.fst ++ "\" -> \"" ++ nt ++ "/" ++ e.snd ++ "\";\n"; -} +fun makeNtFlow String ::= nt::String e::Pair = + "\"" ++ nt ++ "/" ++ e.fst ++ "\" -> \"" ++ nt ++ "/" ++ e.snd ++ "\";\n"; -function generateDotGraph -String ::= specs::[ProductionGraph] -{ - return case specs of +fun generateDotGraph String ::= specs::[ProductionGraph] = + case specs of | [] -> "" | productionGraph(prod, _, _, graph, suspect, _) :: t -> "subgraph \"cluster:" ++ prod ++ "\" {\n" ++ @@ -117,14 +109,10 @@ String ::= specs::[ProductionGraph] "}\n" ++ generateDotGraph(t) end; -} -- "production/flowvertex" -> "production/flowvertex" -function makeDotArrow -String ::= p::String e::Pair style::String -{ - return "\"" ++ p ++ "/" ++ e.fst.dotName ++ "\" -> \"" ++ p ++ "/" ++ e.snd.dotName ++ "\"" ++ style ++ ";\n"; -} +fun makeDotArrow String ::= p::String e::Pair style::String = + "\"" ++ p ++ "/" ++ e.fst.dotName ++ "\" -> \"" ++ p ++ "/" ++ e.snd.dotName ++ "\"" ++ style ++ ";\n"; diff --git a/grammars/silver/compiler/definition/flow/driver/FlowGraph.sv b/grammars/silver/compiler/definition/flow/driver/FlowGraph.sv index 27d2435a0..f8059559f 100644 --- a/grammars/silver/compiler/definition/flow/driver/FlowGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/FlowGraph.sv @@ -28,11 +28,7 @@ function expandGraph return set:toList(expandSuspectEdges(set:toList(initial), initial, e)); } -function onlyLhsInh -set:Set ::= s::[FlowVertex] -{ - return set:add(filterLhsInh(s), set:empty()); -} +fun onlyLhsInh set:Set ::= s::[FlowVertex] = set:add(filterLhsInh(s), set:empty()); -- suspect edges are not in the standard graph, so iteratively add them -- call like expandSuspectEdges(p.edges.toList, p.edges, p) @@ -57,47 +53,28 @@ set:Set ::= todolist::[FlowVertex] current::set:Set p: - @param flow The flow type environment (NOTE: TODO: this is currently 'myFlow' or something, NOT top.flowEnv) - @return A set of inherited attributes on this nonterminal, needed to compute this synthesized attribute. -} -function inhDepsForSyn -set:Set ::= syn::String nt::String flow::EnvTree -{ - return g:edgesFrom(syn, findFlowType(nt, flow)); -} +fun inhDepsForSyn set:Set ::= syn::String nt::String flow::EnvTree = + g:edgesFrom(syn, findFlowType(nt, flow)); -function isLhsInhSet -Boolean ::= v::FlowVertex inhSet::set:Set -{ - return case v of +fun isLhsInhSet Boolean ::= v::FlowVertex inhSet::set:Set = + case v of | lhsInhVertex(a) -> set:contains(a, inhSet) | _ -> false end; -} -function createFlowGraph -g:Graph ::= l::[Pair] -{ - return g:add(l, g:empty()); -} +fun createFlowGraph g:Graph ::= l::[Pair] = g:add(l, g:empty()); -function extendFlowGraph -g:Graph ::= l::[Pair] g::g:Graph -{ - return g:add(l, g); -} +fun extendFlowGraph g:Graph ::= l::[Pair] g::g:Graph = + g:add(l, g); -function transitiveClose +fun transitiveClose g:Graph ::= - graph::g:Graph -{ - return g:transitiveClosure(graph); -} + graph::g:Graph = g:transitiveClosure(graph); -function repairClosure +fun repairClosure g:Graph ::= newEdges::[Pair] - graph::g:Graph -{ - return g:repairClosure(newEdges, graph); -} + graph::g:Graph = g:repairClosure(newEdges, graph); diff --git a/grammars/silver/compiler/definition/flow/driver/FlowTypes.sv b/grammars/silver/compiler/definition/flow/driver/FlowTypes.sv index be74a204f..2d5da3982 100644 --- a/grammars/silver/compiler/definition/flow/driver/FlowTypes.sv +++ b/grammars/silver/compiler/definition/flow/driver/FlowTypes.sv @@ -28,32 +28,15 @@ EnvTree ::= specDefs::[(String, String, [String], [String])] return rtm:add(map(initialFlowType, specs), rtm:empty()); } -function initialFlowType -Pair ::= x::(NtName, [(String, [String])]) -{ - return (x.fst, g:add(flatMap(toFlatEdges, x.snd), g:empty())); -} -function ntListLte -Boolean ::= a::Pair b::Pair -{ - return a.fst <= b.fst; -} -function ntListEq -Boolean ::= a::Pair b::Pair -{ - return a.fst == b.fst; -} -function ntListCoalesce -[(NtName, [(String, [String])])] ::= l::[[(NtName, String, [String])]] -{ - return if null(l) then [] +fun initialFlowType Pair ::= x::(NtName, [(String, [String])]) = + (x.fst, g:add(flatMap(toFlatEdges, x.snd), g:empty())); +fun ntListLte Boolean ::= a::Pair b::Pair = a.fst <= b.fst; +fun ntListEq Boolean ::= a::Pair b::Pair = a.fst == b.fst; +fun ntListCoalesce [(NtName, [(String, [String])])] ::= l::[[(NtName, String, [String])]] = + if null(l) then [] else (head(head(l)).fst, map(snd, head(l))) :: ntListCoalesce(tail(l)); -} -function toFlatEdges -[Pair] ::= x::Pair -{ - return map(pair(fst=x.fst, snd=_), x.snd); -} +fun toFlatEdges [Pair] ::= x::Pair = + map(pair(fst=x.fst, snd=_), x.snd); {-- @@ -127,22 +110,13 @@ function findBrandNewEdges } -- Expand 'ver' using 'graph', then filter down to just those in 'inhs' -function expandVertexFilterTo -Pair ::= ver::FlowVertex graph::ProductionGraph -{ - -- TODO: we might return 'Pair>' instead of [String] and gain speed? - -- Have set:filter, don't have "set:map" yet... (FlowVertex->String) - return (ver.flowTypeName, filterLhsInh(set:toList(graph.edgeMap(ver)))); -} +fun expandVertexFilterTo Pair ::= ver::FlowVertex graph::ProductionGraph = + (ver.flowTypeName, filterLhsInh(set:toList(graph.edgeMap(ver)))); {-- - Filters vertexes down to just the names of inherited attributes on the LHS -} -function filterLhsInh -[String] ::= f::[FlowVertex] -{ - return foldr(collectInhs, [], f); -} +fun filterLhsInh [String] ::= f::[FlowVertex] = foldr(collectInhs, [], f); {-- - Used to filter down to just the inherited attributes (on the LHS) @@ -151,14 +125,11 @@ function filterLhsInh - @param l The current set of inherited attribute dependencies - @return {l} with {f} added to it -} -function collectInhs -[String] ::= f::FlowVertex l::[String] -{ - return case f of +fun collectInhs [String] ::= f::FlowVertex l::[String] = + case f of | lhsInhVertex(a) -> a::l | _ -> l end; -} {-- diff --git a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv index ca10e3095..429c764a6 100644 --- a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv @@ -88,23 +88,19 @@ top::ProductionGraph ::= end end; } -function updateGraph +fun updateGraph ProductionGraph ::= graph::ProductionGraph prodEnv::EnvTree - ntEnv::EnvTree -{ - return graph.stitchedGraph(ntEnv, prodEnv).cullSuspect(ntEnv); -} + ntEnv::EnvTree = + graph.stitchedGraph(ntEnv, prodEnv).cullSuspect(ntEnv); -- construct a production graph for each production -function computeAllProductionGraphs -[ProductionGraph] ::= prods::[ValueDclInfo] prodTree::EnvTree flowEnv::FlowEnv realEnv::Env -{ - return if null(prods) then [] +fun computeAllProductionGraphs +[ProductionGraph] ::= prods::[ValueDclInfo] prodTree::EnvTree flowEnv::FlowEnv realEnv::Env = + if null(prods) then [] else constructProductionGraph(head(prods), searchEnvTree(head(prods).fullName, prodTree), flowEnv, realEnv) :: computeAllProductionGraphs(tail(prods), prodTree, flowEnv, realEnv); -} -------------------------------------------------------------------------------- @@ -354,11 +350,8 @@ ProductionGraph ::= nt::String flowEnv::FlowEnv realEnv::Env return productionGraph("Phantom for " ++ nt, nt, flowTypeVertexes, initialGraph, suspectEdges, stitchPoints).transitiveClosure; } -function getPhantomEdge -Pair ::= at::String -{ - return (lhsSynVertex(at), forwardEqVertex()); -} +fun getPhantomEdge Pair ::= at::String = + (lhsSynVertex(at), forwardEqVertex()); ---- Begin helpers for fixing up graphs ---------------------------------------- @@ -366,60 +359,47 @@ Pair ::= at::String - Introduces implicit 'lhs.syn -> forward.syn' (& forward.eq) equations. - Called twice: once for safe edges, later for SUSPECT edges! -} -function addFwdSynEqs -[Pair] ::= prod::ProdName syns::[String] flowEnv::FlowEnv -{ - return if null(syns) then [] +fun addFwdSynEqs [Pair] ::= prod::ProdName syns::[String] flowEnv::FlowEnv = + if null(syns) then [] else (if null(lookupSyn(prod, head(syns), flowEnv)) then [(lhsSynVertex(head(syns)), forwardSynVertex(head(syns))), (lhsSynVertex(head(syns)), forwardEqVertex())] else []) ++ addFwdSynEqs(prod, tail(syns), flowEnv); -} {-- - Introduces implicit 'forward.inh = lhs.inh' equations. - Inherited equations are never suspect. -} -function addFwdInhEqs -[Pair] ::= prod::ProdName inhs::[String] flowEnv::FlowEnv -{ - return if null(inhs) then [] +fun addFwdInhEqs [Pair] ::= prod::ProdName inhs::[String] flowEnv::FlowEnv = + if null(inhs) then [] else (if null(lookupFwdInh(prod, head(inhs), flowEnv)) then [(forwardInhVertex(head(inhs)), lhsInhVertex(head(inhs)))] else []) ++ addFwdInhEqs(prod, tail(inhs), flowEnv); -} {-- - Introduces implicit 'fwrd.inh = lhs.inh' equations for forward production attributes. - Inherited equations are never suspect. -} -function addFwdProdAttrInhEqs -[Pair] ::= prod::ProdName fName::String inhs::[String] flowEnv::FlowEnv -{ - return if null(inhs) then [] +fun addFwdProdAttrInhEqs +[Pair] ::= prod::ProdName fName::String inhs::[String] flowEnv::FlowEnv = + if null(inhs) then [] else (if null(lookupLocalInh(prod, fName, head(inhs), flowEnv)) then [(localInhVertex(fName, head(inhs)), lhsInhVertex(head(inhs)))] else []) ++ addFwdProdAttrInhEqs(prod, fName, tail(inhs), flowEnv); -} -function allFwdProdAttrs -[String] ::= d::[FlowDef] -{ - return case d of +fun allFwdProdAttrs [String] ::= d::[FlowDef] = + case d of | [] -> [] | localEq(_, fN, _, true, true, _) :: rest -> fN :: allFwdProdAttrs(rest) | _ :: rest -> allFwdProdAttrs(rest) end; -} {-- - Introduces default equations deps. Realistically, should be empty, always. -} -function addDefEqs -[Pair] ::= prod::ProdName nt::NtName syns::[String] flowEnv :: FlowEnv -{ - return if null(syns) then [] +fun addDefEqs +[Pair] ::= prod::ProdName nt::NtName syns::[String] flowEnv :: FlowEnv = + if null(syns) then [] else (if null(lookupSyn(prod, head(syns), flowEnv)) then let x :: [FlowDef] = lookupDef(nt, head(syns), flowEnv) in if null(x) then [] else head(x).flowEdges end else []) ++ addDefEqs(prod, nt, tail(syns), flowEnv); -} ---- End helpers for fixing up graphs ------------------------------------------ @@ -428,26 +408,20 @@ function addDefEqs {-- - Stitch points for the flow type of 'nt', and the flow types of all translation attributes on 'nt'. -} -function nonterminalStitchPoints -[StitchPoint] ::= realEnv::Env nt::NtName vertexType::VertexType -{ - return - nonterminalStitchPoint(nt, vertexType) :: - flatMap( - \ o::OccursDclInfo -> - case getAttrDcl(o.attrOccurring, realEnv) of - | at :: _ when at.isSynthesized && at.isTranslation -> - [nonterminalStitchPoint( - at.typeScheme.typeName, - transAttrVertexType(vertexType, o.attrOccurring))] - | _ -> [] - end, - getAttrOccursOn(nt, realEnv)); -} -function localStitchPoints -[StitchPoint] ::= realEnv::Env nt::NtName ds::[FlowDef] -{ - return flatMap(\ d::FlowDef -> +fun nonterminalStitchPoints [StitchPoint] ::= realEnv::Env nt::NtName vertexType::VertexType = + nonterminalStitchPoint(nt, vertexType) :: + flatMap( + \ o::OccursDclInfo -> + case getAttrDcl(o.attrOccurring, realEnv) of + | at :: _ when at.isSynthesized && at.isTranslation -> + [nonterminalStitchPoint( + at.typeScheme.typeName, + transAttrVertexType(vertexType, o.attrOccurring))] + | _ -> [] + end, + getAttrOccursOn(nt, realEnv)); +fun localStitchPoints [StitchPoint] ::= realEnv::Env nt::NtName ds::[FlowDef] = + flatMap(\ d::FlowDef -> case d of -- We add the forward stitch point here, too! | fwdEq(_, _, _) -> nonterminalStitchPoints(realEnv, nt, forwardVertexType) @@ -458,7 +432,6 @@ function localStitchPoints -- Ignore all other flow def info | _ -> [] end, ds); -} function rhsStitchPoints [StitchPoint] ::= realEnv::Env rhs::NamedSignatureElement { @@ -468,17 +441,14 @@ function rhsStitchPoints then nonterminalStitchPoints(realEnv, rhs.typerep.typeName, rhsVertexType(rhs.elementName)) else []; } -function patternStitchPoints -[StitchPoint] ::= realEnv::Env defs::[FlowDef] -{ - return case defs of +fun patternStitchPoints [StitchPoint] ::= realEnv::Env defs::[FlowDef] = + case defs of | [] -> [] | patternRuleEq(_, matchProd, scrutinee, vars) :: rest -> flatMap(patVarStitchPoints(matchProd, scrutinee, realEnv, _), vars) ++ patternStitchPoints(realEnv, rest) | _ :: rest -> patternStitchPoints(realEnv, rest) end; -} function patVarStitchPoints [StitchPoint] ::= matchProd::String scrutinee::VertexType realEnv::Env var::PatternVarProjection { @@ -490,10 +460,8 @@ function patVarStitchPoints nonterminalStitchPoints(realEnv, typeName, anonVertexType(patternVar)) end; } -function subtermDecSiteStitchPoints -[StitchPoint] ::= flowEnv::FlowEnv realEnv::Env defs::[FlowDef] -{ - return flatMap(\ d::FlowDef -> +fun subtermDecSiteStitchPoints [StitchPoint] ::= flowEnv::FlowEnv realEnv::Env defs::[FlowDef] = + flatMap(\ d::FlowDef -> case d of | subtermDecEq(prodName, parent, termProdName, sigName) -> map(\ prodDcl::ValueDclInfo -> @@ -504,15 +472,10 @@ function subtermDecSiteStitchPoints | _ -> [] end, defs); -} ---- End helpers for figuring our stitch points -------------------------------- -function prodGraphToEnv -Pair ::= p::ProductionGraph -{ - return (p.prod, p); -} +fun prodGraphToEnv Pair ::= p::ProductionGraph = (p.prod, p); ---- Begin Suspect edge handling ----------------------------------------------- diff --git a/grammars/silver/compiler/definition/flow/driver/StitchPoint.sv b/grammars/silver/compiler/definition/flow/driver/StitchPoint.sv index e2c97dcc2..094f22a7f 100644 --- a/grammars/silver/compiler/definition/flow/driver/StitchPoint.sv +++ b/grammars/silver/compiler/definition/flow/driver/StitchPoint.sv @@ -60,37 +60,29 @@ top::StitchPoint ::= - @param prod ...of this production (prodType in here, others in original prod graph) - @return edges from 'sourceType.inhVertex(attr)' to 'targetType.inhVertex(??)' -} -function projectAttribute +fun projectAttribute [Pair] ::= attr::String sourceType::VertexType targetType::VertexType prodType::VertexType - prod::ProductionGraph -{ - -- emit edges from the src vertex of this production - return map(pair(fst=sourceType.inhVertex(attr), snd=_), + prod::ProductionGraph = + map(pair(fst=sourceType.inhVertex(attr), snd=_), -- Turn into inh vertexes (in this production) on targetType map(targetType.inhVertex, -- Filter down to just LHS Inh in that production, (string names) filterLhsInh( -- Deps of this vertex in that other production set:toList(prod.edgeMap(prodType.inhVertex(attr)))))); -} -- Useful for mapping -function stitchEdgesFor -[Pair] ::= sp::StitchPoint ntEnv::EnvTree prodEnv::EnvTree -{ - return sp.stitchEdges(ntEnv, prodEnv); -} +fun stitchEdgesFor +[Pair] ::= sp::StitchPoint ntEnv::EnvTree prodEnv::EnvTree = + sp.stitchEdges(ntEnv, prodEnv); -function edgeIsNew -Boolean ::= edge::Pair e::g:Graph -{ - return !g:contains(edge, e); -} +fun edgeIsNew Boolean ::= edge::Pair e::g:Graph = + !g:contains(edge, e); {-- - Creates edges from a "flow type" source to a "flow type" sink. @@ -99,12 +91,9 @@ Boolean ::= edge::Pair e::g:Graph - @param vt The vertex type we're creating edges within - @param edge pair of syn/fwd and inh. The edge. -} -function flowTypeEdge -Pair ::= vt::VertexType edge::Pair -{ - return if edge.fst == "forward" then +fun flowTypeEdge Pair ::= vt::VertexType edge::Pair = + if edge.fst == "forward" then (vt.fwdVertex, vt.inhVertex(edge.snd)) else (vt.synVertex(edge.fst), vt.inhVertex(edge.snd)); -} diff --git a/grammars/silver/compiler/definition/flow/env/FlowEnv.sv b/grammars/silver/compiler/definition/flow/env/FlowEnv.sv index 6b5fb4135..f96ba3d81 100644 --- a/grammars/silver/compiler/definition/flow/env/FlowEnv.sv +++ b/grammars/silver/compiler/definition/flow/env/FlowEnv.sv @@ -60,136 +60,81 @@ top::FlowEnv ::= -- synthesized equation in a production -function lookupSyn -[FlowDef] ::= prod::String attr::String e::FlowEnv -{ - return searchEnvTree(crossnames(prod, attr), e.synTree); -} +fun lookupSyn [FlowDef] ::= prod::String attr::String e::FlowEnv = + searchEnvTree(crossnames(prod, attr), e.synTree); -- inherited equation for a child in a production -function lookupInh -[FlowDef] ::= prod::String sigName::String attr::String e::FlowEnv -{ - return searchEnvTree(crossnames(prod, crossnames(sigName, attr)), e.inhTree); -} +fun lookupInh [FlowDef] ::= prod::String sigName::String attr::String e::FlowEnv = + searchEnvTree(crossnames(prod, crossnames(sigName, attr)), e.inhTree); -- default equation for a nonterminal -function lookupDef -[FlowDef] ::= nt::String attr::String e::FlowEnv -{ - return searchEnvTree(crossnames(nt, attr), e.defTree); -} +fun lookupDef [FlowDef] ::= nt::String attr::String e::FlowEnv = + searchEnvTree(crossnames(nt, attr), e.defTree); -- forward equation for a production -function lookupFwd -[FlowDef] ::= prod::String e::FlowEnv -{ - return searchEnvTree(prod, e.fwdTree); -} +fun lookupFwd [FlowDef] ::= prod::String e::FlowEnv = searchEnvTree(prod, e.fwdTree); -- inherited equation for the forward in a production -function lookupFwdInh -[FlowDef] ::= prod::String attr::String e::FlowEnv -{ - return searchEnvTree(crossnames(prod, attr), e.fwdInhTree); -} +fun lookupFwdInh [FlowDef] ::= prod::String attr::String e::FlowEnv = + searchEnvTree(crossnames(prod, attr), e.fwdInhTree); -- inherited equation for a local in a production -function lookupLocalInh -[FlowDef] ::= prod::String fName::String attr::String e::FlowEnv -{ - return searchEnvTree(crossnames(prod, crossnames(fName, attr)), e.localInhTree); -} +fun lookupLocalInh [FlowDef] ::= prod::String fName::String attr::String e::FlowEnv = + searchEnvTree(crossnames(prod, crossnames(fName, attr)), e.localInhTree); -function lookupLocalEq -[FlowDef] ::= prod::String fName::String e::FlowEnv -{ - return searchEnvTree(crossnames(prod, fName), e.localTree); -} +fun lookupLocalEq [FlowDef] ::= prod::String fName::String e::FlowEnv = + searchEnvTree(crossnames(prod, fName), e.localTree); -- unique references taken for a child -function lookupUniqueRefs -[UniqueRefSite] ::= prod::String sigName::String e::FlowEnv -{ - return searchEnvTree(prod ++ ":" ++ sigName, e.uniqueRefTree); -} +fun lookupUniqueRefs [UniqueRefSite] ::= prod::String sigName::String e::FlowEnv = + searchEnvTree(prod ++ ":" ++ sigName, e.uniqueRefTree); -- unique references taken for a local/production attribute -function lookupLocalUniqueRefs -[UniqueRefSite] ::= fName::String e::FlowEnv -{ - return searchEnvTree(fName, e.uniqueRefTree); -} +fun lookupLocalUniqueRefs [UniqueRefSite] ::= fName::String e::FlowEnv = + searchEnvTree(fName, e.uniqueRefTree); -- unique references taken for a translation attribute on a child -function lookupTransUniqueRefs -[UniqueRefSite] ::= prod::String sigName::String attrName::String e::FlowEnv -{ - return searchEnvTree(prod ++ ":" ++ sigName ++ "." ++ attrName, e.uniqueRefTree); -} +fun lookupTransUniqueRefs +[UniqueRefSite] ::= prod::String sigName::String attrName::String e::FlowEnv = + searchEnvTree(prod ++ ":" ++ sigName ++ "." ++ attrName, e.uniqueRefTree); -- unique references taken for a translation attribute on a local -function lookupLocalTransUniqueRefs -[UniqueRefSite] ::= fName::String attrName::String e::FlowEnv -{ - return searchEnvTree(fName ++ "." ++ attrName, e.uniqueRefTree); -} +fun lookupLocalTransUniqueRefs [UniqueRefSite] ::= fName::String attrName::String e::FlowEnv = + searchEnvTree(fName ++ "." ++ attrName, e.uniqueRefTree); -- possible decoration sites for unique references taken for a child -function lookupRefPossibleDecSites -[VertexType] ::= prod::String sigName::String e::FlowEnv -{ - return searchEnvTree(s"${prod}:${sigName}", e.refPossibleDecSiteTree); -} +fun lookupRefPossibleDecSites [VertexType] ::= prod::String sigName::String e::FlowEnv = + searchEnvTree(s"${prod}:${sigName}", e.refPossibleDecSiteTree); -- possible decoration sites for unique references taken for a local/production attribute -function lookupLocalRefPossibleDecSites -[VertexType] ::= fName::String e::FlowEnv -{ - return searchEnvTree(fName, e.refPossibleDecSiteTree); -} +fun lookupLocalRefPossibleDecSites [VertexType] ::= fName::String e::FlowEnv = + searchEnvTree(fName, e.refPossibleDecSiteTree); -- possible decoration sites for unique references taken for a translation attribute on a child -function lookupTransRefPossibleDecSites -[VertexType] ::= prod::String sigName::String attrName::String e::FlowEnv -{ - return searchEnvTree(s"${prod}:${sigName}.${attrName}", e.refPossibleDecSiteTree); -} +fun lookupTransRefPossibleDecSites +[VertexType] ::= prod::String sigName::String attrName::String e::FlowEnv = + searchEnvTree(s"${prod}:${sigName}.${attrName}", e.refPossibleDecSiteTree); -- possible decoration sites for unique references taken for a translation attribute on a local/production attribute -function lookupLocalTransRefPossibleDecSites -[VertexType] ::= fName::String attrName::String e::FlowEnv -{ - return searchEnvTree(s"${fName}.${attrName}", e.refPossibleDecSiteTree); -} +fun lookupLocalTransRefPossibleDecSites [VertexType] ::= fName::String attrName::String e::FlowEnv = + searchEnvTree(s"${fName}.${attrName}", e.refPossibleDecSiteTree); -- unconditional decoration sites for unique references taken for a child -function lookupRefDecSite -[VertexType] ::= prod::String sigName::String e::FlowEnv -{ - return searchEnvTree(s"${prod}:${sigName}", e.refDecSiteTree); -} +fun lookupRefDecSite [VertexType] ::= prod::String sigName::String e::FlowEnv = + searchEnvTree(s"${prod}:${sigName}", e.refDecSiteTree); -- unconditional decoration sites for unique references taken for a local/production attribute -function lookupLocalRefDecSite -[VertexType] ::= fName::String e::FlowEnv -{ - return searchEnvTree(fName, e.refDecSiteTree); -} +fun lookupLocalRefDecSite [VertexType] ::= fName::String e::FlowEnv = + searchEnvTree(fName, e.refDecSiteTree); -- unconditional decoration sites for unique references taken for a translation attribute on a child -function lookupTransRefDecSite -[VertexType] ::= prod::String sigName::String attrName::String e::FlowEnv -{ - return searchEnvTree(s"${prod}:${sigName}.${attrName}", e.refDecSiteTree); -} +fun lookupTransRefDecSite +[VertexType] ::= prod::String sigName::String attrName::String e::FlowEnv = + searchEnvTree(s"${prod}:${sigName}.${attrName}", e.refDecSiteTree); -- unconditional decoration sites for unique references taken for a translation attribute on a local/production attribute -function lookupLocalTransRefDecSite -[VertexType] ::= fName::String attrName::String e::FlowEnv -{ - return searchEnvTree(s"${fName}.${attrName}", e.refDecSiteTree); -} +fun lookupLocalTransRefDecSite [VertexType] ::= fName::String attrName::String e::FlowEnv = + searchEnvTree(s"${fName}.${attrName}", e.refDecSiteTree); {-- - This is a glorified lambda function, to help look for equations. @@ -199,25 +144,14 @@ function lookupLocalTransRefDecSite - e.g. `lookupInh(prod, rhs, _, env)` - @param attr The attribute to look up. -} -function isEquationMissing -Boolean ::= f::([FlowDef] ::= String) attr::String -{ - return null(f(attr)); -} +fun isEquationMissing Boolean ::= f::([FlowDef] ::= String) attr::String = null(f(attr)); -- default set of inherited attributes required/assumed to exist for references -function getInhsForNtRef -[[String]] ::= nt::String e::FlowEnv -{ - return searchEnvTree(nt, e.refTree); -} +fun getInhsForNtRef [[String]] ::= nt::String e::FlowEnv = searchEnvTree(nt, e.refTree); -- implicit forward syn copy equations that are allowed to affect the flow type -function getNonSuspectAttrsForProd -[String] ::= prod::String e::FlowEnv -{ - return concat(searchEnvTree(prod, e.nonSuspectTree)); -} +fun getNonSuspectAttrsForProd [String] ::= prod::String e::FlowEnv = + concat(searchEnvTree(prod, e.nonSuspectTree)); -- all (non-forwarding) productions constructing a nonterminal function getNonforwardingProds @@ -240,22 +174,13 @@ function getHostSynsFor } -- Get syns (and "forward") that have flow types specified -function getSpecifiedSynsForNt -[String] ::= nt::String e::FlowEnv -{ - return map(fst, searchEnvTree(nt, e.specTree)); -} -function getFlowTypeSpecFor -[(String, [String], [String])] ::= nt::String e::FlowEnv -{ - return searchEnvTree(nt, e.specTree); -} +fun getSpecifiedSynsForNt [String] ::= nt::String e::FlowEnv = + map(fst, searchEnvTree(nt, e.specTree)); +fun getFlowTypeSpecFor [(String, [String], [String])] ::= nt::String e::FlowEnv = + searchEnvTree(nt, e.specTree); -function getGraphContribsFor -[FlowDef] ::= prod::String e::FlowEnv -{ - return searchEnvTree(prod, e.prodGraphTree); -} +fun getGraphContribsFor [FlowDef] ::= prod::String e::FlowEnv = + searchEnvTree(prod, e.prodGraphTree); monoid attribute occursContextInhDeps::[(String, String, [String])] -- (type name, syn, inhs) occurs on Contexts, Context; diff --git a/grammars/silver/compiler/definition/flow/env/ProductionBody.sv b/grammars/silver/compiler/definition/flow/env/ProductionBody.sv index cf88c1628..bca5555ac 100644 --- a/grammars/silver/compiler/definition/flow/env/ProductionBody.sv +++ b/grammars/silver/compiler/definition/flow/env/ProductionBody.sv @@ -352,15 +352,9 @@ String ::= s::String return if i > 0 then substring(0, i, s) else ""; } -- Source grammar of a lookup of an attribute occurrence dcl -function hackGramFromDcl -String ::= qn::Decorated QNameAttrOccur -{ - return if qn.found then qn.dcl.sourceGrammar else ""; -} +fun hackGramFromDcl String ::= qn::Decorated QNameAttrOccur = + if qn.found then qn.dcl.sourceGrammar else ""; -- Source grammar of a lookup of a local dcl -function hackGramFromQName -String ::= qn::QNameLookup -{ - return if qn.found then qn.dcl.sourceGrammar else ""; -} +fun hackGramFromQName String ::= qn::QNameLookup = + if qn.found then qn.dcl.sourceGrammar else ""; diff --git a/grammars/silver/compiler/definition/type/Helpers.sv b/grammars/silver/compiler/definition/type/Helpers.sv index 8f9e3f668..fa2b741de 100644 --- a/grammars/silver/compiler/definition/type/Helpers.sv +++ b/grammars/silver/compiler/definition/type/Helpers.sv @@ -3,17 +3,10 @@ grammar silver:compiler:definition:type; global appTypes::(Type ::= Type [Type]) = foldl(appType, _, _); -- HUGE LIE: This is not a set. Well, maybe. We *might* depend on this being ordered. -function setUnionTyVars -[TyVar] ::= a::[TyVar] b::[TyVar] -{ - return a ++ removeAll(a, b); -} -function setUnionTyVarsAll -[TyVar] ::= tvs::[[TyVar]] -{ - return if null(tvs) - then [] - else if null(tail(tvs)) - then head(tvs) - else setUnionTyVars( head(tvs), setUnionTyVarsAll(tail(tvs))); -} +fun setUnionTyVars [TyVar] ::= a::[TyVar] b::[TyVar] = a ++ removeAll(a, b); +fun setUnionTyVarsAll [TyVar] ::= tvs::[[TyVar]] = + if null(tvs) + then [] + else if null(tail(tvs)) + then head(tvs) + else setUnionTyVars( head(tvs), setUnionTyVarsAll(tail(tvs))); diff --git a/grammars/silver/compiler/definition/type/PrettyPrinting.sv b/grammars/silver/compiler/definition/type/PrettyPrinting.sv index b067560d6..1a8525720 100644 --- a/grammars/silver/compiler/definition/type/PrettyPrinting.sv +++ b/grammars/silver/compiler/definition/type/PrettyPrinting.sv @@ -266,21 +266,17 @@ String ::= tv::TyVar bv::[TyVar] return findAbbrevHelp(tv, named ++ anon, ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], []); } -function findAbbrevHelp -String ::= tv::TyVar bv::[TyVar] vn::[String] assigned::[String] -{ - return - case bv, vn of - | tyVarNamed(n) :: tbv, _ when !contains(n, assigned) -> - if tv == head(bv) then n else findAbbrevHelp(tv, tbv, vn, n :: assigned) - | hbv :: tbv, hvn :: tvn -> - if contains(hvn, assigned) - then findAbbrevHelp(tv, bv, tvn, assigned) - else if tv == hbv then hvn else findAbbrevHelp(tv, tbv, tvn, hvn :: assigned) - | _, _ -> - case positionOf(tv, bv) of - | i when i > 0 && !contains("a" ++ toString(i), assigned) -> "a" ++ toString(i) - | _ -> "V_" ++ toString(tv.varId) - end - end; -} +fun findAbbrevHelp String ::= tv::TyVar bv::[TyVar] vn::[String] assigned::[String] = + case bv, vn of + | tyVarNamed(n) :: tbv, _ when !contains(n, assigned) -> + if tv == head(bv) then n else findAbbrevHelp(tv, tbv, vn, n :: assigned) + | hbv :: tbv, hvn :: tvn -> + if contains(hvn, assigned) + then findAbbrevHelp(tv, bv, tvn, assigned) + else if tv == hbv then hvn else findAbbrevHelp(tv, tbv, tvn, hvn :: assigned) + | _, _ -> + case positionOf(tv, bv) of + | i when i > 0 && !contains("a" ++ toString(i), assigned) -> "a" ++ toString(i) + | _ -> "V_" ++ toString(tv.varId) + end +end; diff --git a/grammars/silver/compiler/definition/type/Substitutions.sv b/grammars/silver/compiler/definition/type/Substitutions.sv index 8496f02be..c4a134c32 100644 --- a/grammars/silver/compiler/definition/type/Substitutions.sv +++ b/grammars/silver/compiler/definition/type/Substitutions.sv @@ -34,48 +34,26 @@ top::Substitution ::= sublst::[Pair] errs::[String] top.failure = true; } -function emptySubst -Substitution ::= -{ - return goodSubst([]); -} -function errorSubst -Substitution ::= e::String -{ - return badSubst([], [e]); -} -function subst -Substitution ::= tv::TyVar te::Type -{ - return goodSubst([(tv,te)]); -} -function composeSubst -Substitution ::= s1::Substitution s2::Substitution -{ - return case s1, s2 of +fun emptySubst Substitution ::= = goodSubst([]); +fun errorSubst Substitution ::= e::String = badSubst([], [e]); +fun subst Substitution ::= tv::TyVar te::Type = goodSubst([(tv,te)]); +fun composeSubst Substitution ::= s1::Substitution s2::Substitution = + case s1, s2 of | goodSubst(s1l), goodSubst(s2l) -> goodSubst(s1l ++ s2l) | goodSubst(s1l), badSubst(s2l, s2e) -> badSubst(s1l ++ s2l, s2e) | badSubst(s1l, s1e), goodSubst(s2l) -> badSubst(s1l ++ s2l, s1e) | badSubst(s1l, s1e), badSubst(s2l, s2e) -> badSubst(s1l ++ s2l, s1e ++ s2e) end; -} -function ignoreFailure -Substitution ::= s::Substitution -{ - return case s of - | goodSubst(_) -> s - | badSubst(sl,_) -> goodSubst(sl) - end; -} +fun ignoreFailure Substitution ::= s::Substitution = + case s of +| goodSubst(_) -> s +| badSubst(sl,_) -> goodSubst(sl) +end; -------------------------------------------------------------------------------- -function findSubst -Maybe ::= tv::TyVar s::Substitution -{ - return lookup(tv, s.substList); -} +fun findSubst Maybe ::= tv::TyVar s::Substitution = lookup(tv, s.substList); -------------------------------------------------------------------------------- @@ -198,11 +176,7 @@ Type ::= te::Type s::Substitution return te.substituted; } -function mapSubst -[Type] ::= tes::[Type] s::Substitution -{ - return map(performSubstitution(_, s), tes); -} +fun mapSubst [Type] ::= tes::[Type] s::Substitution = map(performSubstitution(_, s), tes); ---- @@ -220,67 +194,36 @@ Type ::= te::Type s::Substitution return te.flatRenamed; } -function mapRenameSubst -[Type] ::= tes::[Type] s::Substitution -{ - return map(performRenaming(_, s), tes); -} +fun mapRenameSubst [Type] ::= tes::[Type] s::Substitution = map(performRenaming(_, s), tes); -------------------------------------------------------------------------------- -- Generate fresh type vars with the same kinds as tvs -function freshTyVars -[TyVar] ::= tvs::[TyVar] -{ - return map(freshTyVar, map((.kind), tvs)); -} +fun freshTyVars [TyVar] ::= tvs::[TyVar] = map(freshTyVar, map((.kind), tvs)); -function zipVarsIntoSubstitution -Substitution ::= original::[TyVar] sub::[TyVar] -{ - -- once we have "productions are subtypes of functions" then make this just map 'varType' and call the other one below - return if null(original) || null(sub) then emptySubst() - else composeSubst(subst(head(original), varType(head(sub))), - zipVarsIntoSubstitution(tail(original), tail(sub))); -} +fun zipVarsIntoSubstitution Substitution ::= original::[TyVar] sub::[TyVar] = + if null(original) || null(sub) then emptySubst() + else composeSubst(subst(head(original), varType(head(sub))), + zipVarsIntoSubstitution(tail(original), tail(sub))); -function zipVarsIntoSkolemizedSubstitution -Substitution ::= original::[TyVar] sub::[TyVar] -{ - -- once we have "productions are subtypes of functions" then make this just map 'varType' and call the other one below - return if null(original) || null(sub) then emptySubst() - else composeSubst(subst(head(original), skolemType(head(sub))), - zipVarsIntoSkolemizedSubstitution(tail(original), tail(sub))); -} +fun zipVarsIntoSkolemizedSubstitution Substitution ::= original::[TyVar] sub::[TyVar] = + if null(original) || null(sub) then emptySubst() + else composeSubst(subst(head(original), skolemType(head(sub))), + zipVarsIntoSkolemizedSubstitution(tail(original), tail(sub))); -function zipVarsAndTypesIntoSubstitution -Substitution ::= original::[TyVar] sub::[Type] -{ - return if null(original) || null(sub) then emptySubst() - else composeSubst(subst(head(original), head(sub)), - zipVarsAndTypesIntoSubstitution(tail(original), tail(sub))); -} +fun zipVarsAndTypesIntoSubstitution Substitution ::= original::[TyVar] sub::[Type] = + if null(original) || null(sub) then emptySubst() + else composeSubst(subst(head(original), head(sub)), + zipVarsAndTypesIntoSubstitution(tail(original), tail(sub))); -function freshenType -Type ::= te::Type tvs::[TyVar] -{ - return freshenTypeWith(te, tvs, freshTyVars(tvs)); -} +fun freshenType Type ::= te::Type tvs::[TyVar] = freshenTypeWith(te, tvs, freshTyVars(tvs)); -function freshenContextWith -Context ::= c::Context tvs::[TyVar] ntvs::[TyVar] -{ - -- Freshening just straight replaces variables, not deeply substituting them. - return performContextRenaming(c, zipVarsIntoSubstitution(tvs, ntvs)); -} +fun freshenContextWith Context ::= c::Context tvs::[TyVar] ntvs::[TyVar] = + performContextRenaming(c, zipVarsIntoSubstitution(tvs, ntvs)); -function freshenTypeWith -Type ::= te::Type tvs::[TyVar] ntvs::[TyVar] -{ - -- Freshening just straight replaces variables, not deeply substituting them. - return performRenaming(te, zipVarsIntoSubstitution(tvs, ntvs)); -} +fun freshenTypeWith Type ::= te::Type tvs::[TyVar] ntvs::[TyVar] = + performRenaming(te, zipVarsIntoSubstitution(tvs, ntvs)); function errorSubstitution Substitution ::= t::Type diff --git a/grammars/silver/compiler/definition/type/Type.sv b/grammars/silver/compiler/definition/type/Type.sv index cf8a8ad71..0bbaa9f8e 100644 --- a/grammars/silver/compiler/definition/type/Type.sv +++ b/grammars/silver/compiler/definition/type/Type.sv @@ -351,20 +351,8 @@ instance Eq TyVar { global freshTyVar::(TyVar ::= Kind) = \ k::Kind -> tyVar(kind=k, varId=genInt()); global freshTyVarNamed::(TyVar ::= String Kind) = \ n::String k::Kind -> tyVarNamed(n, kind=k, varId=genInt()); -function freshType -Type ::= -{ - return varType(freshTyVar(starKind())); -} +fun freshType Type ::= = varType(freshTyVar(starKind())); -function newSkolemConstant -Type ::= -{ - return skolemType(freshTyVar(starKind())); -} +fun newSkolemConstant Type ::= = skolemType(freshTyVar(starKind())); -function freshInhSet -Type ::= -{ - return varType(freshTyVar(inhSetKind())); -} +fun freshInhSet Type ::= = varType(freshTyVar(inhSetKind())); diff --git a/grammars/silver/compiler/definition/type/Unification.sv b/grammars/silver/compiler/definition/type/Unification.sv index 946167bd1..8071d7e80 100644 --- a/grammars/silver/compiler/definition/type/Unification.sv +++ b/grammars/silver/compiler/definition/type/Unification.sv @@ -222,11 +222,8 @@ Substitution ::= te1::Type te2::Type else rightward; -- arbitrary choice of errors. Non-confluent!! } -function unifyCheck -Substitution ::= te1::Type te2::Type s::Substitution -{ - return composeSubst(ignoreFailure(s), unify(performSubstitution(te1, s), performSubstitution(te2, s))); -} +fun unifyCheck Substitution ::= te1::Type te2::Type s::Substitution = + composeSubst(ignoreFailure(s), unify(performSubstitution(te1, s), performSubstitution(te2, s))); -- This function is meant to produce a simple rewriting FROM `fromte` to `tote` -- suitable for use with `performRenaming` (vs `performSubstitution`). @@ -236,14 +233,7 @@ Substitution ::= te1::Type te2::Type s::Substitution -- should yield: v1 -> int, v2 -> v1. -- Rewriting should apply this without `v2` becoming `int`. (As normal subst would do.) -- TODO this code is obviously implemented in a fragile way. -function unifyDirectional -Substitution ::= fromte::Type tote::Type -{ - -- Currently, this is built on the assumption that the unification will not fail. - -- Therefore, for now we will FRAGILEY just call unify - -- This is a possible source of bugs/unexpected behavior? - return unify(fromte, tote); -} +fun unifyDirectional Substitution ::= fromte::Type tote::Type = unify(fromte, tote); function unifyAll Substitution ::= te1::[Type] te2::[Type] diff --git a/grammars/silver/compiler/definition/type/syntax/AspectDcl.sv b/grammars/silver/compiler/definition/type/syntax/AspectDcl.sv index dbf0a0f77..8df5d7e4d 100644 --- a/grammars/silver/compiler/definition/type/syntax/AspectDcl.sv +++ b/grammars/silver/compiler/definition/type/syntax/AspectDcl.sv @@ -6,11 +6,9 @@ attribute lexicalTypeVariables, lexicalTyVarKinds occurs on flowtype lexicalTypeVariables {realSignature, env, flowEnv, grammarName} on AspectProductionSignature, AspectProductionLHS, AspectRHS, AspectFunctionSignature, AspectFunctionLHS; flowtype lexicalTypeVariables {realSignature, env, flowEnv, grammarName, deterministicCount} on AspectRHSElem; -function addNewLexicalTyVars_ActuallyVariables -[Def] ::= gn::String sl::Location lk::[Pair] l::[String] -{ - return map(\ n::String -> aspectLexTyVarDef(gn, sl, n, freshTyVarNamed(n, fromMaybe(starKind(), lookup(n, lk)))), l); -} +fun addNewLexicalTyVars_ActuallyVariables +[Def] ::= gn::String sl::Location lk::[Pair] l::[String] = + map(\ n::String -> aspectLexTyVarDef(gn, sl, n, freshTyVarNamed(n, fromMaybe(starKind(), lookup(n, lk)))), l); -- This binds variables that appear in the signature to type variables, rather than skolem constants -- as in productions declarations. They will be unified with the "real" type, and therefore diff --git a/grammars/silver/compiler/driver/BuildProcess.sv b/grammars/silver/compiler/driver/BuildProcess.sv index a05632cc3..f6e5fc8c1 100644 --- a/grammars/silver/compiler/driver/BuildProcess.sv +++ b/grammars/silver/compiler/driver/BuildProcess.sv @@ -22,20 +22,15 @@ IO ::= args::[String] svParser::SVParser } -- Compute the environment, and then setup and do a build run. No postOps executed, though. -function cmdLineRunInitial -IOErrorable ::= args::[String] svParser::SVParser -{ - return do { +fun cmdLineRunInitial IOErrorable ::= args::[String] svParser::SVParser = + do { env::(Decorated CmdArgs, BuildEnv) <- computeEnv(args); setupBuildRun(svParser, env.1, env.2); }; -} -- Perform the postOps from a cmdLineRunInitial. -function performActions -IO ::= unit::IOErrorable -{ - return do { +fun performActions IO ::= unit::IOErrorable = + do { res::Either <- unit.run; case res of | left(re) -> do { @@ -45,42 +40,35 @@ IO ::= unit::IOErrorable | right(comp) -> runAll(comp.postOps) end; }; -} -- Parser args and environment -function computeEnv -IOErrorable<(Decorated CmdArgs, BuildEnv)> ::= args::[String] -{ - return - -- Figure out arguments - case parseArgs(args) of - | left(argErrors) -> throwRunError(1, argErrors) - | right(a) -> do { - -- Figure out build env from environment and args - benv::BuildEnv <- determineBuildEnv(a); - -- Because we want printing the version to work even if the environment is messed up - -- we premptively handle that here. This is slightly unfortunate. - -- Ideally, version printing would be just another thing we could have the command - -- line decide to go do, but currently it's hard to re-use code if we do that. - if a.displayVersion then - throwRunError(127, -- error code so 'ant' isnt run - "Silver Version 0.4.5-dev\n" ++ - "SILVER_HOME = " ++ benv.silverHome ++ "\n" ++ - "SILVER_GEN = " ++ benv.silverGen ++ "\n" ++ - "GRAMMAR_PATH:\n" ++ implode("\n", benv.grammarPath)) - else pure((a, benv)); - } - end; -} +fun computeEnv IOErrorable<(Decorated CmdArgs, BuildEnv)> ::= args::[String] = + case parseArgs(args) of + | left(argErrors) -> throwRunError(1, argErrors) + | right(a) -> do { + -- Figure out build env from environment and args + benv::BuildEnv <- determineBuildEnv(a); + -- Because we want printing the version to work even if the environment is messed up + -- we premptively handle that here. This is slightly unfortunate. + -- Ideally, version printing would be just another thing we could have the command + -- line decide to go do, but currently it's hard to re-use code if we do that. + if a.displayVersion then + throwRunError(127, -- error code so 'ant' isnt run + "Silver Version 0.4.5-dev\n" ++ + "SILVER_HOME = " ++ benv.silverHome ++ "\n" ++ + "SILVER_GEN = " ++ benv.silverGen ++ "\n" ++ + "GRAMMAR_PATH:\n" ++ implode("\n", benv.grammarPath)) + else pure((a, benv)); + } + end; -- Upon deciding that we're to build one or more grammars into a jar, we do this -function setupBuildRun +fun setupBuildRun IOErrorable ::= svParser::SVParser a::Decorated CmdArgs - benv::BuildEnv -{ - return do { + benv::BuildEnv = + do { -- Check environment stuff specific to building a grammar checkbuild::[String] <- lift(checkPreBuild(benv, a.buildGrammars)); when_(!null(checkbuild), throwRunError(1, implode("\n", checkbuild))); @@ -94,21 +82,19 @@ IOErrorable ::= return buildrun; }; -} {-- - Given an environment and a grammar to build, returns a Compilation. - Note that it's the caller's responsibility to actually evaluate that - compilation's actions. -} -function buildRun +fun buildRun IO ::= svParser::SVParser a::Decorated CmdArgs benv::BuildEnv - buildGrammars::[String] -{ - return mdo { + buildGrammars::[String] = + mdo { -- Compile grammars. There's some tricky circular program data flow here. -- This does an "initial grammar stream" composed of -- grammars and interface files that *locally* seem good. @@ -147,7 +133,6 @@ IO ::= return unit; }; -} {-- - Eat the stream `need` and produce the output stream of (maybe, if found) `RootSpec`s. @@ -156,15 +141,12 @@ IO ::= - @param need A **stream** of grammars to compile. - @param clean If true, ignore interface files entirely. -} -function compileGrammars +fun compileGrammars IO<[Maybe]> ::= svParser::SVParser benv::BuildEnv need::[String] - clean::Boolean -{ - return traverseA(\ g::String -> compileGrammar(svParser, benv, g, clean).run, need); -} + clean::Boolean = traverseA(\ g::String -> compileGrammar(svParser, benv, g, clean).run, need); {-- - Consumes a stream of parses, outputs a stream of new dependencies. @@ -203,8 +185,4 @@ data RunError = runError -- A common return type for IO functions. Does IO and returns error or whatever. type IOErrorable = EitherT; -function throwRunError -IOErrorable ::= c::Integer m::String -{ - return throwError(runError(code=c, errMsg=m)); -} +fun throwRunError IOErrorable ::= c::Integer m::String = throwError(runError(code=c, errMsg=m)); diff --git a/grammars/silver/compiler/driver/Command.sv b/grammars/silver/compiler/driver/Command.sv index 4a126e5a0..28b7c350e 100644 --- a/grammars/silver/compiler/driver/Command.sv +++ b/grammars/silver/compiler/driver/Command.sv @@ -181,20 +181,14 @@ Either ::= args::[String] else right(cmdArgs); } -function parseArgsOrError -Decorated CmdArgs ::= args::[String] -{ - return - case parseArgs(args) of - | left(msg) -> error("Failed to parse args: " ++ msg) - | right(a) -> a - end; -} +fun parseArgsOrError Decorated CmdArgs ::= args::[String] = + case parseArgs(args) of + | left(msg) -> error("Failed to parse args: " ++ msg) + | right(a) -> a + end; -function determineBuildEnv -IOErrorable ::= a::Decorated CmdArgs -{ - return do { +fun determineBuildEnv IOErrorable ::= a::Decorated CmdArgs = + do { benv :: BuildEnv <- lift(do { -- Let's locally set up and verify the environment envSH :: String <- envVar("SILVER_HOME"); @@ -221,12 +215,9 @@ IOErrorable ::= a::Decorated CmdArgs return benv; }; -} -function checkEnvironment -IO<[String]> ::= benv::BuildEnv -{ - return do { +fun checkEnvironment IO<[String]> ::= benv::BuildEnv = + do { isGenDir :: Boolean <- isDirectory(benv.silverGen); isGramDir :: Boolean <- isDirectory(benv.defaultGrammarPath); @@ -243,14 +234,12 @@ IO<[String]> ::= benv::BuildEnv -- TODO: We should probably check everything in grammarPath? -- TODO: Maybe look for 'core' specifically? }; -} -function checkPreBuild +fun checkPreBuild IO<[String]> ::= benv::BuildEnv - buildGrammars::[String] -{ - return pure( + buildGrammars::[String] = + pure( if null(buildGrammars) then ["No grammar(s) to build were specified.\n"] else flatMap(\ buildGrammar::String -> if indexOf("/", buildGrammar) != -1 -- basic sanity check @@ -259,8 +248,6 @@ IO<[String]> ::= then ["Build grammar appears to contain dots: " ++ buildGrammar ++ "\n"] else [], buildGrammars)); - -- TODO: presently, we check whether we find this grammar elsewhere. Maybe it should be here? not sure. -} -- This code has to live in the generated jar for the program, as putting it in the -- standard library may someday return the location of the standard library jar instead diff --git a/grammars/silver/compiler/driver/CompileFiles.sv b/grammars/silver/compiler/driver/CompileFiles.sv index c09e48635..c383429ea 100644 --- a/grammars/silver/compiler/driver/CompileFiles.sv +++ b/grammars/silver/compiler/driver/CompileFiles.sv @@ -7,26 +7,22 @@ grammar silver:compiler:driver; - @param files The list of .sv files to read. - @return An IO action constructing the list of parse results and parse errors. -} -function compileFiles -IO<([Root], [ParseError])> ::= svParser::SVParser gpath::String files::[String] -{ - return - case files of - | file :: rest -> do { - rawText :: String <- readFile(gpath ++ file); - let text :: String = transformFile(file, rawText); +fun compileFiles IO<([Root], [ParseError])> ::= svParser::SVParser gpath::String files::[String] = + case files of + | file :: rest -> do { + rawText :: String <- readFile(gpath ++ file); + let text :: String = transformFile(file, rawText); - -- This is where a .sv file actually gets parsed: - let r :: ParseResult = svParser(text, file); + -- This is where a .sv file actually gets parsed: + let r :: ParseResult = svParser(text, file); - -- Continue parsing the rest of the files. - recurse :: ([Root], [ParseError]) <- compileFiles(svParser, gpath, rest); - return - case r of - | parseSucceeded(rtree, _) -> (rtree :: recurse.1, recurse.2) - | parseFailed(errval, _) -> (recurse.1, errval :: recurse.2) - end; - } - | [] -> pure(([], [])) - end; -} + -- Continue parsing the rest of the files. + recurse :: ([Root], [ParseError]) <- compileFiles(svParser, gpath, rest); + return + case r of + | parseSucceeded(rtree, _) -> (rtree :: recurse.1, recurse.2) + | parseFailed(errval, _) -> (recurse.1, errval :: recurse.2) + end; + } + | [] -> pure(([], [])) + end; diff --git a/grammars/silver/compiler/driver/CompileGrammar.sv b/grammars/silver/compiler/driver/CompileGrammar.sv index 33e3e8ccd..ff89f9644 100644 --- a/grammars/silver/compiler/driver/CompileGrammar.sv +++ b/grammars/silver/compiler/driver/CompileGrammar.sv @@ -64,71 +64,49 @@ MaybeT ::= }; } -function foldRoot -Grammar ::= l::[Root] -{ - return foldr(consGrammar, nilGrammar(), l); -} +fun foldRoot Grammar ::= l::[Root] = foldr(consGrammar, nilGrammar(), l); {-- - Determined whether a file name should be considered a Silver source file. -} -function isValidSilverFile -Boolean ::= f::String -{ - return any(map(endsWith(_, f), allowedSilverFileExtensions)) && !startsWith(".", f); -} -function listSilverFiles -IO<[String]> ::= dir::String -{ - return do { +fun isValidSilverFile Boolean ::= f::String = + any(map(endsWith(_, f), allowedSilverFileExtensions)) && !startsWith(".", f); +fun listSilverFiles IO<[String]> ::= dir::String = + do { files :: [String] <- listContents(dir); return filter(isValidSilverFile, files); }; -} {-- - Determines the maximum modification time of all files in a directory. - Including the directory itself, to detect file deletions. -} -function fileTimes -IO ::= dir::String is::[String] -{ - return - case is of - | [] -> fileTime(dir) -- check the directory itself. Catches deleted files. - | h :: t -> do { - ft :: Integer <- fileTime(dir ++ h); - rest :: Integer <- fileTimes(dir, t); - return max(ft, rest); - } - end; -} +fun fileTimes IO ::= dir::String is::[String] = + case is of + | [] -> fileTime(dir) -- check the directory itself. Catches deleted files. + | h :: t -> do { + ft :: Integer <- fileTime(dir ++ h); + rest :: Integer <- fileTimes(dir, t); + return max(ft, rest); + } + end; -- A crude approximation of line wrapping -function renderFileNames -String ::= files::[String] depth::Integer -{ - return - if null(files) then "" else - if depth >= 7 then "\n\t " ++ renderFileNames(files, 0) else - head(files) ++ - if null(tail(files)) then "" else " " ++ renderFileNames(tail(files), depth + 1); -} +fun renderFileNames String ::= files::[String] depth::Integer = + if null(files) then "" else + if depth >= 7 then "\n\t " ++ renderFileNames(files, 0) else + head(files) ++ + if null(tail(files)) then "" else " " ++ renderFileNames(tail(files), depth + 1); {-- - Takes a grammar name (already converted to a path) and searches the grammar - path for the first directory that matches. -} -function findGrammarLocation -MaybeT ::= path::String searchPaths::[String] -{ - return - case searchPaths of - | h :: t -> alt(findGrammarInLocation(path, h), findGrammarLocation(path, t)) - | [] -> empty - end; -} +fun findGrammarLocation MaybeT ::= path::String searchPaths::[String] = + case searchPaths of + | h :: t -> alt(findGrammarInLocation(path, h), findGrammarLocation(path, t)) + | [] -> empty + end; {-- - Looks to see if the grammar can be found in 'inPath' diff --git a/grammars/silver/compiler/driver/CompileInterface.sv b/grammars/silver/compiler/driver/CompileInterface.sv index ba3d2a424..24ea5aad0 100644 --- a/grammars/silver/compiler/driver/CompileInterface.sv +++ b/grammars/silver/compiler/driver/CompileInterface.sv @@ -48,15 +48,11 @@ MaybeT ::= grammarName::String silverHostGen::[String] {-- - Takes a grammar name (already converted to a path) and searches for Silver.svi -} -function findInterfaceLocation -MaybeT ::= gramPath::String searchPaths::[String] -{ - return - case searchPaths of - | [] -> empty - | h :: t -> do { - exists :: Boolean <- lift(isFile(h ++ "src/" ++ gramPath ++ "Silver.svi")); - if exists then pure(h) else findInterfaceLocation(gramPath, t); - } - end; -} +fun findInterfaceLocation MaybeT ::= gramPath::String searchPaths::[String] = + case searchPaths of + | [] -> empty + | h :: t -> do { + exists :: Boolean <- lift(isFile(h ++ "src/" ++ gramPath ++ "Silver.svi")); + if exists then pure(h) else findInterfaceLocation(gramPath, t); + } + end; diff --git a/grammars/silver/compiler/driver/DriverAction.sv b/grammars/silver/compiler/driver/DriverAction.sv index 43cbd666d..5351c5494 100644 --- a/grammars/silver/compiler/driver/DriverAction.sv +++ b/grammars/silver/compiler/driver/DriverAction.sv @@ -34,11 +34,8 @@ top::DriverAction ::= r::[Decorated RootSpec] genPath::String top.run = do { touchFiles(map(sviPath(_, genPath), r)); return 0; }; top.order = 3; } -function sviPath -String ::= r::Decorated RootSpec genPath::String -{ - return genPath ++ "src/" ++ grammarToPath(r.declaredName) ++ "Silver.svi"; -} +fun sviPath String ::= r::Decorated RootSpec genPath::String = + genPath ++ "src/" ++ grammarToPath(r.declaredName) ++ "Silver.svi"; abstract production printAllBindingErrors top::DriverAction ::= specs::[Decorated RootSpec] @@ -87,16 +84,10 @@ top::DriverAction ::= specs::[Decorated RootSpec] top.order = 0; } -function renderMessages -String ::= grammarSource::String msg::Pair -{ - return " [" ++ grammarSource ++ msg.fst ++ "]\n" ++ messagesToString(msg.snd) ++ "\n"; -} +fun renderMessages String ::= grammarSource::String msg::Pair = + " [" ++ grammarSource ++ msg.fst ++ "]\n" ++ messagesToString(msg.snd) ++ "\n"; -function grammarContainsErrors -Boolean ::= es::[Pair] werr::Boolean -{ - return if null(es) then false +fun grammarContainsErrors Boolean ::= es::[Pair] werr::Boolean = + if null(es) then false else containsErrors(head(es).snd, werr) || grammarContainsErrors(tail(es), werr); -} diff --git a/grammars/silver/compiler/driver/util/BuildEnv.sv b/grammars/silver/compiler/driver/util/BuildEnv.sv index 7c4f5e808..c4eb3c694 100644 --- a/grammars/silver/compiler/driver/util/BuildEnv.sv +++ b/grammars/silver/compiler/driver/util/BuildEnv.sv @@ -71,10 +71,6 @@ BuildEnv ::= {-- - Ensures a string ends with a forward slash. Safe to use if it already has one. -} -function endWithSlash -String ::= s::String -{ - return if endsWith("/", s) then s else s ++ "/"; -} +fun endWithSlash String ::= s::String = if endsWith("/", s) then s else s ++ "/"; diff --git a/grammars/silver/compiler/driver/util/Compilation.sv b/grammars/silver/compiler/driver/util/Compilation.sv index 6fd3b9923..c584dfe39 100644 --- a/grammars/silver/compiler/driver/util/Compilation.sv +++ b/grammars/silver/compiler/driver/util/Compilation.sv @@ -103,9 +103,6 @@ top::Grammars ::= - @param keep The set of grammars to keep - @param d The list of grammars to filter -} -function keepGrammars -[Decorated RootSpec] ::= keep::[String] d::[Decorated RootSpec] -{ - return filter(\ r::Decorated RootSpec -> contains(r.declaredName, keep), d); -} +fun keepGrammars [Decorated RootSpec] ::= keep::[String] d::[Decorated RootSpec] = + filter(\ r::Decorated RootSpec -> contains(r.declaredName, keep), d); diff --git a/grammars/silver/compiler/driver/util/DriverAction.sv b/grammars/silver/compiler/driver/util/DriverAction.sv index 2ff794b0c..4b0986eff 100644 --- a/grammars/silver/compiler/driver/util/DriverAction.sv +++ b/grammars/silver/compiler/driver/util/DriverAction.sv @@ -7,12 +7,9 @@ synthesized attribute order :: Integer; {-- - Run actions in order until a non-zero error code is encountered. -} -function runAll -IO ::= l::[DriverAction] -{ - return foldl( +fun runAll IO ::= l::[DriverAction] = + foldl( \ prev::IO a::DriverAction -> bind(prev, \ code::Integer -> if code != 0 then pure(code) else a.run), pure(0), sortBy(\ a::DriverAction b::DriverAction -> a.order <= b.order, l)); -} diff --git a/grammars/silver/compiler/driver/util/ModuleGraph.sv b/grammars/silver/compiler/driver/util/ModuleGraph.sv index 4e688a651..02dbdd76f 100644 --- a/grammars/silver/compiler/driver/util/ModuleGraph.sv +++ b/grammars/silver/compiler/driver/util/ModuleGraph.sv @@ -30,19 +30,14 @@ mentionedGrammars: Any mentioned grammar (for build process, what grammars to lo - @param e All built grammars - @return Whether the target is exported by the sources. -} -function isExportedBy -Boolean ::= target::String sources::[String] e::EnvTree -{ - return contains(target, computeOptionalDeps(sources, e)); -} +fun isExportedBy Boolean ::= target::String sources::[String] e::EnvTree = + contains(target, computeOptionalDeps(sources, e)); {-- - Alternate for the "reference set" heuristic: ignore options, but otherwise follow exports -} -function isStrictlyExportedBy -Boolean ::= target::String sources::[String] e::EnvTree -{ - return contains(target, computeDependencies(sources, e)); -} +fun isStrictlyExportedBy +Boolean ::= target::String sources::[String] e::EnvTree = + contains(target, computeDependencies(sources, e)); {-- @@ -98,11 +93,8 @@ function expandAllDeps - @param e All built grammars - @return The initial set, plus any grammar directly or indirectly exported by it, even conditionally. -} -function computeDependencies -[String] ::= need::[String] e::EnvTree -{ - return expandCondBuilds(expandExports(need, [], e), [], [], e); -} +fun computeDependencies [String] ::= need::[String] e::EnvTree = + expandCondBuilds(expandExports(need, [], e), [], [], e); {-- - Closes over triggered grammars, including the exports (and triggers ofc) of those triggered grammars. @@ -207,18 +199,11 @@ function inductivelyExpand - @param rules A set of rules [[trigger, triggered by any of...]...] - @return A list of triggers that the initial set tripped, not in the inital set already. -} -function noninductiveExpansion -[String] ::= initial::[String] rules::[[String]] -{ - return if null(rules) then [] - else if any(map(contains(_, initial), tail(head(rules)))) && !contains(head(head(rules)), initial) - then head(head(rules)) :: noninductiveExpansion(initial, tail(rules)) - else noninductiveExpansion(initial, tail(rules)); -} +fun noninductiveExpansion [String] ::= initial::[String] rules::[[String]] = + if null(rules) then [] + else if any(map(contains(_, initial), tail(head(rules)))) && !contains(head(head(rules)), initial) + then head(head(rules)) :: noninductiveExpansion(initial, tail(rules)) + else noninductiveExpansion(initial, tail(rules)); -function skipNulls -[b] ::= f::([b] ::= a) l::[a] -{ - return if null(l) then [] else f(head(l)); -} +fun skipNulls [b] ::= f::([b] ::= a) l::[a] = if null(l) then [] else f(head(l)); diff --git a/grammars/silver/compiler/driver/util/RootSpec.sv b/grammars/silver/compiler/driver/util/RootSpec.sv index a1521a695..b0dc6401a 100644 --- a/grammars/silver/compiler/driver/util/RootSpec.sv +++ b/grammars/silver/compiler/driver/util/RootSpec.sv @@ -200,10 +200,8 @@ top::RootSpec ::= e::[ParseError] grammarName::String grammarSource::String g top.serInterface = error("errorRootSpec demanded interface"); } -function parseErrorToMessage -Pair ::= grammarSource::String e::ParseError -{ - return case e of +fun parseErrorToMessage Pair ::= grammarSource::String e::ParseError = + case e of | syntaxError(str, locat, _, _) -> (locat.filename, [err(locat, @@ -213,7 +211,6 @@ Pair ::= grammarSource::String e::ParseError [err(loc(grammarSource ++ file, -1, -1, -1, -1, -1, -1), "Unknown error while parsing:\n" ++ str)]) end; -} monoid attribute maybeGrammarSource::Maybe with nothing(), orElse; monoid attribute maybeGrammarTime::Maybe with nothing(), orElse; @@ -392,11 +389,8 @@ InterfaceItems ::= r::Decorated RootSpec {-- - All grammar names mentioned by this root spec (not transitive!) -} -function mentionedGrammars -[String] ::= r::Decorated RootSpec -{ - return nub(r.moduleNames ++ concat(r.condBuild) ++ r.optionalGrammars); -} +fun mentionedGrammars [String] ::= r::Decorated RootSpec = + nub(r.moduleNames ++ concat(r.condBuild) ++ r.optionalGrammars); -- We're comparing INTERFACE TIME against GRAMMAR TIME, just to emphasize what's going on here... function isOutOfDate diff --git a/grammars/silver/compiler/driver/util/Util.sv b/grammars/silver/compiler/driver/util/Util.sv index af289ae97..80946d626 100644 --- a/grammars/silver/compiler/driver/util/Util.sv +++ b/grammars/silver/compiler/driver/util/Util.sv @@ -9,24 +9,14 @@ global allowedSilverFileExtensions::[String] = [".sv", ".ag", ".sv.md", ".ag.md" {-- - Turns a grammar name into a path, including trailing slash. -} -function grammarToPath -String ::= g::String -{ - return substitute(":", "/", g) ++ "/"; -} +fun grammarToPath String ::= g::String = substitute(":", "/", g) ++ "/"; @{-- - Given a path (with terminating /) and list of (file names relative to that root, contents), - write these out. -} -function writeFiles -IO<()> ::= path::String s::[(String, String)] -{ - return traverse_(\ item::(String, String) -> writeFile(path ++ item.1, item.2), s); -} +fun writeFiles IO<()> ::= path::String s::[(String, String)] = + traverse_(\ item::(String, String) -> writeFile(path ++ item.1, item.2), s); -function writeBinaryFiles -IO<()> ::= path::String s::[(String, ByteArray)] -{ - return traverse_(\ item::(String, ByteArray) -> writeBinaryFile(path ++ item.1, item.2), s); -} +fun writeBinaryFiles IO<()> ::= path::String s::[(String, ByteArray)] = + traverse_(\ item::(String, ByteArray) -> writeBinaryFile(path ++ item.1, item.2), s); diff --git a/grammars/silver/compiler/extension/convenience/Children.sv b/grammars/silver/compiler/extension/convenience/Children.sv index 14b8ae09a..65f74ed48 100644 --- a/grammars/silver/compiler/extension/convenience/Children.sv +++ b/grammars/silver/compiler/extension/convenience/Children.sv @@ -21,8 +21,5 @@ top::Expr ::= '$' e::Int_t forwards to baseExpr(qName(ref)); } -function findChild -Maybe ::= i::Integer s::[String] -{ - return if null(s) then nothing() else if i == 0 then just(head(s)) else findChild(i-1, tail(s)); -} +fun findChild Maybe ::= i::Integer s::[String] = + if null(s) then nothing() else if i == 0 then just(head(s)) else findChild(i-1, tail(s)); diff --git a/grammars/silver/compiler/extension/convenience/Lists.sv b/grammars/silver/compiler/extension/convenience/Lists.sv index 9c3d3c3c4..446265050 100644 --- a/grammars/silver/compiler/extension/convenience/Lists.sv +++ b/grammars/silver/compiler/extension/convenience/Lists.sv @@ -53,13 +53,10 @@ top::QNames ::= id1::QNameWithTL ',' id2::QNames -------------------------------------------------------------------------------- -function makeOccursDcls -AGDcl ::= ats::[QNameWithTL] nts::[QNameWithTL] -{ - return if null(ats) - then emptyAGDcl() - else appendAGDcl(makeOccursDclsHelp(head(ats), nts), makeOccursDcls(tail(ats), nts)); -} +fun makeOccursDcls AGDcl ::= ats::[QNameWithTL] nts::[QNameWithTL] = + if null(ats) + then emptyAGDcl() + else appendAGDcl(makeOccursDclsHelp(head(ats), nts), makeOccursDcls(tail(ats), nts)); function makeOccursDclsHelp AGDcl ::= at::QNameWithTL nts::[QNameWithTL] diff --git a/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv b/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv index 7f2ddad32..6d9a8b2e4 100644 --- a/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv +++ b/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv @@ -7,15 +7,11 @@ import silver:compiler:modification:let_fix; - @param l the list of patterns to modify - @return A patternList List-Like Nonterminal instance. -} -function makePatternListFromListofPatterns -PatternList ::= l::[Pattern] -{ - return - foldr( - \next::Pattern accum::PatternList -> patternList_more(next, ',', accum), - patternList_nil(), - l); -} +fun makePatternListFromListofPatterns PatternList ::= l::[Pattern] = + foldr( + \next::Pattern accum::PatternList -> patternList_more(next, ',', accum), + patternList_nil(), + l); @@ -44,10 +40,8 @@ function collectPatternsFromPatternList - @return A patternList List-like construct containing only the subpatterns of the list that was provided. - @warning Note that the subpatterns being extracted here are only applications of productions. -} -function extractSubPatternListsFromProdPatterns -PatternList ::= pl::PatternList -{ - return makePatternListFromListofPatterns( +fun extractSubPatternListsFromProdPatterns PatternList ::= pl::PatternList = + makePatternListFromListofPatterns( foldr( append, [], @@ -57,7 +51,6 @@ PatternList ::= pl::PatternList | _ -> [] end, collectPatternsFromPatternList(pl,[]))))); -} @{- @@ -65,17 +58,13 @@ PatternList ::= pl::PatternList - @param l A list of Expr's. - @return A combined Exprs List-like construct made from the Expr's in the input list. -} -function makeExprsFromExprList -Exprs ::= l::[Expr] -{ - return - if null(l) then exprsEmpty() - else - foldrLastElem( - \leftelem::Expr accum::Exprs -> exprsCons(leftelem,',',accum), - \elem::Expr -> exprsSingle(elem), - l); -} +fun makeExprsFromExprList Exprs ::= l::[Expr] = + if null(l) then exprsEmpty() + else + foldrLastElem( + \leftelem::Expr accum::Exprs -> exprsCons(leftelem,',',accum), + \elem::Expr -> exprsSingle(elem), + l); @{- @@ -83,16 +72,12 @@ Exprs ::= l::[Expr] - @param l A list of match rules. - @return A MRuleList list-like construct from the list of match rules. -} -function makeMRuleListFromListMatchRules -MRuleList ::= l::[MatchRule] -{ - return foldrLastElem( +fun makeMRuleListFromListMatchRules MRuleList ::= l::[MatchRule] = + foldrLastElem( \leftelem::MatchRule accum::MRuleList -> mRuleList_cons(leftelem,'|',accum), \a::MatchRule -> mRuleList_one(a), l); -} - @{- - Given a MRuleList element, transforms it into a regular list of MatchRules - @param l A List-like construct MRuleList instance. @@ -162,11 +147,7 @@ PatternList ::= mr::MatchRule - @param name The name being defined. - @return a concrete definition LHS element that uses the name provided. -} -function makeDefinitionLHSFromName -DefLHS ::= name::Name -{ - return concreteDefLHS(qNameId(name)); -} +fun makeDefinitionLHSFromName DefLHS ::= name::Name = concreteDefLHS(qNameId(name)); @{- - This function takes in a name, aspectRHS, and expr, returning a let expression that binds the name we provide to the name of @@ -177,19 +158,15 @@ DefLHS ::= name::Name - @param e The expression that uses the name we're defining and will be surrounded by let. - @return A Let expr that binds the name we provide to the "top" term in our aspect production with let, and surrounds the expression we gave. -} -function makeLetExprForTopRenaming -Expr ::= newName::Name aspectLHS::Decorated ConvAspectLHS e::Expr -{ - return letp( - assignExpr( - newName, - '::', - aspectLHS.aspectType, - '=', - baseExpr(qNameId(aspectLHS.aspectName))), - e); - -} +fun makeLetExprForTopRenaming Expr ::= newName::Name aspectLHS::Decorated ConvAspectLHS e::Expr = + letp( + assignExpr( + newName, + '::', + aspectLHS.aspectType, + '=', + baseExpr(qNameId(aspectLHS.aspectName))), + e); @{- @hide @@ -448,18 +425,10 @@ Pattern ::= mRule::MatchRule - @param r second match rule - @return Boolean telling us if the head pattern of two match rules uses the same production (or are equivalent in terms of being a wildcard or varpattern). -} -function eqHeadPatternMatchRule -Boolean ::= l::MatchRule r::MatchRule -{ - -- The reason this isn't done with attributes is that demanding attributes - -- (from silver core lang elements) has caused infinite loops and mwda errors - -- for me (due to me working with concrete syntax elements, I'm presuming), so I've been - -- avoiding demanding attributes as much as possible. - return - eqProdNamePattern( - extractHeadPatternFromMatchRule(l), - extractHeadPatternFromMatchRule(r)); -} +fun eqHeadPatternMatchRule Boolean ::= l::MatchRule r::MatchRule = + eqProdNamePattern( + extractHeadPatternFromMatchRule(l), + extractHeadPatternFromMatchRule(r)); @{- diff --git a/grammars/silver/compiler/extension/deriving/Derive.sv b/grammars/silver/compiler/extension/deriving/Derive.sv index 80fe2dca6..4ce98e01b 100644 --- a/grammars/silver/compiler/extension/deriving/Derive.sv +++ b/grammars/silver/compiler/extension/deriving/Derive.sv @@ -273,13 +273,9 @@ top::AGDcl ::= nt::Decorated! QName }; } -function foldPrimPatterns -PrimPatterns ::= ps::[PrimPattern] -{ - return - case ps of - | [h] -> onePattern(h) - | h :: t -> consPattern(h, '|', foldPrimPatterns(t)) - | [] -> error("empty patterns") - end; -} +fun foldPrimPatterns PrimPatterns ::= ps::[PrimPattern] = + case ps of + | [h] -> onePattern(h) + | h :: t -> consPattern(h, '|', foldPrimPatterns(t)) + | [] -> error("empty patterns") + end; diff --git a/grammars/silver/compiler/extension/doc/core/CommentItem.sv b/grammars/silver/compiler/extension/doc/core/CommentItem.sv index 4921a3137..9e8b8ec35 100644 --- a/grammars/silver/compiler/extension/doc/core/CommentItem.sv +++ b/grammars/silver/compiler/extension/doc/core/CommentItem.sv @@ -12,13 +12,10 @@ items for the list of CommentItems that AGDcl is given -} -function sanitizeAnchor -String ::= n::String -{ - return substitute(" ", "_", substitute("[", "_", substitute("]", "_", +fun sanitizeAnchor String ::= n::String = + substitute(" ", "_", substitute("[", "_", substitute("]", "_", substitute("<", "_", substitute(">", "_", substitute("(", "_", substitute(")", "_", n))))))); -} function makeStub String ::= forName::String docUnparse::String grammarName::String @@ -60,8 +57,5 @@ top::CommentItem ::= forName::String docUnparse::String grammarName::String top.undocNames = [forName]; } -function mkUndocumentedItem -CommentItem ::= f::String t::Decorated AGDcl -{ - return undocumentedItem(f, t.docUnparse, t.grammarName); -} +fun mkUndocumentedItem CommentItem ::= f::String t::Decorated AGDcl = + undocumentedItem(f, t.docUnparse, t.grammarName); diff --git a/grammars/silver/compiler/extension/doc/core/DocConfig.sv b/grammars/silver/compiler/extension/doc/core/DocConfig.sv index ca1e59d07..b2ae6996f 100644 --- a/grammars/silver/compiler/extension/doc/core/DocConfig.sv +++ b/grammars/silver/compiler/extension/doc/core/DocConfig.sv @@ -36,74 +36,53 @@ end; -- a grammar with @excludeGrammar containing file(s) with @excludeFile false will -- only emit docs for that file(s) -function doesExcludeFile -Boolean ::= args::[DocConfigSetting] -{ - return case args of - | fileNoDocsConfig(v)::_ -> v - | grammarNoDocsConfig(true)::_ -> true - | _::r -> doesExcludeFile(r) - | [] -> false - end; -} +fun doesExcludeFile Boolean ::= args::[DocConfigSetting] = + case args of + | fileNoDocsConfig(v)::_ -> v + | grammarNoDocsConfig(true)::_ -> true + | _::r -> doesExcludeFile(r) + | [] -> false + end; -function getFileTitle -String ::= args::[DocConfigSetting] fallback::String -{ - return case args of - | titleConfig(x)::_ -> x - | _::r -> getFileTitle(r, fallback) - | [] -> fallback - end; -} +fun getFileTitle String ::= args::[DocConfigSetting] fallback::String = + case args of + | titleConfig(x)::_ -> x + | _::r -> getFileTitle(r, fallback) + | [] -> fallback + end; -function getGrammarTitle -String ::= args::[DocConfigSetting] fallback::String -{ - return case args of - | grammarTitleConfig(x)::_ -> x - | _::r -> getGrammarTitle(r, fallback) - | [] -> fallback - end; -} +fun getGrammarTitle String ::= args::[DocConfigSetting] fallback::String = + case args of + | grammarTitleConfig(x)::_ -> x + | _::r -> getGrammarTitle(r, fallback) + | [] -> fallback + end; -function getFileWeight -Integer ::= args::[DocConfigSetting] -{ - return case args of - | weightConfig(x)::_ -> x - | _::r -> getFileWeight(r) - | [] -> 0 - end; -} +fun getFileWeight Integer ::= args::[DocConfigSetting] = + case args of + | weightConfig(x)::_ -> x + | _::r -> getFileWeight(r) + | [] -> 0 + end; -function getGrammarWeight -Integer ::= args::[DocConfigSetting] -{ - return case args of - | grammarWeightConfig(x)::_ -> x - | _::r -> getGrammarWeight(r) - | [] -> 0 - end; -} +fun getGrammarWeight Integer ::= args::[DocConfigSetting] = + case args of + | grammarWeightConfig(x)::_ -> x + | _::r -> getGrammarWeight(r) + | [] -> 0 + end; -function getSplit -Boolean ::= args::[DocConfigSetting] -{ - return case args of - | fileSplitConfig(v)::_ -> v - | splitConfig(true)::_ -> true - | _::r -> getSplit(r) - | [] -> false - end; -} +fun getSplit Boolean ::= args::[DocConfigSetting] = + case args of + | fileSplitConfig(v)::_ -> v + | splitConfig(true)::_ -> true + | _::r -> getSplit(r) + | [] -> false + end; -function getToc -Boolean ::= args::[DocConfigSetting] -{ - return case args of - | tocConfig(v)::_ -> v - | _::r -> getToc(r) - | [] -> false - end; -} +fun getToc Boolean ::= args::[DocConfigSetting] = + case args of + | tocConfig(v)::_ -> v + | _::r -> getToc(r) + | [] -> false + end; diff --git a/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv b/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv index e5297cb01..64844c66c 100644 --- a/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv +++ b/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv @@ -22,24 +22,18 @@ DclComment ::= conf::Decorated CmdArgs body::DocComment_t return if conf.parseDocs then comment else theEmptyDclComment; } -function getFreeTypeNames -[String] ::= l::[TyVar] -{ - return case l of - | tyVarNamed(s)::xs -> s :: getFreeTypeNames(xs) - | _::xs -> getFreeTypeNames(xs) - | [] -> [] - end; -} +fun getFreeTypeNames [String] ::= l::[TyVar] = + case l of + | tyVarNamed(s)::xs -> s :: getFreeTypeNames(xs) + | _::xs -> getFreeTypeNames(xs) + | [] -> [] + end; -function getFirstAGDcl -Decorated AGDcl ::= a::Decorated AGDcl -{ - return case a of - | appendAGDcl(x, _) -> getFirstAGDcl(x) - | x -> x - end; -} +fun getFirstAGDcl Decorated AGDcl ::= a::Decorated AGDcl = + case a of + | appendAGDcl(x, _) -> getFirstAGDcl(x) + | x -> x + end; @{- - This wraps an AGDcl to allow it to be prefixed with a doc comment. AGDcls will by default diff --git a/grammars/silver/compiler/extension/doc/core/RootSpec.sv b/grammars/silver/compiler/extension/doc/core/RootSpec.sv index 6a2b94e76..83892d2f5 100644 --- a/grammars/silver/compiler/extension/doc/core/RootSpec.sv +++ b/grammars/silver/compiler/extension/doc/core/RootSpec.sv @@ -29,39 +29,34 @@ top::RootSpec ::= g::Grammar _ _ _ _ _ g.downDocConfig = g.upDocConfig; } -function silverToMdFilename -String ::= fileName::String -{ - return foldr( +fun silverToMdFilename String ::= fileName::String = + foldr( \ ext::String file::String -> if endsWith(ext, file) then substitute(ext, ".md", file) else file, fileName, allowedSilverFileExtensions); -} @{- - Turn the files in a grammar into zero or more single-file docs pages, and collect the rest of the docs - (possibly zero) into the index file. -} -function toSplitFiles -[Pair] ::= g::Decorated Grammar with {decorate, downDocConfig} grammarConf::[DocConfigSetting] forIndex::[CommentItem] soFar::[Pair] -{ - return case g of - | consGrammar(this, rest) -> - let filename::String = getParsedOriginLocation(this).fromJust.filename - in if getSplit(this.localDocConfig) then toSplitFiles(rest, grammarConf, forIndex, formatFile( - silverToMdFilename(filename), - getFileTitle(this.localDocConfig, silverToMdFilename(filename)), - getFileWeight(this.localDocConfig), true, - s"In grammar `${g.grammarName}` file `${filename}`: "++(if getToc(this.localDocConfig) then "{{< toc >}}" else ""), - this.docs) ++ soFar) else toSplitFiles(rest, grammarConf, forIndex ++ this.docs, soFar) - end - | nilGrammar() -> let skel::Boolean = (length(soFar) == 0 && length(grammarConf) == 0 && length(forIndex) == 0) in - formatFile("_index.md", - getGrammarTitle(grammarConf, "["++g.grammarName++"]"++(if skel then " (skel)" else "")), - getGrammarWeight(grammarConf) + (if skel then 10000 else 0), - false, s"Contents of `[${g.grammarName}]`: {{< toc-tree >}} \n\nDefined in this grammar:", forIndex) ++ soFar end - end; -} +fun toSplitFiles +[Pair] ::= g::Decorated Grammar with {decorate, downDocConfig} grammarConf::[DocConfigSetting] forIndex::[CommentItem] soFar::[Pair] = + case g of + | consGrammar(this, rest) -> + let filename::String = getParsedOriginLocation(this).fromJust.filename + in if getSplit(this.localDocConfig) then toSplitFiles(rest, grammarConf, forIndex, formatFile( + silverToMdFilename(filename), + getFileTitle(this.localDocConfig, silverToMdFilename(filename)), + getFileWeight(this.localDocConfig), true, + s"In grammar `${g.grammarName}` file `${filename}`: "++(if getToc(this.localDocConfig) then "{{< toc >}}" else ""), + this.docs) ++ soFar) else toSplitFiles(rest, grammarConf, forIndex ++ this.docs, soFar) + end + | nilGrammar() -> let skel::Boolean = (length(soFar) == 0 && length(grammarConf) == 0 && length(forIndex) == 0) in + formatFile("_index.md", + getGrammarTitle(grammarConf, "["++g.grammarName++"]"++(if skel then " (skel)" else "")), + getGrammarWeight(grammarConf) + (if skel then 10000 else 0), + false, s"Contents of `[${g.grammarName}]`: {{< toc-tree >}} \n\nDefined in this grammar:", forIndex) ++ soFar end + end; function formatFile [Pair] ::= fileName::String title::String weight::Integer @@ -93,8 +88,4 @@ ${implode("\n\n
\n\n", map((.body), stubDocs))} ))]; } -function lastPart -String ::= s::String -{ - return last(explode(":", s)); -} +fun lastPart String ::= s::String = last(explode(":", s)); diff --git a/grammars/silver/compiler/extension/doc/core/doclang/DclComment.sv b/grammars/silver/compiler/extension/doc/core/doclang/DclComment.sv index d59a05018..bc5db73ee 100644 --- a/grammars/silver/compiler/extension/doc/core/doclang/DclComment.sv +++ b/grammars/silver/compiler/extension/doc/core/doclang/DclComment.sv @@ -126,11 +126,8 @@ top::DclComment ::= InitialIgnore_t blocks::DclCommentBlocks FinalIgnore_t (!fromMaybe(false, fromMaybe(kwdValue(terminal(ConfigValueKeyword_t, "off")), lookup("hide", blocks.configArgs)).asBool)); } -function getBlocksNamed -[String] ::= l::[Pair] f::String -{ - return flatMap((\x::Pair -> if x.fst==f then [x.snd] else []), l); -} +fun getBlocksNamed [String] ::= l::[Pair] f::String = + flatMap((\x::Pair -> if x.fst==f then [x.snd] else []), l); function processConfigOptions Pair<[String] [DocConfigSetting]> ::= alreadyErrs::[String] args::[Pair] conf::[DocConfigSetting] @@ -178,15 +175,12 @@ Pair<[String] [DocConfigSetting]> ::= alreadyErrs::[String] args::[Pair checkParams(p_, b_) - | pn::p_, bn::b_ -> s"Param '${pn}' in wrong order in doc-comment" :: checkParams(p_, b_) - | _, _ -> [] - end; -} +fun checkParams [String] ::= p::[String] b::[String] = + case p, b of + | pn::p_, bn::b_ when pn==bn -> checkParams(p_, b_) + | pn::p_, bn::b_ -> s"Param '${pn}' in wrong order in doc-comment" :: checkParams(p_, b_) + | _, _ -> [] + end; abstract production errorDclComment top::DclComment ::= content::String error::ParseError diff --git a/grammars/silver/compiler/extension/easyterminal/Env.sv b/grammars/silver/compiler/extension/easyterminal/Env.sv index d40993fff..a88ab469c 100644 --- a/grammars/silver/compiler/extension/easyterminal/Env.sv +++ b/grammars/silver/compiler/extension/easyterminal/Env.sv @@ -2,11 +2,8 @@ grammar silver:compiler:extension:easyterminal; import silver:compiler:definition:env; -function getTerminalRegexDclAll -[TypeDclInfo] ::= search::String e::Env -{ - return searchEnv(search, e.terminalTree); -} +fun getTerminalRegexDclAll [TypeDclInfo] ::= search::String e::Env = + searchEnv(search, e.terminalTree); synthesized attribute terminalTree :: [EnvTree] occurs on Env; -- must be kept in sync with typeTree's type!! (whether its a [] or not) @@ -19,11 +16,8 @@ function filterAndConvertTermDcls end; } -function buildTerminalTree -EnvTree ::= eis::[EnvItem] -{ - return directBuildTree(foldr(filterAndConvertTermDcls,[],eis)); -} +fun buildTerminalTree EnvTree ::= eis::[EnvItem] = + directBuildTree(foldr(filterAndConvertTermDcls,[],eis)); aspect production emptyEnv top::Env ::= diff --git a/grammars/silver/compiler/extension/implicit_monads/Case.sv b/grammars/silver/compiler/extension/implicit_monads/Case.sv index 33661cc13..833bdb26c 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Case.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Case.sv @@ -134,23 +134,21 @@ top::Expr ::= 'case' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' } --find if any of the expressions are being matched as their inner type --if returns (true, ty), ty will be used to find the correct Fail() -function monadicallyUsedExpr +fun monadicallyUsedExpr Boolean ::= elst::[Expr] env::Env sub::Substitution f::BlockContext gn::String cg::EnvTree c::Decorated CmdArgs fe::FlowEnv em::Type - iR::Boolean oR::[Decorated Expr] -{ - return case elst of - | [] -> false - | e::etl -> - let etyp::Type = decorate e with {env=env; mDownSubst=sub; frame=f; grammarName=gn; - downSubst=sub; finalSubst=sub; - compiledGrammars=cg; config=c; alwaysDecorated = false; flowEnv=fe; - expectedMonad=em; isRoot=iR; originRules=oR;}.mtyperep - in - fst(monadsMatch(etyp, em, sub)) || monadicallyUsedExpr(etl, env, sub, f, gn, cg, c, fe, em, iR, oR) - end - end; -} + iR::Boolean oR::[Decorated Expr] = + case elst of + | [] -> false + | e::etl -> + let etyp::Type = decorate e with {env=env; mDownSubst=sub; frame=f; grammarName=gn; + downSubst=sub; finalSubst=sub; + compiledGrammars=cg; config=c; alwaysDecorated = false; flowEnv=fe; + expectedMonad=em; isRoot=iR; originRules=oR;}.mtyperep + in + fst(monadsMatch(etyp, em, sub)) || monadicallyUsedExpr(etl, env, sub, f, gn, cg, c, fe, em, iR, oR) + end + end; --make a list of the expression types, rewritten expressions and names for -- binding them as well as a new list of expressions for the forward to use --use a name from names when that is not empty; when empty, use a new name diff --git a/grammars/silver/compiler/extension/implicit_monads/DclInfo.sv b/grammars/silver/compiler/extension/implicit_monads/DclInfo.sv index 5fe9c5c53..0cebceb49 100644 --- a/grammars/silver/compiler/extension/implicit_monads/DclInfo.sv +++ b/grammars/silver/compiler/extension/implicit_monads/DclInfo.sv @@ -91,32 +91,20 @@ top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type -function restrictedSynDef -Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type -{ - return attrDef(defaultEnvItem(restrictedSynDcl(fn, bound, ty, sourceGrammar=sg, sourceLocation=sl))); -} +fun restrictedSynDef Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type = + attrDef(defaultEnvItem(restrictedSynDcl(fn, bound, ty, sourceGrammar=sg, sourceLocation=sl))); -function restrictedInhDef -Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type -{ - return attrDef(defaultEnvItem(restrictedInhDcl(fn, bound, ty, sourceGrammar=sg, sourceLocation=sl))); -} +fun restrictedInhDef Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type = + attrDef(defaultEnvItem(restrictedInhDcl(fn, bound, ty, sourceGrammar=sg, sourceLocation=sl))); -function implicitSynDef -Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type -{ - return attrDef(defaultEnvItem(implicitSynDcl(fn, bound, ty, sourceGrammar=sg, sourceLocation=sl))); -} +fun implicitSynDef Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type = + attrDef(defaultEnvItem(implicitSynDcl(fn, bound, ty, sourceGrammar=sg, sourceLocation=sl))); -function implicitInhDef -Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type -{ - return attrDef(defaultEnvItem(implicitInhDcl(fn, bound, ty, sourceGrammar=sg, sourceLocation=sl))); -} +fun implicitInhDef Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type = + attrDef(defaultEnvItem(implicitInhDcl(fn, bound, ty, sourceGrammar=sg, sourceLocation=sl))); diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index d6bfffb51..8c6bd815b 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -304,43 +304,34 @@ Expr ::= realtys::[Type] monadTysLocs::[Pair] monadAnns::[(Type, Q return lambdap(params, body); } --build the parameters for the lambda applied to all the original arguments plus the function -function buildMonadApplicationParams -LambdaRHS ::= realtys::[Type] currentLoc::Integer funType::Type -{ - return if null(realtys) - then lambdaRHSCons(lambdaRHSElemIdTy(name("f"), - '::', - typerepTypeExpr(funType)), - lambdaRHSNil()) - else lambdaRHSCons(lambdaRHSElemIdTy(name("a"++toString(currentLoc)), - '::', - typerepTypeExpr(dropDecorated(head(realtys)))), - buildMonadApplicationParams(tail(realtys), currentLoc+1, funType)); -} +fun buildMonadApplicationParams LambdaRHS ::= realtys::[Type] currentLoc::Integer funType::Type = + if null(realtys) + then lambdaRHSCons(lambdaRHSElemIdTy(name("f"), + '::', + typerepTypeExpr(funType)), + lambdaRHSNil()) + else lambdaRHSCons(lambdaRHSElemIdTy(name("a"++toString(currentLoc)), + '::', + typerepTypeExpr(dropDecorated(head(realtys)))), + buildMonadApplicationParams(tail(realtys), currentLoc+1, funType)); --build the arguments for the application inside all the binds --currentIndex is the numerical index of the argument for the name (a, like a3) -function buildFunArgs -AppExprs ::= currentIndex::Integer -{ - return if currentIndex == 0 - then emptyAppExprs() - else snocAppExprs(buildFunArgs(currentIndex - 1), ',', - presentAppExpr(baseExpr(qName("a"++toString(currentIndex))))); -} +fun buildFunArgs AppExprs ::= currentIndex::Integer = + if currentIndex == 0 + then emptyAppExprs() + else snocAppExprs(buildFunArgs(currentIndex - 1), ',', + presentAppExpr(baseExpr(qName("a"++toString(currentIndex))))); --build the annotation arguments for the application inside all the binds --annotations are the annotations given to the original call --currentIndex is the numerical index of the argument for the name (a, like a3) -function buildFunAnnArgs -AnnoAppExprs ::= annotations::[(Type, QName, Boolean)] currentIndex::Integer -{ - return case annotations of - | [] -> emptyAnnoAppExprs() - | (ty, q, _)::rest -> - snocAnnoAppExprs(buildFunAnnArgs(rest, currentIndex + 1), ',', - annoExpr(q, '=', - presentAppExpr(baseExpr(qName("a" ++ toString(currentIndex)))))) - end; -} +fun buildFunAnnArgs AnnoAppExprs ::= annotations::[(Type, QName, Boolean)] currentIndex::Integer = + case annotations of + | [] -> emptyAnnoAppExprs() + | (ty, q, _)::rest -> + snocAnnoAppExprs(buildFunAnnArgs(rest, currentIndex + 1), ',', + annoExpr(q, '=', + presentAppExpr(baseExpr(qName("a" ++ toString(currentIndex)))))) + end; --build the body of the lambda which includes all the binds function buildMonadApplicationBody Expr ::= monadTysLocs::[Pair] funargs::AppExprs annargs::AnnoAppExprs diff --git a/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv b/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv index 052e3d87f..7abe0675c 100644 --- a/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv +++ b/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv @@ -178,16 +178,13 @@ top::ProductionStmt ::= 'unrestricted' dl::DefLHS '.' attr::QNameAttrOccur '=' e --take a list of unallowed attributes and generate error messages for them -function buildExplicitAttrErrors -[Message] ::= l::[Decorated QNameAttrOccur] -{ - return case l of - | [] -> [] - | a::t -> - errFromOrigin(a, "Attributes accessed in restricted equations must be restricted; " ++ - a.name ++ " is not")::buildExplicitAttrErrors(t) - end; -} +fun buildExplicitAttrErrors [Message] ::= l::[Decorated QNameAttrOccur] = + case l of + | [] -> [] + | a::t -> + errFromOrigin(a, "Attributes accessed in restricted equations must be restricted; " ++ + a.name ++ " is not")::buildExplicitAttrErrors(t) + end; diff --git a/grammars/silver/compiler/extension/implicit_monads/Util.sv b/grammars/silver/compiler/extension/implicit_monads/Util.sv index 2c1d7ba27..9a3c38010 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Util.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Util.sv @@ -34,32 +34,23 @@ synthesized attribute mtyperep::Type; threaded attribute mDownSubst, mUpSubst::Substitution; -function isMonad -Boolean ::= ty::Type env::Env -{ - return case dropDecorated(ty) of - | appType(t, _) -> length(getInstanceDcl("silver:core:Monad", t, env)) > 0 - | t -> length(getInstanceDcl("silver:core:Monad", t, env)) > 0 - end; -} +fun isMonad Boolean ::= ty::Type env::Env = + case dropDecorated(ty) of + | appType(t, _) -> length(getInstanceDcl("silver:core:Monad", t, env)) > 0 + | t -> length(getInstanceDcl("silver:core:Monad", t, env)) > 0 + end; -function isMonadPlus -Boolean ::= ty::Type env::Env -{ - return case dropDecorated(ty) of - | appType(t, _) -> length(getInstanceDcl("silver:core:MonadPlus", t, env)) > 0 - | t -> length(getInstanceDcl("silver:core:MonadPlus", t, env)) > 0 - end; -} +fun isMonadPlus Boolean ::= ty::Type env::Env = + case dropDecorated(ty) of + | appType(t, _) -> length(getInstanceDcl("silver:core:MonadPlus", t, env)) > 0 + | t -> length(getInstanceDcl("silver:core:MonadPlus", t, env)) > 0 + end; -function isMonadFail -Boolean ::= ty::Type env::Env -{ - return case dropDecorated(ty) of - | appType(t, _) -> length(getInstanceDcl("silver:core:MonadFail", t, env)) > 0 - | t -> length(getInstanceDcl("silver:core:MonadFail", t, env)) > 0 - end; -} +fun isMonadFail Boolean ::= ty::Type env::Env = + case dropDecorated(ty) of + | appType(t, _) -> length(getInstanceDcl("silver:core:MonadFail", t, env)) > 0 + | t -> length(getInstanceDcl("silver:core:MonadFail", t, env)) > 0 + end; function dropDecorated @@ -71,16 +62,12 @@ Type ::= ty::Type {-This checks two types are the same monad, (assuming they are monads) though not necessarily the same monadic type (see discussion above)-} -function monadsMatch -Pair ::= ty1::Type ty2::Type subst::Substitution -{ - return - case dropDecorated(ty1), dropDecorated(ty2) of - | appType(c1, _), appType(c2, _) -> - tyMatch(c1, c2, subst) - | _, _ -> (false, subst) - end; -} +fun monadsMatch Pair ::= ty1::Type ty2::Type subst::Substitution = + case dropDecorated(ty1), dropDecorated(ty2) of + | appType(c1, _), appType(c2, _) -> + tyMatch(c1, c2, subst) + | _, _ -> (false, subst) + end; {-This is the easiest way to get case_any translation working. We @@ -90,15 +77,12 @@ Pair ::= ty1::Type ty2::Type subst::Substitution We also need to use this because we occasionally need to use new to drop the decoration from the type of things we're passing into binds.-} -function acceptableMonadFunction -Boolean ::= f::Decorated Expr -{ - return case f of - | functionReference(qNameId(name)) -> - name.name == "silver:core:alt" - | _ -> false - end; -} +fun acceptableMonadFunction Boolean ::= f::Decorated Expr = + case f of + | functionReference(qNameId(name)) -> + name.name == "silver:core:alt" + | _ -> false + end; function tyMatch @@ -125,43 +109,28 @@ Type ::= mty::Type {-take the monad of mty and replace its inner type with the given type to make a new monadic type-} -function monadOfType -Type ::= mty::Type newInner::Type -{ - return case dropDecorated(mty) of - | appType(c, _) -> appType(c, newInner) - | _ -> error("Tried to take a monad out of a non-monadic type (" ++ prettyType(mty) ++ ") to apply") - end; -} +fun monadOfType Type ::= mty::Type newInner::Type = + case dropDecorated(mty) of + | appType(c, _) -> appType(c, newInner) + | _ -> error("Tried to take a monad out of a non-monadic type (" ++ prettyType(mty) ++ ") to apply") + end; --Print out the monad nicely rather than filled in with some other type -function monadToString -String ::= ty::Type -{ - return - case dropDecorated(ty) of - | appType(c, _) -> - --We use nonterminalType to get it to show just an underscore - --e.g. this gives us Maybe<_>, Either - prettyType(appType(c, nonterminalType("_", [], false, false))) - | _ -> error("Tried to get monadToString for a non-monadic type (" ++ prettyType(ty) ++ ")") - end; -} +fun monadToString String ::= ty::Type = + case dropDecorated(ty) of + | appType(c, _) -> + --We use nonterminalType to get it to show just an underscore + --e.g. this gives us Maybe<_>, Either + prettyType(appType(c, nonterminalType("_", [], false, false))) + | _ -> error("Tried to get monadToString for a non-monadic type (" ++ prettyType(ty) ++ ")") + end; {-find the name of the bind/return for a given monad to use to build the rewritten term-} -function monadBind -Expr ::= -{ - return baseExpr(qNameId(name("silver:core:bind"))); -} -function monadReturn -Expr ::= -{ - return baseExpr(qNameId(name("silver:core:pure"))); -} +fun monadBind Expr ::= = baseExpr(qNameId(name("silver:core:bind"))); +fun monadReturn Expr ::= = baseExpr(qNameId(name("silver:core:pure"))); --We want to produce a value, not a function, so we apply it to an argument function monadFail @@ -176,16 +145,8 @@ Expr ::= } -function monadPlus -Expr ::= -{ - return baseExpr(qNameId(name("silver:core:alt"))); -} -function monadZero -Expr ::= -{ - return baseExpr(qNameId(name("silver:core:empty"))); -} +fun monadPlus Expr ::= = baseExpr(qNameId(name("silver:core:alt"))); +fun monadZero Expr ::= = baseExpr(qNameId(name("silver:core:empty"))); @@ -197,38 +158,28 @@ Expr ::= These can also be easier to read because we don't have all the "$Expr"s and "Silver_Expr"s around. -} -function buildApplication -Expr ::= fun::Expr args::[Expr] -{ - return applicationExpr(fun, '(', buildApplicationReverseArgs(reverse(args)), ')'); -} +fun buildApplication Expr ::= fun::Expr args::[Expr] = + applicationExpr(fun, '(', buildApplicationReverseArgs(reverse(args)), ')'); --because the AST is set up as a snoc list, we build the arguments in reverse --e.g. [a,b,c] gives application arguments (c, b, a) -function buildApplicationReverseArgs -AppExprs ::= args::[Expr] -{ - return case args of - | [] -> emptyAppExprs() - | hd::tl -> - snocAppExprs(buildApplicationReverseArgs(tl), ',', - presentAppExpr(hd)) - end; -} - - - -function buildLambda -Expr ::= n::String ty::Type body::Expr -{ - -- \ n::ty -> body - return lambdap( - lambdaRHSCons(lambdaRHSElemIdTy(name(n), - '::', - typerepTypeExpr(ty)), - lambdaRHSNil()), - body); -} +fun buildApplicationReverseArgs AppExprs ::= args::[Expr] = + case args of + | [] -> emptyAppExprs() + | hd::tl -> + snocAppExprs(buildApplicationReverseArgs(tl), ',', + presentAppExpr(hd)) + end; + + + +fun buildLambda Expr ::= n::String ty::Type body::Expr = + lambdap( + lambdaRHSCons(lambdaRHSElemIdTy(name(n), + '::', + typerepTypeExpr(ty)), + lambdaRHSNil()), + body); function buildMultiLambda diff --git a/grammars/silver/compiler/extension/patternmatching/Case.sv b/grammars/silver/compiler/extension/patternmatching/Case.sv index 9fb2ecd9d..202ec6077 100644 --- a/grammars/silver/compiler/extension/patternmatching/Case.sv +++ b/grammars/silver/compiler/extension/patternmatching/Case.sv @@ -183,22 +183,20 @@ ts:Set ::= frame::BlockContext x::a --Get the initial segment of the match rules which all have the same --pattern type (constructor or var) and the rest of the rules -function initialSegmentPatternType -Pair<[AbstractMatchRule] [AbstractMatchRule]> ::= lst::[AbstractMatchRule] -{ - return case lst of - --this probably shouldn't be called with an empty list, but catch it anyway - | [] -> ([], []) - | [mr] -> ([mr], []) - | mr1::mr2::rest -> - if mr1.isVarMatchRule == mr2.isVarMatchRule - then --both have the same type of pattern - let sub::Pair<[AbstractMatchRule] [AbstractMatchRule]> = initialSegmentPatternType(mr2::rest) - in (mr1::sub.fst, sub.snd) end - else --the first has a different type of pattern than the second - ([mr1], mr2::rest) - end; -} +fun initialSegmentPatternType +Pair<[AbstractMatchRule] [AbstractMatchRule]> ::= lst::[AbstractMatchRule] = + case lst of + --this probably shouldn't be called with an empty list, but catch it anyway + | [] -> ([], []) + | [mr] -> ([mr], []) + | mr1::mr2::rest -> + if mr1.isVarMatchRule == mr2.isVarMatchRule + then --both have the same type of pattern + let sub::Pair<[AbstractMatchRule] [AbstractMatchRule]> = initialSegmentPatternType(mr2::rest) + in (mr1::sub.fst, sub.snd) end + else --the first has a different type of pattern than the second + ([mr1], mr2::rest) + end; {- @@ -505,18 +503,15 @@ function checkOverlappingPatterns list into segments of only constructor or variable patterns in order, then checking each segment as its own match. -} -function checkOverlappingMixedCaseMatches -[Message] ::= es::[Expr] ml::[AbstractMatchRule] -{ - return if null(ml) - then [] - else let segments::Pair<[AbstractMatchRule] [AbstractMatchRule]> = - initialSegmentPatternType(ml) - in - checkOverlappingMixedCaseMatches(es, segments.snd) ++ - checkOverlappingPatterns(es, segments.fst) - end; -} +fun checkOverlappingMixedCaseMatches [Message] ::= es::[Expr] ml::[AbstractMatchRule] = + if null(ml) + then [] + else let segments::Pair<[AbstractMatchRule] [AbstractMatchRule]> = + initialSegmentPatternType(ml) + in + checkOverlappingMixedCaseMatches(es, segments.snd) ++ + checkOverlappingPatterns(es, segments.fst) + end; {-- - Expand the head of a match rule as if matched, and check for @@ -629,11 +624,7 @@ Maybe<[Pattern]> ::= lst::[[Decorated Pattern]] env::Env for expanding a variable pattern list to be the same length as an expanded list from a head pattern with subpatterns. -} -function generateWildcards -[Pattern] ::= n::Integer -{ - return repeat(wildcPattern('_'), n); -} +fun generateWildcards [Pattern] ::= n::Integer = repeat(wildcPattern('_'), n); {- Sometimes we need to decorate a list of wildcard patterns for the @@ -641,46 +632,36 @@ function generateWildcards replace a variable. We should never need to access anything on these, so passing in bottom values for the attributes is fine. -} -function decoratePattList -[Decorated Pattern] ::= lst::[Pattern] -{ - return map(\ p::Pattern -> decorate p with { +fun decoratePattList [Decorated Pattern] ::= lst::[Pattern] = + map(\ p::Pattern -> decorate p with { config = error("not needed"); frame = error("not needed"); env = error("not needed"); patternVarEnv = error("not needed"); }, lst); -} --Group sets of patterns by the first pattern in each set --The core groupBy function doesn't work because it groups contiguous -- sets, and the patterns might not be contiguous. -function groupAllPattsByHead -[[[Decorated Pattern]]] ::= pattLists::[[Decorated Pattern]] -{ - return - if null(pattLists) - then [] - else case groupAllPattsByHeadHelp(head(pattLists), tail(pattLists)) of - | (thisGroup, others) -> - (head(pattLists)::thisGroup)::groupAllPattsByHead(others) - end; -} -function groupAllPattsByHeadHelp +fun groupAllPattsByHead [[[Decorated Pattern]]] ::= pattLists::[[Decorated Pattern]] = + if null(pattLists) + then [] + else case groupAllPattsByHeadHelp(head(pattLists), tail(pattLists)) of + | (thisGroup, others) -> + (head(pattLists)::thisGroup)::groupAllPattsByHead(others) + end; +fun groupAllPattsByHeadHelp Pair<[[Decorated Pattern]] [[Decorated Pattern]]> ::= - item::[Decorated Pattern] rest::[[Decorated Pattern]] -{ - return - case rest of - | [] -> ([], []) - | h::t -> case groupAllPattsByHeadHelp(item, t) of - | (grp, rst) -> - if head(item).patternSortKey == head(h).patternSortKey - then (h::grp, rst) - else (grp, h::rst) - end - end; -} + item::[Decorated Pattern] rest::[[Decorated Pattern]] = + case rest of + | [] -> ([], []) + | h::t -> case groupAllPattsByHeadHelp(item, t) of + | (grp, rst) -> + if head(item).patternSortKey == head(h).patternSortKey + then (h::grp, rst) + else (grp, h::rst) + end + end; --This checks the primitive patterns all have the same type and generates an -- example of a primitive value which is not covered by the given patterns @@ -713,27 +694,18 @@ Maybe ::= patts::[Decorated Pattern] end; } -function generateMissingIntegerPattern -Pattern ::= lst::[Integer] initial::Integer -{ - return if containsBy(\ a::Integer b::Integer -> a == b, initial, lst) - then generateMissingIntegerPattern(lst, initial + 1) - else intPattern(terminal(Int_t, toString(initial), bogusLoc())); -} -function generateMissingFloatPattern -Pattern ::= lst::[Float] initial::Float -{ - return if containsBy(\ a::Float b::Float -> a == b, initial, lst) - then generateMissingFloatPattern(lst, initial + 1.0) - else fltPattern(terminal(Float_t, toString(initial), bogusLoc())); -} -function generateMissingStringPattern -Pattern ::= lst::[String] initial::String -{ - return if containsBy(\ a::String b::String -> a == b, initial, lst) - then generateMissingStringPattern(lst, initial ++ "*") - else strPattern(terminal(String_t, "\"" ++ initial ++ "\"", bogusLoc())); -} +fun generateMissingIntegerPattern Pattern ::= lst::[Integer] initial::Integer = + if containsBy(\ a::Integer b::Integer -> a == b, initial, lst) + then generateMissingIntegerPattern(lst, initial + 1) + else intPattern(terminal(Int_t, toString(initial), bogusLoc())); +fun generateMissingFloatPattern Pattern ::= lst::[Float] initial::Float = + if containsBy(\ a::Float b::Float -> a == b, initial, lst) + then generateMissingFloatPattern(lst, initial + 1.0) + else fltPattern(terminal(Float_t, toString(initial), bogusLoc())); +fun generateMissingStringPattern Pattern ::= lst::[String] initial::String = + if containsBy(\ a::String b::String -> a == b, initial, lst) + then generateMissingStringPattern(lst, initial ++ "*") + else strPattern(terminal(String_t, "\"" ++ initial ++ "\"", bogusLoc())); --First pattern in each set in conPatts is a primitive --The first match can only be completed by a variable @@ -1218,25 +1190,15 @@ Name ::= p::Decorated Pattern end; return name(n); } -function convStringsToVarBinders -VarBinders ::= s::[Name] -{ - return if null(s) then nilVarBinder() - else if null(tail(s)) then oneVarBinder(varVarBinder(head(s))) - else consVarBinder(varVarBinder(head(s)), ',', convStringsToVarBinders(tail(s))); -} -function exprFromName -Expr ::= n::Name -{ - return baseExpr(qNameId(n)); -} +fun convStringsToVarBinders VarBinders ::= s::[Name] = + if null(s) then nilVarBinder() + else if null(tail(s)) then oneVarBinder(varVarBinder(head(s))) + else consVarBinder(varVarBinder(head(s)), ',', convStringsToVarBinders(tail(s))); +fun exprFromName Expr ::= n::Name = baseExpr(qNameId(n)); -function foldPrimPatterns -PrimPatterns ::= l::[PrimPattern] -{ - return if null(tail(l)) then onePattern(head(l)) - else consPattern(head(l), '|', foldPrimPatterns(tail(l))); -} +fun foldPrimPatterns PrimPatterns ::= l::[PrimPattern] = + if null(tail(l)) then onePattern(head(l)) + else consPattern(head(l), '|', foldPrimPatterns(tail(l))); {-- - Remove the first pattern from the rule, and put a let binding of it into @@ -1283,14 +1245,11 @@ AbstractMatchRule ::= absRule::AbstractMatchRule end; } -function makeLet -Expr ::= s::String t::Type e::Expr o::Expr -{ - return letp( +fun makeLet Expr ::= s::String t::Type e::Expr o::Expr = + letp( assignExpr( name(s), '::', typerepTypeExpr(t), '=', e), o); -} instance Eq AbstractMatchRule { eq = \ a::AbstractMatchRule b::AbstractMatchRule -> @@ -1306,39 +1265,31 @@ instance Ord AbstractMatchRule { - - i.e. [cons, nil, cons] becomes [[cons, cons], [nil]] (where 'cons' is the key of the head pattern) -} -function groupMRules -[[AbstractMatchRule]] ::= l::[AbstractMatchRule] -{ - return group(sort(l)); -} +fun groupMRules [[AbstractMatchRule]] ::= l::[AbstractMatchRule] = group(sort(l)); {-- - Given a list of match rules, which are presumed to match empty - patterns (this is not checked), turn them into nested - conditionals. -} -function buildMatchWhenConditionals -Expr ::= ml::[AbstractMatchRule] failExpr::Expr -{ - return - case ml of - | matchRule(_, just((c, nothing())), e) :: tl -> - Silver_Expr { - if $Expr{c} - then $Expr{e} - else $Expr{buildMatchWhenConditionals(tl, failExpr)} - } - | matchRule(_, just((c, just(p))), e) :: tl -> - Silver_Expr { - case $Expr{c} of - | $Pattern{p} -> $Expr{e} - | _ -> $Expr{buildMatchWhenConditionals(tl, failExpr)} - end - } - | matchRule(_, nothing(), e) :: tl -> e - | [] -> failExpr - end; -} +fun buildMatchWhenConditionals Expr ::= ml::[AbstractMatchRule] failExpr::Expr = + case ml of + | matchRule(_, just((c, nothing())), e) :: tl -> + Silver_Expr { + if $Expr{c} + then $Expr{e} + else $Expr{buildMatchWhenConditionals(tl, failExpr)} + } + | matchRule(_, just((c, just(p))), e) :: tl -> + Silver_Expr { + case $Expr{c} of + | $Pattern{p} -> $Expr{e} + | _ -> $Expr{buildMatchWhenConditionals(tl, failExpr)} + end + } + | matchRule(_, nothing(), e) :: tl -> e + | [] -> failExpr + end; {-- - Check whether there are patterns that overlap in a list of match @@ -1350,17 +1301,13 @@ Expr ::= ml::[AbstractMatchRule] failExpr::Expr - analysis of the conditions on the patterns to determine whether - they are actually useless. We do not do that. -} -function areUselessPatterns -Boolean ::= ml::[AbstractMatchRule] -{ - return - case ml of - | matchRule(_, just(_), _) :: tl -> - areUselessPatterns(tl) - | matchRule(_, nothing(), _) :: _ :: _ -> true - | matchRule(_, nothing(), _) :: [] -> false - | [] -> false - end; -} +fun areUselessPatterns Boolean ::= ml::[AbstractMatchRule] = + case ml of + | matchRule(_, just(_), _) :: tl -> + areUselessPatterns(tl) + | matchRule(_, nothing(), _) :: _ :: _ -> true + | matchRule(_, nothing(), _) :: [] -> false + | [] -> false + end; diff --git a/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv b/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv index 0ead2fc0d..866c6c741 100644 --- a/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv +++ b/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv @@ -396,13 +396,10 @@ top::NamedPattern ::= qn::QName '=' p::Pattern } --helper function for building patternLists from lists of patterns -function buildPatternList -PatternList ::= plst::[Pattern] loc::Location -{ - return case plst of - | [] -> patternList_nil() - | h::t -> - patternList_more(h, ',', buildPatternList(t, loc)) - end; -} +fun buildPatternList PatternList ::= plst::[Pattern] loc::Location = + case plst of + | [] -> patternList_nil() + | h::t -> + patternList_more(h, ',', buildPatternList(t, loc)) + end; diff --git a/grammars/silver/compiler/extension/strategyattr/StrategyExpr.sv b/grammars/silver/compiler/extension/strategyattr/StrategyExpr.sv index c8b8c2e7e..01403fe65 100644 --- a/grammars/silver/compiler/extension/strategyattr/StrategyExpr.sv +++ b/grammars/silver/compiler/extension/strategyattr/StrategyExpr.sv @@ -158,22 +158,16 @@ propagate genericStep, ntStep, prodStep, genericSimplify, ntSimplify, optimize o propagate elimInfeasibleMRules on MRuleList; -- Convert an expression of type a to Maybe
-function asPartial -Expr ::= e::Expr -{ return Silver_Expr { silver:core:just($Expr{e}) }; } +fun asPartial Expr ::= e::Expr = Silver_Expr { silver:core:just($Expr{e}) }; -- Convert an expression of type Maybe to a -function asTotal -Expr ::= t::Type e::Expr -{ - return - Silver_Expr { - let res::$TypeExpr{typerepTypeExpr(t)} = - silver:core:error("Total result demanded when partial strategy failed") - in silver:core:fromMaybe(res, $Expr{e}) - end - }; -} +fun asTotal Expr ::= t::Type e::Expr = + Silver_Expr { + let res::$TypeExpr{typerepTypeExpr(t)} = + silver:core:error("Total result demanded when partial strategy failed") + in silver:core:fromMaybe(res, $Expr{e}) + end + }; aspect default production top::StrategyExpr ::= @@ -1035,13 +1029,9 @@ Boolean ::= env::Env attrName::String end; } -function attrMatchesFrame -Boolean ::= env::Env attrName::String attrFor::Type -{ - return - decorate qNameAttrOccur(qName(attrName)) - with { env = env; attrFor = attrFor; }.matchesFrame; -} +fun attrMatchesFrame Boolean ::= env::Env attrName::String attrFor::Type = + decorate qNameAttrOccur(qName(attrName)) + with { env = env; attrFor = attrFor; }.matchesFrame; function attrMatchesChild Boolean ::= env::Env attrName::String frame::BlockContext diff --git a/grammars/silver/compiler/extension/testing/Helper.sv b/grammars/silver/compiler/extension/testing/Helper.sv index a68e3f6c4..339adf100 100644 --- a/grammars/silver/compiler/extension/testing/Helper.sv +++ b/grammars/silver/compiler/extension/testing/Helper.sv @@ -13,32 +13,16 @@ import silver:compiler:modification:list; -- or otherwise don't belong here! -- Create an Expr from a String. -function mkNameExpr -Expr ::= name::String -{ - return baseExpr(qName(name)); -} +fun mkNameExpr Expr ::= name::String = baseExpr(qName(name)); -- fold a list of expressions(Expr) into a single "++"-separated Expr -function foldStringExprs -Expr ::= es::[Expr] -{ - return if null(es) - then stringConst(terminal(String_t, "\"\"")) - else plusPlus(head(es), '++', foldStringExprs(tail(es))); -} +fun foldStringExprs Expr ::= es::[Expr] = + if null(es) + then stringConst(terminal(String_t, "\"\"")) + else plusPlus(head(es), '++', foldStringExprs(tail(es))); -- Create an Expr that is a string constant from a string. -function strCnst -Expr ::= s::String -{ - return stringConst(terminal(String_t, "\"" ++ escapeString(s) ++ "\"")); -} +fun strCnst Expr ::= s::String = stringConst(terminal(String_t, "\"" ++ escapeString(s) ++ "\"")); -- Create an attribute reference from two names. as in "n.a" -function attrAcc -Expr ::= n::String a::String -{ - return - access(mkNameExpr(n), '.', qNameAttrOccur(qName(a))); -} +fun attrAcc Expr ::= n::String a::String = access(mkNameExpr(n), '.', qNameAttrOccur(qName(a))); diff --git a/grammars/silver/compiler/extension/testing/WrongCode.sv b/grammars/silver/compiler/extension/testing/WrongCode.sv index 14b8972c4..066aeb50e 100644 --- a/grammars/silver/compiler/extension/testing/WrongCode.sv +++ b/grammars/silver/compiler/extension/testing/WrongCode.sv @@ -10,11 +10,8 @@ terminal WarnCode_kwd 'warnCode' lexer classes {KEYWORD}; terminal NoWarnCode_kwd 'noWarnCode' lexer classes {KEYWORD}; terminal WrongFlowCode_kwd 'wrongFlowCode' lexer classes {KEYWORD}; -function containsMessage -Boolean ::= text::String severity::Integer msgs::[Message] -{ - return any(map((\x::Message -> x.severity==severity && indexOf(text, x.output)!=-1), msgs)); -} +fun containsMessage Boolean ::= text::String severity::Integer msgs::[Message] = + any(map((\x::Message -> x.severity==severity && indexOf(text, x.output)!=-1), msgs)); concrete production wrongDecl top::AGDcl ::= 'wrongCode' s::String_t '{' ags::AGDcls '}' diff --git a/grammars/silver/compiler/extension/treegen/Arbitrary.sv b/grammars/silver/compiler/extension/treegen/Arbitrary.sv index 1d667bc6a..7909d2e51 100644 --- a/grammars/silver/compiler/extension/treegen/Arbitrary.sv +++ b/grammars/silver/compiler/extension/treegen/Arbitrary.sv @@ -186,14 +186,11 @@ Boolean ::= v::ValueDclInfo } -- splits where operator becomes false in list -function takeWhile2 -[a] ::= f::(Boolean ::= a a) l::[a] -{ - return if null(l) then [] +fun takeWhile2 [a] ::= f::(Boolean ::= a a) l::[a] = + if null(l) then [] else if null(tail(l)) then l else if f(head(l), head(tail(l))) then head(l) :: takeWhile2(f, tail(l)) else [head(l)]; -} -- local genExpr::(RandomGen ::= Integer) = \ depth::Integer -> ...; function genNtLocalDecl diff --git a/grammars/silver/compiler/langserver/ReferenceLocations.sv b/grammars/silver/compiler/langserver/ReferenceLocations.sv index 49db2cbba..d3ca6d2f0 100644 --- a/grammars/silver/compiler/langserver/ReferenceLocations.sv +++ b/grammars/silver/compiler/langserver/ReferenceLocations.sv @@ -245,15 +245,14 @@ top::Compilation ::= g::Grammars r::Grammars _ _ top.allAttributeRefs = buildAllRefs((.attributeRefLocs), g.grammarList); } -function buildFileRefs +fun buildFileRefs annotation sourceLocation occurs on a, annotation sourceGrammar occurs on a => map:Map ::= accessor::([(Location, a)] ::= Decorated RootSpec) accessList::([EnvItem] ::= Def) - rs::[Decorated RootSpec] -{ - return directBuildTree(flatMap(\ r::Decorated RootSpec -> + rs::[Decorated RootSpec] = + directBuildTree(flatMap(\ r::Decorated RootSpec -> map(\ item::(Location, a) -> (r.grammarSource ++ item.1.filename, item.1, head(map:lookup(item.2.sourceGrammar, r.compiledGrammars)), item.2), accessor(r)) ++ @@ -265,7 +264,6 @@ map:Map ::= accessList(def)), r.defs), rs)); -} -- Create a map from a reference's unique id to its path & location function buildAllRefs @@ -327,61 +325,45 @@ InterfaceItems ::= r::Decorated RootSpec ]; } -function lookupPos -[a] ::= line::Integer col::Integer items::[(Location, a)] -{ - return map(snd, filter( +fun lookupPos [a] ::= line::Integer col::Integer items::[(Location, a)] = + map(snd, filter( \ item::(Location, a) -> item.1.line <= line && item.1.endLine >= line && item.1.column <= col && item.1.endColumn >= col, items)); -} -function updateLocPath -Location ::= p::String l::Location -{ - return loc(p, l.line, l.column, l.endLine, l.endColumn, l.index, l.endIndex); -} +fun updateLocPath Location ::= p::String l::Location = + loc(p, l.line, l.column, l.endLine, l.endColumn, l.index, l.endIndex); -function lookupDeclLocation +fun lookupDeclLocation annotation sourceGrammar occurs on a, annotation sourceLocation occurs on a => -[Location] ::= fileName::String line::Integer col::Integer decls::map:Map -{ - return map(\ item::(Decorated RootSpec, a) -> +[Location] ::= fileName::String line::Integer col::Integer decls::map:Map = + map(\ item::(Decorated RootSpec, a) -> updateLocPath(item.1.grammarSource ++ item.2.sourceLocation.filename, item.2.sourceLocation), lookupPos(line, col, map:lookup(fileName, decls))); -} -function findDeclLocation -[Location] ::= fileName::String line::Integer col::Integer c::Decorated Compilation -{ - return - lookupDeclLocation(fileName, line, col, c.valueFileRefLocs) ++ - lookupDeclLocation(fileName, line, col, c.typeFileRefLocs) ++ - lookupDeclLocation(fileName, line, col, c.attributeFileRefLocs); -} +fun findDeclLocation +[Location] ::= fileName::String line::Integer col::Integer c::Decorated Compilation = + lookupDeclLocation(fileName, line, col, c.valueFileRefLocs) ++ + lookupDeclLocation(fileName, line, col, c.typeFileRefLocs) ++ + lookupDeclLocation(fileName, line, col, c.attributeFileRefLocs); -- Looks up all references to symbol at the given location -- Returns a list of all reference locations -- Input is filename, line & col number, & decl map to resolve the symbol -- Uses refs map to lookup the reference paths & locations from the symbol unique id -function lookupReferenceLocations +fun lookupReferenceLocations annotation sourceGrammar occurs on a, annotation sourceLocation occurs on a, attribute fullName {} occurs on a => -[Location] ::= fileName::String line::Integer col::Integer decls::map:Map refs::map:Map -{ - return flatMap(\ item::(Decorated RootSpec, a) -> +[Location] ::= fileName::String line::Integer col::Integer decls::map:Map refs::map:Map = + flatMap(\ item::(Decorated RootSpec, a) -> map(\ loc::(String, Location) -> updateLocPath(loc.1, loc.2), map:lookup(makeRefId(item.2), refs)), lookupPos(line, col, map:lookup(fileName, decls))); -} -function findReferences -[Location] ::= fileName::String line::Integer col::Integer c::Decorated Compilation -{ - return - lookupReferenceLocations(fileName, line, col, c.valueFileRefLocs, c.allValueRefs) ++ - lookupReferenceLocations(fileName, line, col, c.typeFileRefLocs, c.allTypeRefs) ++ - lookupReferenceLocations(fileName, line, col, c.attributeFileRefLocs, c.allAttributeRefs); -} +fun findReferences +[Location] ::= fileName::String line::Integer col::Integer c::Decorated Compilation = + lookupReferenceLocations(fileName, line, col, c.valueFileRefLocs, c.allValueRefs) ++ + lookupReferenceLocations(fileName, line, col, c.typeFileRefLocs, c.allTypeRefs) ++ + lookupReferenceLocations(fileName, line, col, c.attributeFileRefLocs, c.allAttributeRefs); diff --git a/grammars/silver/compiler/metatranslation/Translation.sv b/grammars/silver/compiler/metatranslation/Translation.sv index 7dfff33d4..06f635341 100644 --- a/grammars/silver/compiler/metatranslation/Translation.sv +++ b/grammars/silver/compiler/metatranslation/Translation.sv @@ -333,14 +333,10 @@ top::NamedAST ::= n::String v::AST -- the functions below are directly referenced in reflection code in silver:compiler:extensions:silverconstruction -- so make sure you grep for that if you change/move them. -function makeName -Name ::= n::String loc::Location -{ - return - if isUpper(head(explode("", n))) - then nameIdUpper(terminal(IdUpper_t, n, loc)) - else nameIdLower(terminal(IdLower_t, n, loc)); -} +fun makeName Name ::= n::String loc::Location = + if isUpper(head(explode("", n))) + then nameIdUpper(terminal(IdUpper_t, n, loc)) + else nameIdLower(terminal(IdLower_t, n, loc)); function makeQName QName ::= n::String loc::Location diff --git a/grammars/silver/compiler/modification/collection/DclInfo.sv b/grammars/silver/compiler/modification/collection/DclInfo.sv index 9b81d09b8..c50a793ab 100644 --- a/grammars/silver/compiler/modification/collection/DclInfo.sv +++ b/grammars/silver/compiler/modification/collection/DclInfo.sv @@ -118,19 +118,10 @@ global collectionAttrDefError::(ProductionStmt ::= Decorated! DefLHS Decorated! -- Defs -function synColDef -Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type o::Operation -{ - return attrDef(defaultEnvItem(synCollectionDcl(fn,bound,ty,o,sourceGrammar=sg,sourceLocation=sl))); -} -function inhColDef -Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type o::Operation -{ - return attrDef(defaultEnvItem(inhCollectionDcl(fn,bound,ty,o,sourceGrammar=sg,sourceLocation=sl))); -} -function localColDef -Def ::= sg::String sl::Location fn::String ty::Type o::Operation -{ - return valueDef(defaultEnvItem(localCollectionDcl(fn,ty,o,sourceGrammar=sg,sourceLocation=sl))); -} +fun synColDef Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type o::Operation = + attrDef(defaultEnvItem(synCollectionDcl(fn,bound,ty,o,sourceGrammar=sg,sourceLocation=sl))); +fun inhColDef Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type o::Operation = + attrDef(defaultEnvItem(inhCollectionDcl(fn,bound,ty,o,sourceGrammar=sg,sourceLocation=sl))); +fun localColDef Def ::= sg::String sl::Location fn::String ty::Type o::Operation = + valueDef(defaultEnvItem(localCollectionDcl(fn,ty,o,sourceGrammar=sg,sourceLocation=sl))); diff --git a/grammars/silver/compiler/modification/collection/java/Collection.sv b/grammars/silver/compiler/modification/collection/java/Collection.sv index a4c1a2e01..f1370025c 100644 --- a/grammars/silver/compiler/modification/collection/java/Collection.sv +++ b/grammars/silver/compiler/modification/collection/java/Collection.sv @@ -250,9 +250,5 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur } -function makeCAClassName -String ::= s::String -{ - return substituteLast(".", ".CA", makeName(s)); -} +fun makeCAClassName String ::= s::String = substituteLast(".", ".CA", makeName(s)); diff --git a/grammars/silver/compiler/modification/copper/BuildProcess.sv b/grammars/silver/compiler/modification/copper/BuildProcess.sv index 7e18b3f12..b906033ee 100644 --- a/grammars/silver/compiler/modification/copper/BuildProcess.sv +++ b/grammars/silver/compiler/modification/copper/BuildProcess.sv @@ -66,12 +66,9 @@ Either ::= args::[String] -- Skips parser specs from SILVER_HOST_GEN -- The way that feature works, they shouldn't need regeneration. -function obtainParserSpecs -[ParserSpec] ::= g::Decorated RootSpec benv::BuildEnv -{ - return if g.generateLocation != benv.silverGen then [] - else g.parserSpecs; -} +fun obtainParserSpecs [ParserSpec] ::= g::Decorated RootSpec benv::BuildEnv = + if g.generateLocation != benv.silverGen then [] + else g.parserSpecs; aspect production compilation top::Compilation ::= g::Grammars _ _ benv::BuildEnv diff --git a/grammars/silver/compiler/modification/copper/Env.sv b/grammars/silver/compiler/modification/copper/Env.sv index 0dfbdf088..8ae2c6001 100644 --- a/grammars/silver/compiler/modification/copper/Env.sv +++ b/grammars/silver/compiler/modification/copper/Env.sv @@ -31,41 +31,23 @@ top::Def ::= d::EnvItem top.valueList = [d]; } -function parserAttrDef -Def ::= sg::String sl::Location fn::String ty::Type -{ - return valueDef(defaultEnvItem(parserAttrDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); -} +fun parserAttrDef Def ::= sg::String sl::Location fn::String ty::Type = + valueDef(defaultEnvItem(parserAttrDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); -function pluckTermDef -Def ::= sg::String sl::Location fn::String -{ - return valueDef(defaultEnvItem(pluckTermDcl(fn,sourceGrammar=sg,sourceLocation=sl))); -} +fun pluckTermDef Def ::= sg::String sl::Location fn::String = + valueDef(defaultEnvItem(pluckTermDcl(fn,sourceGrammar=sg,sourceLocation=sl))); -function lexerClassDef -Def ::= sg::String sl::Location fn::String sc::[String] -{ - return lxrClsDef(defaultEnvItem(lexerClassDcl(fn,sc,sourceGrammar=sg,sourceLocation=sl))); -} +fun lexerClassDef Def ::= sg::String sl::Location fn::String sc::[String] = + lxrClsDef(defaultEnvItem(lexerClassDcl(fn,sc,sourceGrammar=sg,sourceLocation=sl))); -function termAttrValueDef -Def ::= sg::String sl::Location fn::String ty::Type -{ - return valueDef(defaultEnvItem(termAttrValueDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); -} +fun termAttrValueDef Def ::= sg::String sl::Location fn::String ty::Type = + valueDef(defaultEnvItem(termAttrValueDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); -function actionChildDef -Def ::= sg::String sl::Location fn::String ty::Type -{ - return valueDef(defaultEnvItem(actionChildDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); -} +fun actionChildDef Def ::= sg::String sl::Location fn::String ty::Type = + valueDef(defaultEnvItem(actionChildDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); -function parserLocalDef -Def ::= sg::String sl::Location fn::String ty::Type -{ - return valueDef(defaultEnvItem(parserLocalDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); -} +fun parserLocalDef Def ::= sg::String sl::Location fn::String ty::Type = + valueDef(defaultEnvItem(parserLocalDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); -------------------------------------------------------------------------------- -- Env.sv @@ -96,25 +78,18 @@ top::Env ::= _ e::Env top.lexerClassTree = e.lexerClassTree; } -function getLexerClassDcl -[ValueDclInfo] ::= search::String e::Env -{ - return searchEnvTree(search, e.lexerClassTree); -} +fun getLexerClassDcl [ValueDclInfo] ::= search::String e::Env = + searchEnvTree(search, e.lexerClassTree); -function expandTransitiveSuperClasses -[String] ::= seen::[String] toExpand::[String] e::Env -{ - return - case toExpand of - | [] -> seen - | c :: cs -> - if contains(c, seen) - then expandTransitiveSuperClasses(seen, cs, e) - else expandTransitiveSuperClasses( - c :: seen, flatMap((.superClasses), getLexerClassDcl(c, e)) ++ cs, e) - end; -} +fun expandTransitiveSuperClasses [String] ::= seen::[String] toExpand::[String] e::Env = + case toExpand of + | [] -> seen + | c :: cs -> + if contains(c, seen) + then expandTransitiveSuperClasses(seen, cs, e) + else expandTransitiveSuperClasses( + c :: seen, flatMap((.superClasses), getLexerClassDcl(c, e)) ++ cs, e) + end; -------------------------------------------------------------------------------- -- QName.sv diff --git a/grammars/silver/compiler/modification/copper_mda/Analysis.sv b/grammars/silver/compiler/modification/copper_mda/Analysis.sv index 68995dce2..7d15f0e6d 100644 --- a/grammars/silver/compiler/modification/copper_mda/Analysis.sv +++ b/grammars/silver/compiler/modification/copper_mda/Analysis.sv @@ -38,13 +38,10 @@ top::AGDcl ::= 'copper_mda' testname::Name '(' orig::QName ')' '{' m::ParserComp end; } -function findSpec -[ParserSpec] ::= n::String s::[ParserSpec] -{ - return if null(s) then [] - else if n == head(s).fullName then [head(s)] - else findSpec(n, tail(s)); -} +fun findSpec [ParserSpec] ::= n::String s::[ParserSpec] = + if null(s) then [] + else if n == head(s).fullName then [head(s)] + else findSpec(n, tail(s)); tracked nonterminal MdaSpec with sourceGrammar, fullName, compiledGrammars,cstAst; diff --git a/grammars/silver/compiler/modification/defaultattr/DefaultAttr.sv b/grammars/silver/compiler/modification/defaultattr/DefaultAttr.sv index 3a8338225..5fe4ea179 100644 --- a/grammars/silver/compiler/modification/defaultattr/DefaultAttr.sv +++ b/grammars/silver/compiler/modification/defaultattr/DefaultAttr.sv @@ -83,11 +83,8 @@ top::AspectDefaultProductionSignature ::= lhs::Name '::' te::TypeExpr '::=' sigNames = [lhs.name]; } -function defaultLhsDef -Def ::= sg::String sl::Location fn::String ty::Type -{ - return valueDef(defaultEnvItem(defaultLhsDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); -} +fun defaultLhsDef Def ::= sg::String sl::Location fn::String ty::Type = + valueDef(defaultEnvItem(defaultLhsDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); abstract production defaultLhsDcl top::ValueDclInfo ::= fn::String ty::Type { diff --git a/grammars/silver/compiler/modification/ffi/java/FunctionDcl.sv b/grammars/silver/compiler/modification/ffi/java/FunctionDcl.sv index 5fffd0900..b13480520 100644 --- a/grammars/silver/compiler/modification/ffi/java/FunctionDcl.sv +++ b/grammars/silver/compiler/modification/ffi/java/FunctionDcl.sv @@ -38,13 +38,10 @@ String ::= ns::NamedSignatureElement return "common.Util.<" ++ ns.typerep.transType ++ ">demand(" ++ ns.childRefElem ++ ")"; } -function computeSigTranslation -String ::= str::String sig::NamedSignature -{ - return substituteAll(str, - map(wrapStrictNotation, sig.inputNames) ++ map(wrapLazyNotation, sig.inputNames) ++ map(wrapContextNotation, range(0, length(sig.contexts))), - map(strictChildAccessor, sig.inputElements) ++ map((.childRefElem), sig.inputElements) ++ map(\ c::Context -> decorate c with {boundVariables = sig.freeVariables;}.contextRefElem, sig.contexts)); -} +fun computeSigTranslation String ::= str::String sig::NamedSignature = + substituteAll(str, + map(wrapStrictNotation, sig.inputNames) ++ map(wrapLazyNotation, sig.inputNames) ++ map(wrapContextNotation, range(0, length(sig.contexts))), + map(strictChildAccessor, sig.inputElements) ++ map((.childRefElem), sig.inputElements) ++ map(\ c::Context -> decorate c with {boundVariables = sig.freeVariables;}.contextRefElem, sig.contexts)); -- TODO: this needs clean up. diff --git a/grammars/silver/compiler/modification/ffi/util/FFIUtil.sv b/grammars/silver/compiler/modification/ffi/util/FFIUtil.sv index 18cf113c8..f0906da22 100644 --- a/grammars/silver/compiler/modification/ffi/util/FFIUtil.sv +++ b/grammars/silver/compiler/modification/ffi/util/FFIUtil.sv @@ -5,35 +5,15 @@ import silver:compiler:definition:env; import silver:compiler:definition:type; import silver:compiler:modification:ffi; -function substituteAll -String ::= s::String names::[String] results::[String] -{ - return if null(names) then s - else substituteAll(substitute(head(names), head(results), s), tail(names), tail(results)); -} +fun substituteAll String ::= s::String names::[String] results::[String] = + if null(names) then s + else substituteAll(substitute(head(names), head(results), s), tail(names), tail(results)); -function wrapStrictNotation -String ::= s::String -{ - return "%" ++ s ++ "%"; -} -function wrapLazyNotation -String ::= s::String -{ - return "%?" ++ s ++ "?%"; -} -function wrapContextNotation -String ::= i::Integer -{ - return "%@" ++ toString(i) ++ "@%"; -} +fun wrapStrictNotation String ::= s::String = "%" ++ s ++ "%"; +fun wrapLazyNotation String ::= s::String = "%?" ++ s ++ "?%"; +fun wrapContextNotation String ::= i::Integer = "%@" ++ toString(i) ++ "@%"; -function cleanStringLexeme -String ::= s::String -{ - -- peel off outer quotes - return cleanStringEscapes(substring(1,length(s)-1, s)); -} +fun cleanStringLexeme String ::= s::String = cleanStringEscapes(substring(1,length(s)-1, s)); --TODO is this necessary? I... don't think it is. function cleanStringEscapes diff --git a/grammars/silver/compiler/modification/lambda_fn/DclInfo.sv b/grammars/silver/compiler/modification/lambda_fn/DclInfo.sv index 4f6dbfe5a..d74a64701 100644 --- a/grammars/silver/compiler/modification/lambda_fn/DclInfo.sv +++ b/grammars/silver/compiler/modification/lambda_fn/DclInfo.sv @@ -26,8 +26,6 @@ top::ValueDclInfo ::= fn::String ty::Type id::Integer paramIndex::Integer top.transDefLHSDispatcher = errorTransAttrDefLHS; } -function lambdaParamDef -Def ::= sg::String sl::Location fn::String ty::Type id::Integer paramIndex::Integer -{ - return valueDef(defaultEnvItem(lambdaParamDcl(fn,ty,id,paramIndex,sourceGrammar=sg,sourceLocation=sl))); -} +fun lambdaParamDef +Def ::= sg::String sl::Location fn::String ty::Type id::Integer paramIndex::Integer = + valueDef(defaultEnvItem(lambdaParamDcl(fn,ty,id,paramIndex,sourceGrammar=sg,sourceLocation=sl))); diff --git a/grammars/silver/compiler/modification/let_fix/DclInfo.sv b/grammars/silver/compiler/modification/let_fix/DclInfo.sv index 9d9d02a8c..ed334d9ff 100644 --- a/grammars/silver/compiler/modification/let_fix/DclInfo.sv +++ b/grammars/silver/compiler/modification/let_fix/DclInfo.sv @@ -21,9 +21,7 @@ top::ValueDclInfo ::= fn::String ty::Type fi::Maybe fd::[FlowVertex] top.transDefLHSDispatcher = errorTransAttrDefLHS; } -function lexicalLocalDef -Def ::= sg::String sl::Location fn::String ty::Type fi::Maybe fd::[FlowVertex] rs::[(String, UniqueRefSite)] -{ - return valueDef(defaultEnvItem(lexicalLocalDcl(fn,ty,fi,fd,rs,sourceGrammar=sg,sourceLocation=sl))); -} +fun lexicalLocalDef +Def ::= sg::String sl::Location fn::String ty::Type fi::Maybe fd::[FlowVertex] rs::[(String, UniqueRefSite)] = + valueDef(defaultEnvItem(lexicalLocalDcl(fn,ty,fi,fd,rs,sourceGrammar=sg,sourceLocation=sl))); diff --git a/grammars/silver/compiler/modification/let_fix/java/Let.sv b/grammars/silver/compiler/modification/let_fix/java/Let.sv index 9e05417a7..f33298f27 100644 --- a/grammars/silver/compiler/modification/let_fix/java/Let.sv +++ b/grammars/silver/compiler/modification/let_fix/java/Let.sv @@ -34,11 +34,7 @@ synthesized attribute let_translation :: String occurs on AssignExpr; attribute initTransDecSites occurs on AssignExpr; propagate initTransDecSites on AssignExpr; -function makeLocalValueName -String ::= s::String -{ - return "__SV_LOCAL_" ++ makeIdName(s); -} +fun makeLocalValueName String ::= s::String = "__SV_LOCAL_" ++ makeIdName(s); aspect production appendAssignExpr top::AssignExpr ::= a1::AssignExpr a2::AssignExpr @@ -57,11 +53,8 @@ top::AssignExpr ::= id::Name '::' t::TypeExpr '=' e::Expr top.let_translation = makeSpecialLocalBinding(fName, e.translation, finalTy.transType); } -function makeSpecialLocalBinding -String ::= fn::String et::String ty::String -{ - return s"final common.Thunk<${ty}> ${makeLocalValueName(fn)} = ${wrapThunkText(et, ty)};\n"; -} +fun makeSpecialLocalBinding String ::= fn::String et::String ty::String = + s"final common.Thunk<${ty}> ${makeLocalValueName(fn)} = ${wrapThunkText(et, ty)};\n"; aspect production lexicalLocalReference top::Expr ::= q::Decorated! QName _ _ _ diff --git a/grammars/silver/compiler/modification/primitivepattern/Types.sv b/grammars/silver/compiler/modification/primitivepattern/Types.sv index 0e42b1fa2..d86e139ab 100644 --- a/grammars/silver/compiler/modification/primitivepattern/Types.sv +++ b/grammars/silver/compiler/modification/primitivepattern/Types.sv @@ -318,16 +318,13 @@ Substitution ::= te1::[Type] te2::[Type] -------- -function isOnlyTyVars -Boolean ::= ls::[Type] -{ - return case ls of - | [] -> true - | varType(_) :: t -> isOnlyTyVars(t) - | skolemType(_) :: t -> isOnlyTyVars(t) - | _ -> false - end; -} +fun isOnlyTyVars Boolean ::= ls::[Type] = + case ls of + | [] -> true + | varType(_) :: t -> isOnlyTyVars(t) + | skolemType(_) :: t -> isOnlyTyVars(t) + | _ -> false + end; -------- diff --git a/grammars/silver/compiler/refactor/BuildProcess.sv b/grammars/silver/compiler/refactor/BuildProcess.sv index c73d4e6d5..f92483b94 100644 --- a/grammars/silver/compiler/refactor/BuildProcess.sv +++ b/grammars/silver/compiler/refactor/BuildProcess.sv @@ -66,10 +66,8 @@ top::DriverAction ::= a::Decorated CmdArgs specs::[Decorated RootSpec] top.order = 4; } -function refactorSpec -IO<()> ::= r::Decorated RootSpec -{ - return do { +fun refactorSpec IO<()> ::= r::Decorated RootSpec = + do { eprintln("\t[" ++ r.declaredName ++ "]"); traverse_(\ item::(String, Root) -> when_(!endsWith(".md", item.1), -- TODO: Make this work with literate Silver files @@ -81,7 +79,6 @@ IO<()> ::= r::Decorated RootSpec }), r.transformedFiles); }; -} monoid attribute transformedFiles::[(String, Root)] occurs on RootSpec, Grammar; propagate transformedFiles on RootSpec, Grammar; diff --git a/grammars/silver/compiler/translation/java/core/ClassDcl.sv b/grammars/silver/compiler/translation/java/core/ClassDcl.sv index e8110ea0e..ff5895c8d 100644 --- a/grammars/silver/compiler/translation/java/core/ClassDcl.sv +++ b/grammars/silver/compiler/translation/java/core/ClassDcl.sv @@ -61,8 +61,4 @@ top::ClassBodyItem ::= id::Name '::' cl::ConstraintList '=>' ty::TypeExpr '=' e: """; } -function makeInstanceMemberAccessorName -String ::= s::String -{ - return "getMember_" ++ last(explode(":", s)); -} +fun makeInstanceMemberAccessorName String ::= s::String = "getMember_" ++ last(explode(":", s)); diff --git a/grammars/silver/compiler/translation/java/core/Expr.sv b/grammars/silver/compiler/translation/java/core/Expr.sv index 62502bfcd..9f6c5bdad 100644 --- a/grammars/silver/compiler/translation/java/core/Expr.sv +++ b/grammars/silver/compiler/translation/java/core/Expr.sv @@ -252,26 +252,15 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs annos::Decorated! AnnoA end; } -function argsTranslation -String ::= e::Decorated AppExprs with {decorate, decSiteVertexInfo, alwaysDecorated, appProd} -{ - -- TODO: This is the ONLY use of .exprs We could eliminate that, if we fix this. - return implode(", ", map((.lazyTranslation), e.exprs)); -} -function namedargsTranslation -String ::= e::Decorated AnnoAppExprs -{ - -- TODO: This is the ONLY use of .exprs We could eliminate that, if we fix this. - return if null(e.exprs) then "null" +fun argsTranslation +String ::= e::Decorated AppExprs with {decorate, decSiteVertexInfo, alwaysDecorated, appProd} = + implode(", ", map((.lazyTranslation), e.exprs)); +fun namedargsTranslation String ::= e::Decorated AnnoAppExprs = + if null(e.exprs) then "null" else s"new Object[]{${implode(", ", map((.lazyTranslation), reorderedAnnoAppExprs(e)))}}"; -} -function namedargsTranslationNOReorder -String ::= e::Decorated AnnoAppExprs -{ - -- TODO: This is the ONLY use of .exprs We could eliminate that, if we fix this. - return if null(e.exprs) then "null" +fun namedargsTranslationNOReorder String ::= e::Decorated AnnoAppExprs = + if null(e.exprs) then "null" else s"new Object[]{${implode(", ", map((.lazyTranslation), e.exprs))}}"; -} aspect production partialApplication top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs annos::Decorated! AnnoAppExprs @@ -666,18 +655,12 @@ top::Exprs ::= e1::Expr ',' e2::Exprs top.lazyTranslation = e1.lazyTranslation ++ ", " ++ e2.lazyTranslation; } -function wrapThunk -String ::= exp::String beLazy::Boolean -{ - return if beLazy then wrapThunkText(exp, "Object") else exp; -} -function wrapThunkText -String ::= exp::String ty::String -{ - return s"new common.Thunk<${ty}>(new common.Thunk.Evaluable<${ty}>() { public final ${ty} eval() { return ${exp}; } })"; +fun wrapThunk String ::= exp::String beLazy::Boolean = + if beLazy then wrapThunkText(exp, "Object") else exp; +fun wrapThunkText String ::= exp::String ty::String = + s"new common.Thunk<${ty}>(new common.Thunk.Evaluable<${ty}>() { public final ${ty} eval() { return ${exp}; } })"; --TODO: java lambdas are bugged --return s"new common.Thunk<${ty}>(() -> ${exp})"; -} function wrapLazy String ::= e::Decorated Expr { diff --git a/grammars/silver/compiler/translation/java/core/NamedSignature.sv b/grammars/silver/compiler/translation/java/core/NamedSignature.sv index ed52dbe6a..d7541dc96 100644 --- a/grammars/silver/compiler/translation/java/core/NamedSignature.sv +++ b/grammars/silver/compiler/translation/java/core/NamedSignature.sv @@ -295,25 +295,16 @@ s"""if (name.equals("${n}")) { } else """; } -function makeIndexDcls -String ::= i::Integer s::[NamedSignatureElement] -{ - return if null(s) then "" +fun makeIndexDcls String ::= i::Integer s::[NamedSignatureElement] = + if null(s) then "" else s"\tpublic static final int i_${head(s).elementName} = ${toString(i)};\n" ++ makeIndexDcls(i+1, tail(s)); -} -function unpackChildren -[String] ::= i::Integer ns::[NamedSignatureElement] -{ - return if null(ns) then [] +fun unpackChildren [String] ::= i::Integer ns::[NamedSignatureElement] = + if null(ns) then [] else (s"children[${toString(i)}]") :: unpackChildren(i + 1, tail(ns)); -} -function unpackAnnotations -[String] ::= i::Integer ns::[NamedSignatureElement] -{ - return if null(ns) then [] +fun unpackAnnotations [String] ::= i::Integer ns::[NamedSignatureElement] = + if null(ns) then [] else (s"annotations[${toString(i)}]") :: unpackAnnotations(i + 1, tail(ns)); -} function makeChildAccessCase String ::= n::NamedSignatureElement @@ -339,33 +330,29 @@ String ::= env::Env flowEnv::FlowEnv lhsNtName::String prodName::String n::Named | _, _ -> "" end; } -function refAccessTranslation -String ::= env::Env flowEnv::FlowEnv lhsNtName::String v::VertexType -{ - return - case v of - | lhsVertexType_real() -> error("lhs can't be a ref decoration site") - | rhsVertexType(sigName) -> error("child can't be a ref decoration site") - | localVertexType(fName) -> - case getValueDcl(fName, env) of - | dcl :: _ -> s"context.localDecorated(${dcl.attrOccursIndex})" - | [] -> error("Couldn't find decl for local " ++ fName) +fun refAccessTranslation String ::= env::Env flowEnv::FlowEnv lhsNtName::String v::VertexType = + case v of + | lhsVertexType_real() -> error("lhs can't be a ref decoration site") + | rhsVertexType(sigName) -> error("child can't be a ref decoration site") + | localVertexType(fName) -> + case getValueDcl(fName, env) of + | dcl :: _ -> s"context.localDecorated(${dcl.attrOccursIndex})" + | [] -> error("Couldn't find decl for local " ++ fName) + end + | transAttrVertexType(lhsVertexType_real(), transAttr) -> + let transIndexName::String = + case getOccursDcl(transAttr, lhsNtName, env) of + | h :: _ -> h.attrGlobalOccursInitIndex + | [] -> error(s"Trans attr ${transAttr} occurs on ${lhsNtName} dcl not found!") end - | transAttrVertexType(lhsVertexType_real(), transAttr) -> - let transIndexName::String = - case getOccursDcl(transAttr, lhsNtName, env) of - | h :: _ -> h.attrGlobalOccursInitIndex - | [] -> error(s"Trans attr ${transAttr} occurs on ${lhsNtName} dcl not found!") - end - in s"context.translation(${transIndexName}, ${transIndexName}_inhs, ${transIndexName}_dec_site)" - end - | transAttrVertexType(_, transAttr) -> error("trans attr on non-lhs can't be a ref decoration site") - | forwardVertexType_real() -> s"context.forward()" - | anonVertexType(_) -> error("dec site projection shouldn't happen with anon decorate") - | subtermVertexType(parent, prodName, sigName) -> - s"${refAccessTranslation(env, flowEnv, lhsNtName, parent)}.childDecorated(${makeProdName(prodName)}.i_${sigName})" - end; -} + in s"context.translation(${transIndexName}, ${transIndexName}_inhs, ${transIndexName}_dec_site)" + end + | transAttrVertexType(_, transAttr) -> error("trans attr on non-lhs can't be a ref decoration site") + | forwardVertexType_real() -> s"context.forward()" + | anonVertexType(_) -> error("dec site projection shouldn't happen with anon decorate") + | subtermVertexType(parent, prodName, sigName) -> + s"${refAccessTranslation(env, flowEnv, lhsNtName, parent)}.childDecorated(${makeProdName(prodName)}.i_${sigName})" + end; function makeAnnoAssign String ::= n::NamedSignatureElement @@ -393,24 +380,16 @@ ${flatMap(\ inh::String -> s"\t\t\tres[${makeConstraintDictName(inh, t, bv)}] = """; } -function makeTyVarDecls -String ::= indent::Integer vars::[TyVar] -{ - return - implode( - "\n", - map( - \ tv::TyVar -> - s"${concat(repeat("\t", indent))}common.VarTypeRep freshTypeVar_${toString(tv.varId)} = new common.VarTypeRep();", - vars)); - -} -function makeAnnoIndexDcls -String ::= i::Integer s::[NamedSignatureElement] -{ - return if null(s) then "" +fun makeTyVarDecls String ::= indent::Integer vars::[TyVar] = + implode( + "\n", + map( + \ tv::TyVar -> + s"${concat(repeat("\t", indent))}common.VarTypeRep freshTypeVar_${toString(tv.varId)} = new common.VarTypeRep();", + vars)); +fun makeAnnoIndexDcls String ::= i::Integer s::[NamedSignatureElement] = + if null(s) then "" else s"\t\tfinal int i${head(s).annoRefElem} = ${toString(i)};\n" ++ makeAnnoIndexDcls(i+1, tail(s)); -} function makeChildUnify String ::= fn::String n::NamedSignatureElement { diff --git a/grammars/silver/compiler/translation/java/core/Project.sv b/grammars/silver/compiler/translation/java/core/Project.sv index 61c1cea73..6d0f68e51 100644 --- a/grammars/silver/compiler/translation/java/core/Project.sv +++ b/grammars/silver/compiler/translation/java/core/Project.sv @@ -12,58 +12,23 @@ imports silver:compiler:definition:flow:env; imports silver:compiler:analysis:uniqueness; imports silver:compiler:analysis:typechecking:core only finalType; -function makeName -String ::= str::String -{ - return substitute(":", ".", str); -} -function makeIdName -String ::= str::String -{ - return substitute(":", "_", str); -} +fun makeName String ::= str::String = substitute(":", ".", str); +fun makeIdName String ::= str::String = substitute(":", "_", str); -function makeProdName -String ::= s::String -{ - return substituteLast(".", ".P", makeName(s)); -} +fun makeProdName String ::= s::String = substituteLast(".", ".P", makeName(s)); -function makeNTName -String ::= s::String -{ - return substituteLast(".", ".N", makeName(s)); -} +fun makeNTName String ::= s::String = substituteLast(".", ".N", makeName(s)); -function makeAnnoName -String ::= s::String -{ - return substituteLast(".", ".A", makeName(s)); -} +fun makeAnnoName String ::= s::String = substituteLast(".", ".A", makeName(s)); -function makeTerminalName -String ::= s::String -{ - return substituteLast(".", ".T", makeName(s)); -} +fun makeTerminalName String ::= s::String = substituteLast(".", ".T", makeName(s)); -function makeParserName -String ::= s::String -{ - return "Parser_" ++ makeIdName(s); -} +fun makeParserName String ::= s::String = "Parser_" ++ makeIdName(s); -function makeClassName -String ::= s::String -{ - return substituteLast(".", ".C", makeName(s)); -} +fun makeClassName String ::= s::String = substituteLast(".", ".C", makeName(s)); -function makeInstanceName -String ::= g::String s::String t::Type -{ - return substituteLast(".", ".I", makeName(g ++ ":" ++ substitute(":", "_", s))) ++ "_" ++ transTypeName(t); -} +fun makeInstanceName String ::= g::String s::String t::Type = + substituteLast(".", ".I", makeName(g ++ ":" ++ substitute(":", "_", s))) ++ "_" ++ transTypeName(t); function substituteLast String ::= r::String s::String str::String diff --git a/grammars/silver/compiler/translation/java/core/RootSpec.sv b/grammars/silver/compiler/translation/java/core/RootSpec.sv index 6824a5f52..0d53d4da5 100644 --- a/grammars/silver/compiler/translation/java/core/RootSpec.sv +++ b/grammars/silver/compiler/translation/java/core/RootSpec.sv @@ -72,9 +72,6 @@ ${g.initValues} """)]; } -function makeOthers -String ::= others::[String] nme::String -{ - return if null(others) then "" else s"\t\t${makeName(head(others))}.Init.${nme}();\n${makeOthers(tail(others),nme)}"; -} +fun makeOthers String ::= others::[String] nme::String = + if null(others) then "" else s"\t\t${makeName(head(others))}.Init.${nme}();\n${makeOthers(tail(others),nme)}"; diff --git a/grammars/silver/compiler/translation/java/driver/BuildProcess.sv b/grammars/silver/compiler/translation/java/driver/BuildProcess.sv index 723793479..a14d6d516 100644 --- a/grammars/silver/compiler/translation/java/driver/BuildProcess.sv +++ b/grammars/silver/compiler/translation/java/driver/BuildProcess.sv @@ -258,24 +258,11 @@ IO<()> ::= silverGen::String keepFiles::[String] r::Decorated RootSpec }; } -function zipfileset -String ::= s::String -{ - return " \n"; -} -function pathLocation -String ::= s::String -{ - return " \n"; -} -function includeJavaFiles -String ::= gram::String -{ - return s" \n"; -} -function includeClassFiles -String ::= gram::Decorated RootSpec -{ - return s" \n"; -} +fun zipfileset String ::= s::String = + " \n"; +fun pathLocation String ::= s::String = " \n"; +fun includeJavaFiles String ::= gram::String = + s" \n"; +fun includeClassFiles String ::= gram::Decorated RootSpec = + s" \n"; diff --git a/grammars/silver/compiler/translation/java/type/Context.sv b/grammars/silver/compiler/translation/java/type/Context.sv index 95d954a6a..0cebbcaba 100644 --- a/grammars/silver/compiler/translation/java/type/Context.sv +++ b/grammars/silver/compiler/translation/java/type/Context.sv @@ -258,8 +258,4 @@ String ::= i1::Type i2::Type tvs::[TyVar] return s"inhSubset_${i1.transTypeName}_${i2.transTypeName}"; } -function makeInstanceSuperAccessorName -String ::= s::String -{ - return "getSuper_" ++ substitute(":", "_", s); -} +fun makeInstanceSuperAccessorName String ::= s::String = "getSuper_" ++ substitute(":", "_", s); diff --git a/grammars/silver/core/Alternative.sv b/grammars/silver/core/Alternative.sv index 2e78ed001..b21ff3731 100644 --- a/grammars/silver/core/Alternative.sv +++ b/grammars/silver/core/Alternative.sv @@ -50,8 +50,4 @@ class Applicative f, Plus f => Alternative f {} @{- Conditional failure of Alternative computations. -} -function guard -Alternative f => f<()> ::= b::Boolean -{ - return if b then pure(()) else empty; -} +fun guard Alternative f => f<()> ::= b::Boolean = if b then pure(()) else empty; diff --git a/grammars/silver/core/Applicative.sv b/grammars/silver/core/Applicative.sv index bf533a7aa..20fe89442 100644 --- a/grammars/silver/core/Applicative.sv +++ b/grammars/silver/core/Applicative.sv @@ -24,27 +24,19 @@ class Apply f => Applicative f { - Prefer `map` to this function. However, it can be useful to get a `Functor` - instance for free, given an existing `Applicative` instance. -} -function liftA1 -Applicative f => f ::= f::(b ::= a) x::f -{ return ap(pure(f), x); } +fun liftA1 Applicative f => f ::= f::(b ::= a) x::f = ap(pure(f), x); -function when_ -Applicative f => f ::= cond::Boolean body::f -{ return if cond then body else pure(unit()); } +fun when_ Applicative f => f ::= cond::Boolean body::f = + if cond then body else pure(unit()); -function unless -Applicative f => f ::= cond::Boolean body::f -{ return if cond then pure(unit()) else body; } +fun unless Applicative f => f ::= cond::Boolean body::f = + if cond then pure(unit()) else body; -- These should be factored out into a Traversable type class, eventually. -function traverseA -Applicative m => m<[b]> ::= f::(m ::= a) lst::[a] -{ return foldr(lift2(cons, _, _), pure([]), map(f, lst)); } +fun traverseA Applicative m => m<[b]> ::= f::(m ::= a) lst::[a] = + foldr(lift2(cons, _, _), pure([]), map(f, lst)); -function traverse_ -Applicative m => m<()> ::= f::(m<()> ::= a) lst::[a] -{ return foldr(applySecond, pure(()), map(f, lst)); } +fun traverse_ Applicative m => m<()> ::= f::(m<()> ::= a) lst::[a] = + foldr(applySecond, pure(()), map(f, lst)); -function sequence -Applicative m => m<[a]> ::= lst::[m] -{ return foldr(lift2(cons, _, _), pure([]), lst); } +fun sequence Applicative m => m<[a]> ::= lst::[m] = foldr(lift2(cons, _, _), pure([]), lst); diff --git a/grammars/silver/core/Apply.sv b/grammars/silver/core/Apply.sv index 53c766795..9f38cf76a 100644 --- a/grammars/silver/core/Apply.sv +++ b/grammars/silver/core/Apply.sv @@ -13,26 +13,17 @@ class Functor f => Apply f { ap :: (f ::= f<(b ::= a)> f); } -function applyFirst -Apply f => f ::= a::f b::f -{ return ap(map(\x::a -> \y::b -> x, a), b); } +fun applyFirst Apply f => f ::= a::f b::f = ap(map(\x::a -> \y::b -> x, a), b); -function applySecond -Apply f => f ::= a::f b::f -{ return ap(map(\x::a -> \y::b -> y, a), b); } +fun applySecond Apply f => f ::= a::f b::f = ap(map(\x::a -> \y::b -> y, a), b); -function lift2 -Apply f => f ::= f::(c ::= a b) x::f y::f -{ return ap(map(curry(f), x), y); } +fun lift2 Apply f => f ::= f::(c ::= a b) x::f y::f = ap(map(curry(f), x), y); -function lift3 -Apply f => f ::= f::(d ::= a b c) x::f y::f z::f -{ return ap(ap(map(curry3(f), x), y), z); } +fun lift3 Apply f => f ::= f::(d ::= a b c) x::f y::f z::f = + ap(ap(map(curry3(f), x), y), z); -function lift4 -Apply f => f ::= f::(e ::= a b c d) x::f y::f z::f p::f -{ return ap(ap(ap(map(curry4(f), x), y), z), p); } +fun lift4 Apply f => f ::= f::(e ::= a b c d) x::f y::f z::f p::f = + ap(ap(ap(map(curry4(f), x), y), z), p); -function lift5 -Apply f => f ::= f::(g ::= a b c d e) x::f y::f z::f p::f q::f -{ return ap(ap(ap(ap(map(curry5(f), x), y), z), p), q); } +fun lift5 Apply f => f ::= f::(g ::= a b c d e) x::f y::f z::f p::f q::f = + ap(ap(ap(ap(map(curry5(f), x), y), z), p), q); diff --git a/grammars/silver/core/Bind.sv b/grammars/silver/core/Bind.sv index 9df043f5b..317c5cdd4 100644 --- a/grammars/silver/core/Bind.sv +++ b/grammars/silver/core/Bind.sv @@ -13,22 +13,14 @@ class Apply m => Bind m { bind :: (m ::= m (m ::= a)); } -function bindFlipped -Bind m => m ::= f::(m ::= a) x::m -{ return bind(x, f); } +fun bindFlipped Bind m => m ::= f::(m ::= a) x::m = bind(x, f); -function join -Bind m => m ::= x::m> -{ return bind(x, \x::m -> x); } +fun join Bind m => m ::= x::m> = bind(x, \x::m -> x); -function composeKleisli -Bind m => m ::= f::(m ::= a) g::(m ::= b) x::a -{ return bind(f(x), g); } +fun composeKleisli Bind m => m ::= f::(m ::= a) g::(m ::= b) x::a = bind(f(x), g); -function composeKleisliFlipped -Bind m => m ::= g::(m ::= b) f::(m ::= a) x::a -{ return composeKleisli(f, g, x); } +fun composeKleisliFlipped Bind m => m ::= g::(m ::= b) f::(m ::= a) x::a = + composeKleisli(f, g, x); -function ifM -Bind m => m ::= c::m t::m e::m -{ return bind(c, \c::Boolean -> if c then t else e); } +fun ifM Bind m => m ::= c::m t::m e::m = + bind(c, \c::Boolean -> if c then t else e); diff --git a/grammars/silver/core/DivisionRing.sv b/grammars/silver/core/DivisionRing.sv index cd086d4f0..f355e5c8b 100644 --- a/grammars/silver/core/DivisionRing.sv +++ b/grammars/silver/core/DivisionRing.sv @@ -22,14 +22,10 @@ instance DivisionRing Float { - - Iff the type is a commutative ring, this is equivalent to `rightDiv`. -} -function leftDiv -DivisionRing a => a ::= l::a r::a -{ return mul(recip(r), l); } +fun leftDiv DivisionRing a => a ::= l::a r::a = mul(recip(r), l); @{- Division implemented as `l * (1/r)`. - - Iff the type is a commutative ring, this is equivalent to `leftDiv`. -} -function rightDiv -DivisionRing a => a ::= l::a r::a -{ return mul(l, recip(r)); } +fun rightDiv DivisionRing a => a ::= l::a r::a = mul(l, recip(r)); diff --git a/grammars/silver/core/Either.sv b/grammars/silver/core/Either.sv index 3e9ad35ac..4074f279b 100644 --- a/grammars/silver/core/Either.sv +++ b/grammars/silver/core/Either.sv @@ -118,11 +118,8 @@ top::EitherT ::= x::m> @{-- - Transform the computation inside an EitherT. -} -function mapEitherT -EitherT ::= f::(n> ::= m>) x::EitherT -{ - return eitherT(f(x.run)); -} +fun mapEitherT EitherT ::= f::(n> ::= m>) x::EitherT = + eitherT(f(x.run)); instance Functor m => Functor EitherT { map = \ f::(b ::= a) x::EitherT -> mapEitherT(map(map(f, _), _), x); @@ -209,14 +206,11 @@ Pair<[a] [b]> ::= l::[Either] - @param e The either being discriminated - @param o The fallback value -} -function fromLeft -a ::= e::Either o::a -{ - return case e of +fun fromLeft a ::= e::Either o::a = + case e of | left(a) -> a | right(_) -> o end; -} @{-- - Returns the right value, or the default if there is no right value. @@ -224,12 +218,9 @@ a ::= e::Either o::a - @param e The either being discriminated - @param o The fallback value -} -function fromRight -b ::= e::Either o::b -{ - return case e of +fun fromRight b ::= e::Either o::b = + case e of | left(_) -> o | right(b) -> b end; -} diff --git a/grammars/silver/core/EuclideanRing.sv b/grammars/silver/core/EuclideanRing.sv index a425487b6..7d8acbe0e 100644 --- a/grammars/silver/core/EuclideanRing.sv +++ b/grammars/silver/core/EuclideanRing.sv @@ -55,23 +55,15 @@ Float ::= a::Float b::Float } @{- Computes the greatest common divisor of two numbers. -} -function gcd -Eq a, EuclideanRing a => a ::= a::a b::a -{ - return - if b == zero then - a - else - gcd(b, mod(a, b)); -} +fun gcd Eq a, EuclideanRing a => a ::= a::a b::a = + if b == zero then + a + else + gcd(b, mod(a, b)); @{- Computes the least common multiple of two numbers. -} -function lcm -Eq a, EuclideanRing a => a ::= a::a b::a -{ - return - if a == zero || b == zero then - zero - else - div(mul(a, b), gcd(a, b)); -} +fun lcm Eq a, EuclideanRing a => a ::= a::a b::a = + if a == zero || b == zero then + zero + else + div(mul(a, b), gcd(a, b)); diff --git a/grammars/silver/core/Function.sv b/grammars/silver/core/Function.sv index b009923bf..cb915159a 100644 --- a/grammars/silver/core/Function.sv +++ b/grammars/silver/core/Function.sv @@ -1,43 +1,24 @@ grammar silver:core; -function id -a ::= x::a -{ return x; } - -function compose -(c ::= a) ::= f1::(c ::= b) f2::(b ::= a) -{ - return \ x::a -> f1(f2(x)); -} - -function curry -((c ::= b) ::= a) ::= f::(c ::= a b) -{ return \x::a -> \y::b -> f(x, y); } - -function curry3 -(((d ::= c) ::= b) ::= a) ::= f::(d ::= a b c) -{ return \x::a -> \y::b -> \z::c -> f(x, y, z); } - -function curry4 -((((e ::= d) ::= c) ::= b) ::= a) ::= f::(e ::= a b c d) -{ return \x::a -> \y::b -> \z::c -> \p::d -> f(x, y, z, p); } - -function curry5 -(((((f ::= e) ::= d) ::= c) ::= b) ::= a) ::= f::(f ::= a b c d e) -{ return \x::a -> \y::b -> \z::c -> \p::d -> \q::e -> f(x, y, z, p, q); } - -function uncurry -c ::= f::((c ::= b) ::= a) x::a y::b -{ return f(x)(y); } - -function uncurry3 -d ::= f::(((d ::= c) ::= b) ::= a) x::a y::b z::c -{ return f(x)(y)(z); } - -function uncurry4 -e ::= f::((((e ::= d) ::= c) ::= b) ::= a) x::a y::b z::c p::d -{ return f(x)(y)(z)(p); } - -function uncurry5 -f ::= f::(((((f ::= e) ::= d) ::= c) ::= b) ::= a) x::a y::b z::c p::d q::e -{ return f(x)(y)(z)(p)(q); } +fun id a ::= x::a = x; + +fun compose (c ::= a) ::= f1::(c ::= b) f2::(b ::= a) = \ x::a -> f1(f2(x)); + +fun curry ((c ::= b) ::= a) ::= f::(c ::= a b) = \x::a -> \y::b -> f(x, y); + +fun curry3 (((d ::= c) ::= b) ::= a) ::= f::(d ::= a b c) = \x::a -> \y::b -> \z::c -> f(x, y, z); + +fun curry4 ((((e ::= d) ::= c) ::= b) ::= a) ::= f::(e ::= a b c d) = + \x::a -> \y::b -> \z::c -> \p::d -> f(x, y, z, p); + +fun curry5 (((((f ::= e) ::= d) ::= c) ::= b) ::= a) ::= f::(f ::= a b c d e) = + \x::a -> \y::b -> \z::c -> \p::d -> \q::e -> f(x, y, z, p, q); + +fun uncurry c ::= f::((c ::= b) ::= a) x::a y::b = f(x)(y); + +fun uncurry3 d ::= f::(((d ::= c) ::= b) ::= a) x::a y::b z::c = f(x)(y)(z); + +fun uncurry4 e ::= f::((((e ::= d) ::= c) ::= b) ::= a) x::a y::b z::c p::d = f(x)(y)(z)(p); + +fun uncurry5 f ::= f::(((((f ::= e) ::= d) ::= c) ::= b) ::= a) x::a y::b z::c p::d q::e = + f(x)(y)(z)(p)(q); diff --git a/grammars/silver/core/Functor.sv b/grammars/silver/core/Functor.sv index 46b992623..71a9963fd 100644 --- a/grammars/silver/core/Functor.sv +++ b/grammars/silver/core/Functor.sv @@ -14,22 +14,12 @@ class Functor f { map :: (f ::= (b ::= a) f); } -function mapFlipped -Functor f => f ::= x::f f::(b ::= a) -{ return map(f, x); } +fun mapFlipped Functor f => f ::= x::f f::(b ::= a) = map(f, x); -function void -Functor f => f ::= x::f -{ return map(\y::a -> unit(), x); } +fun void Functor f => f ::= x::f = map(\y::a -> unit(), x); -function voidLeft -Functor f => f ::= x::f y::b -{ return map(\z::a -> y, x); } +fun voidLeft Functor f => f ::= x::f y::b = map(\z::a -> y, x); -function voidRight -Functor f => f ::= x::a y::f -{ return map(\z::b -> x, y); } +fun voidRight Functor f => f ::= x::a y::f = map(\z::b -> x, y); -function flap -Functor f => f ::= fs::f<(b ::= a)> x::a -{ return map(\f::(b ::= a) -> f(x), fs); } +fun flap Functor f => f ::= fs::f<(b ::= a)> x::a = map(\f::(b ::= a) -> f(x), fs); diff --git a/grammars/silver/core/Group.sv b/grammars/silver/core/Group.sv index 3eba7196d..4d69cf8c7 100644 --- a/grammars/silver/core/Group.sv +++ b/grammars/silver/core/Group.sv @@ -14,15 +14,11 @@ class Monoid g => Group g { @{- Computes the integer exponent of some group (treating the semigroup as - multiplication, as is standard in algebra). -} -function power -Group g => g ::= x::g n::Integer -{ - return - if n < 0 then - invert(powerHelper(x, -n)) - else - powerHelper(x, n); -} +fun power Group g => g ::= x::g n::Integer = + if n < 0 then + invert(powerHelper(x, -n)) + else + powerHelper(x, n); @{- @hide -} function powerHelper diff --git a/grammars/silver/core/IO.sv b/grammars/silver/core/IO.sv index 9e99abb20..036e407b4 100644 --- a/grammars/silver/core/IO.sv +++ b/grammars/silver/core/IO.sv @@ -134,17 +134,11 @@ top::IO ::= s::String top.stateVal = unit(); } -function println -IO ::= str::String -{ return stateIOUnit(printlnT(str, _)); } +fun println IO ::= str::String = stateIOUnit(printlnT(str, _)); -function eprint -IO ::= str::String -{ return stateIOUnit(eprintT(str, _)); } +fun eprint IO ::= str::String = stateIOUnit(eprintT(str, _)); -function eprintln -IO ::= str::String -{ return stateIOUnit(eprintlnT(str, _)); } +fun eprintln IO ::= str::String = stateIOUnit(eprintlnT(str, _)); abstract production readLineStdin top::IO> ::= diff --git a/grammars/silver/core/IOMisc.sv b/grammars/silver/core/IOMisc.sv index c055a62a9..2af30191c 100644 --- a/grammars/silver/core/IOMisc.sv +++ b/grammars/silver/core/IOMisc.sv @@ -59,11 +59,7 @@ Float ::= - @return val, unchanged. - @warning see @link[unsafeIO] -} -function unsafeTracePrint -a ::= val::a str::String -{ - return unsafeTrace(val, printT(str, unsafeIO())); -} +fun unsafeTracePrint a ::= val::a str::String = unsafeTrace(val, printT(str, unsafeIO())); @{-- - Print a stringification of a value when it is demanded by the Silver runtime. @@ -73,11 +69,7 @@ a ::= val::a str::String - @return val, unchanged. - @warning see @link[unsafeIO] -} -function unsafeTraceDump -a ::= val::a -{ - return unsafeTrace(val, printlnT(genericShow(val), unsafeIO())); -} +fun unsafeTraceDump a ::= val::a = unsafeTrace(val, printlnT(genericShow(val), unsafeIO())); diff --git a/grammars/silver/core/IOToken.sv b/grammars/silver/core/IOToken.sv index af65a9b54..d7e46532e 100644 --- a/grammars/silver/core/IOToken.sv +++ b/grammars/silver/core/IOToken.sv @@ -63,11 +63,7 @@ IOToken ::= s::String i::IOToken @{-- - Like printT, but adds a trailing newline automatically. -} -function printlnT -IOToken ::= str::String ioIn::IOToken -{ - return printT(str ++ "\n", ioIn); -} +fun printlnT IOToken ::= str::String ioIn::IOToken = printT(str ++ "\n", ioIn); @{-- - Like printT, but for stderr. @@ -83,11 +79,7 @@ IOToken ::= str::String ioIn::IOToken @{-- - Like eprintT, but adds a trailing newline automatically. -} -function eprintlnT -IOToken ::= str::String ioIn::IOToken -{ - return eprintT(str ++ "\n", ioIn); -} +fun eprintlnT IOToken ::= str::String ioIn::IOToken = eprintT(str ++ "\n", ioIn); @{-- - Read a line from standard input. diff --git a/grammars/silver/core/List.sv b/grammars/silver/core/List.sv index 26dee3cb1..e777f3741 100644 --- a/grammars/silver/core/List.sv +++ b/grammars/silver/core/List.sv @@ -95,16 +95,13 @@ instance Length [a] { - all the results that are just. The same as Haskell's 'mapMaybe' and Rust's - filter_map. -} -function filterMap -[b] ::= f::(Maybe ::= a) lst::[a] -{ - return flatMap( +fun filterMap [b] ::= f::(Maybe ::= a) lst::[a] = + flatMap( \x::a -> case f(x) of | just(y) -> [y] | nothing() -> [] end, lst); -} @{-- - Applies an operator right-associatively over a list. @@ -115,12 +112,9 @@ function filterMap - @param l The list to fold - @return The result of the function applied right-associatively to the list. -} -function foldr -b ::= f::(b ::= a b) i::b l::[a] -{ - return if null(l) then i - else f(head(l), foldr(f, i, tail(l))); -} +fun foldr b ::= f::(b ::= a b) i::b l::[a] = + if null(l) then i + else f(head(l), foldr(f, i, tail(l))); @{-- - Applies an operator left-associatively over a list. @@ -130,24 +124,18 @@ b ::= f::(b ::= a b) i::b l::[a] - @param l The list to fold - @return The result of the function applied left-associatively to the list. -} -function foldl -b ::= f::(b ::= b a) i::b l::[a] -{ - return if null(l) then i - else foldl(f, f(i, head(l)), tail(l)); -} +fun foldl b ::= f::(b ::= b a) i::b l::[a] = + if null(l) then i + else foldl(f, f(i, head(l)), tail(l)); @{-- - Right-fold, assuming there is always one element, and leaving that element - unchanged for single element lists. See @link[foldr]. -} -function foldr1 -a ::= f::(a ::= a a) l::[a] -{ - return if null(l) then error("Applying foldr1 to empty list.") - else if null(tail(l)) then head(l) - else f(head(l), foldr1(f, tail(l))); -} +fun foldr1 a ::= f::(a ::= a a) l::[a] = + if null(l) then error("Applying foldr1 to empty list.") + else if null(tail(l)) then head(l) + else f(head(l), foldr1(f, tail(l))); @{- - @param f The fold function for combining an element and your accumulator @@ -156,27 +144,21 @@ a ::= f::(a ::= a a) l::[a] - @return An element that is the result of your combining functions applied to the list elements. - Right-Fold, assuming there is always at least one element, and also takes in a function a->b to apply to the last element of a list, and applies that function to the last element. -} -function foldrLastElem -b ::= f::(b ::= a b) i::(b ::= a) l::[a] -{ - return case l of +fun foldrLastElem b ::= f::(b ::= a b) i::(b ::= a) l::[a] = + case l of | [elem] -> i(elem) | h::t -> f(h, foldrLastElem(f,i,t)) | [] -> error("You can't call foldrLastElem with an empty list") end; -} @{-- - Left-fold, assuming there is always one element, and leaving that element - unchanged for single element lists. See @link[foldl]. -} -function foldl1 -a ::= f::(a ::= a a) l::[a] -{ - return if null(l) then error("Applying foldl1 to empty list.") - else foldl(f, head(l), tail(l)); -} +fun foldl1 a ::= f::(a ::= a a) l::[a] = + if null(l) then error("Applying foldl1 to empty list.") + else foldl(f, head(l), tail(l)); @{-- - Filter out elements of a list. @@ -186,15 +168,12 @@ a ::= f::(a ::= a a) l::[a] - @return Only those elements of 'lst' that 'f' returns true for, in the - same order as they appeared in 'lst' -} -function filter -[a] ::= f::(Boolean ::= a) lst::[a] -{ - return if null(lst) - then [] - else if f(head(lst)) - then head(lst) :: filter(f, tail(lst)) - else filter(f, tail(lst)); -} +fun filter [a] ::= f::(Boolean ::= a) lst::[a] = + if null(lst) + then [] + else if f(head(lst)) + then head(lst) :: filter(f, tail(lst)) + else filter(f, tail(lst)); @{-- - Monadic (actually Applicative) version of filter @@ -204,20 +183,17 @@ function filter - @return Only those elements of 'lst' that 'f' returns true for, in the - same order as they appeared in 'lst' -} -function filterM +fun filterM Applicative m => -m<[a]> ::= f::(m ::= a) lst::[a] -{ - return - case lst of - | [] -> pure([]) - | h :: t -> do { - cond::Boolean <- f(h); - rest::[a] <- filterM(f, t); - return if cond then h :: rest else rest; - } - end; -} +m<[a]> ::= f::(m ::= a) lst::[a] = + case lst of + | [] -> pure([]) + | h :: t -> do { + cond::Boolean <- f(h); + rest::[a] <- filterM(f, t); + return if cond then h :: rest else rest; + } + end; @{-- - Partition a list in two @@ -247,11 +223,8 @@ Pair<[a] [a]> ::= f::(Boolean ::= a) lst::[a] - @return True if the equality function returns true for some element of the list, - false otherwise. -} -function containsBy -Boolean ::= eq::(Boolean ::= a a) elem::a lst::[a] -{ - return (!null(lst)) && (eq(elem, head(lst)) || containsBy(eq, elem, tail(lst))); -} +fun containsBy Boolean ::= eq::(Boolean ::= a a) elem::a lst::[a] = + (!null(lst)) && (eq(elem, head(lst)) || containsBy(eq, elem, tail(lst))); @{-- - Determine if an element appears in a list. @@ -260,11 +233,7 @@ Boolean ::= eq::(Boolean ::= a a) elem::a lst::[a] - @param lst The list to search - @return True if == is true for some element of the list, false otherwise. -} -function contains -Eq a => Boolean ::= elem::a lst::[a] -{ - return containsBy(eq, elem, lst); -} +fun contains Eq a => Boolean ::= elem::a lst::[a] = containsBy(eq, elem, lst); @{-- - Removes all duplicates from a list. @@ -273,12 +242,9 @@ Eq a => Boolean ::= elem::a lst::[a] - @param xs The list to remove duplicates from - @return A list containing no duplicates, according to the equality function. -} -function nubBy -[a] ::= eq::(Boolean ::= a a) xs::[a] -{ - return if null(xs) then [] - else head(xs) :: nubBy(eq, removeBy(eq, head(xs), tail(xs))); -} +fun nubBy [a] ::= eq::(Boolean ::= a a) xs::[a] = + if null(xs) then [] + else head(xs) :: nubBy(eq, removeBy(eq, head(xs), tail(xs))); @{-- - Removes all duplicates from a list. @@ -286,11 +252,7 @@ function nubBy - @param xs The list to remove duplicates from - @return A list containing no duplicates, according to ==. -} -function nub -Eq a => [a] ::= xs::[a] -{ - return nubBy(eq, xs); -} +fun nub Eq a => [a] ::= xs::[a] = nubBy(eq, xs); @{-- - Removes all instances of an element from a list. @@ -300,12 +262,9 @@ Eq a => [a] ::= xs::[a] - @param xs The list to remove the element from - @return A list with no remaining instances of 'x' according to 'eq' -} -function removeBy -[a] ::= eq::(Boolean ::= a a) x::a xs::[a] -{ - return if null(xs) then [] - else (if eq(x,head(xs)) then [] else [head(xs)]) ++ removeBy(eq, x, tail(xs)); -} +fun removeBy [a] ::= eq::(Boolean ::= a a) x::a xs::[a] = + if null(xs) then [] + else (if eq(x,head(xs)) then [] else [head(xs)]) ++ removeBy(eq, x, tail(xs)); @{-- - Removes all instances of an element from a list. @@ -314,11 +273,7 @@ function removeBy - @param xs The list to remove the element from - @return A list with no remaining instances of 'x' according to == -} -function remove -Eq a => [a] ::= x::a xs::[a] -{ - return removeBy(eq, x, xs); -} +fun remove Eq a => [a] ::= x::a xs::[a] = removeBy(eq, x, xs); @{-- - Removes all instances of several elements from a list: xs - ys @@ -328,12 +283,9 @@ Eq a => [a] ::= x::a xs::[a] - @param xs The list to remove elements from - @return A list with no remaining instances in 'ys' according to 'eq' -} -function removeAllBy -[a] ::= eq::(Boolean ::= a a) ys::[a] xs::[a] -{ - return if null(ys) then xs - else removeAllBy(eq, tail(ys), removeBy(eq, head(ys), xs)); -} +fun removeAllBy [a] ::= eq::(Boolean ::= a a) ys::[a] xs::[a] = + if null(ys) then xs + else removeAllBy(eq, tail(ys), removeBy(eq, head(ys), xs)); @{-- - Removes all instances of several elements from a list: xs - ys @@ -342,11 +294,7 @@ function removeAllBy - @param xs The list to remove elements from - @return A list with no remaining instances in 'ys' according to 'eq' -} -function removeAll -Eq a => [a] ::= ys::[a] xs::[a] -{ - return removeAllBy(eq, ys, xs); -} +fun removeAll Eq a => [a] ::= ys::[a] xs::[a] = removeAllBy(eq, ys, xs); @{-- - Returns the initial elements of a list. @@ -354,13 +302,10 @@ Eq a => [a] ::= ys::[a] xs::[a] - @param lst The list to examine - @return The initial elements of 'lst'. If 'lst' is empty, crash. -} -function init -[a] ::= lst::[a] -{ - return if null(tail(lst)) - then [] - else head(lst)::init(tail(lst)); -} +fun init [a] ::= lst::[a] = + if null(tail(lst)) + then [] + else head(lst)::init(tail(lst)); @{-- - Returns the last element of a list. @@ -368,98 +313,54 @@ function init - @param lst The list to examine - @return The last element of 'lst'. If 'lst' is empty, crash. -} -function last -a ::= lst::[a] -{ - return if null(tail(lst)) then head(lst) - else last(tail(lst)); -} - -function drop -[a] ::= number::Integer lst::[a] -{ - return if null(lst) || number <= 0 then lst - else drop(number-1, tail(lst)); -} -function take -[a] ::= number::Integer lst::[a] -{ - return if null(lst) || number <= 0 then [] - else head(lst) :: take(number-1, tail(lst)); -} -function dropWhile -[a] ::= f::(Boolean::=a) lst::[a] -{ - return if null(lst) || !f(head(lst)) then lst - else dropWhile(f, tail(lst)); -} -function takeWhile -[a] ::= f::(Boolean::=a) lst::[a] -{ - return if null(lst) || !f(head(lst)) then [] - else head(lst) :: takeWhile(f, tail(lst)); -} -function takeUntil -[a] ::= f::(Boolean::=a) lst::[a] -{ - return if null(lst) || f(head(lst)) - then [] - else head(lst) :: takeUntil(f, tail(lst)); -} - -function positionOfBy -Integer ::= eq::(Boolean ::= a a) x::a xs::[a] -{ - return positionOfHelper(eq,x,xs,0); -} - -function positionOfHelper -Integer ::= eq::(Boolean ::= a a) x::a xs::[a] currentPos::Integer -{ - return if null(xs) then -1 - else if eq(x, head(xs)) then currentPos - else positionOfHelper(eq, x, tail(xs), currentPos+1); -} - -function positionOf -Eq a => Integer ::= x::a xs::[a] -{ - return positionOfBy(eq, x, xs); -} - -function repeat -[a] ::= v::a times::Integer -{ - return if times <= 0 then [] - else v :: repeat(v, times-1); -} - -function range -[Integer] ::= lower::Integer upper::Integer -{ - return if lower >= upper then [] else lower :: range(lower + 1, upper); -} - -function zipWith -[c] ::= f::(c ::= a b) l1::[a] l2::[b] -{ - return if null(l1) || null(l2) then [] - else f(head(l1), head(l2)) :: zipWith(f, tail(l1), tail(l2)); -} - -function unzipWith -[c] ::= f::(c ::= a b) l::[(a, b)] -{ - return if null(l) then [] - else f(head(l).1, head(l).2) :: unzipWith(f, tail(l)); -} - -function zip -[(a, b)] ::= l1::[a] l2::[b] -{ - return if null(l1) || null(l2) then [] - else (head(l1), head(l2)) :: zip(tail(l1), tail(l2)); -} +fun last a ::= lst::[a] = + if null(tail(lst)) then head(lst) + else last(tail(lst)); + +fun drop [a] ::= number::Integer lst::[a] = + if null(lst) || number <= 0 then lst + else drop(number-1, tail(lst)); +fun take [a] ::= number::Integer lst::[a] = + if null(lst) || number <= 0 then [] + else head(lst) :: take(number-1, tail(lst)); +fun dropWhile [a] ::= f::(Boolean::=a) lst::[a] = + if null(lst) || !f(head(lst)) then lst + else dropWhile(f, tail(lst)); +fun takeWhile [a] ::= f::(Boolean::=a) lst::[a] = + if null(lst) || !f(head(lst)) then [] + else head(lst) :: takeWhile(f, tail(lst)); +fun takeUntil [a] ::= f::(Boolean::=a) lst::[a] = + if null(lst) || f(head(lst)) + then [] + else head(lst) :: takeUntil(f, tail(lst)); + +fun positionOfBy Integer ::= eq::(Boolean ::= a a) x::a xs::[a] = positionOfHelper(eq,x,xs,0); + +fun positionOfHelper Integer ::= eq::(Boolean ::= a a) x::a xs::[a] currentPos::Integer = + if null(xs) then -1 + else if eq(x, head(xs)) then currentPos + else positionOfHelper(eq, x, tail(xs), currentPos+1); + +fun positionOf Eq a => Integer ::= x::a xs::[a] = positionOfBy(eq, x, xs); + +fun repeat [a] ::= v::a times::Integer = + if times <= 0 then [] + else v :: repeat(v, times-1); + +fun range [Integer] ::= lower::Integer upper::Integer = + if lower >= upper then [] else lower :: range(lower + 1, upper); + +fun zipWith [c] ::= f::(c ::= a b) l1::[a] l2::[b] = + if null(l1) || null(l2) then [] + else f(head(l1), head(l2)) :: zipWith(f, tail(l1), tail(l2)); + +fun unzipWith [c] ::= f::(c ::= a b) l::[(a, b)] = + if null(l) then [] + else f(head(l).1, head(l).2) :: unzipWith(f, tail(l)); + +fun zip [(a, b)] ::= l1::[a] l2::[b] = + if null(l1) || null(l2) then [] + else (head(l1), head(l2)) :: zip(tail(l1), tail(l2)); function unzip ([a], [b]) ::= l::[(a, b)] @@ -469,12 +370,9 @@ function unzip else (head(l).1 :: rest.1, head(l).2 :: rest.2); } -function zip3 -[(a, b, c)] ::= l1::[a] l2::[b] l3::[c] -{ - return if null(l1) || null(l2) || null(l3) then [] - else (head(l1), head(l2), head(l3)) :: zip3(tail(l1), tail(l2), tail(l3)); -} +fun zip3 [(a, b, c)] ::= l1::[a] l2::[b] l3::[c] = + if null(l1) || null(l2) || null(l3) then [] + else (head(l1), head(l2), head(l3)) :: zip3(tail(l1), tail(l2), tail(l3)); function unzip3 ([a], [b], [c]) ::= l::[(a, b, c)] @@ -491,36 +389,18 @@ fun enumerateFrom [(Integer, a)] ::= i::Integer l::[a] = | [] -> [] end; -function reverse -[a] ::= lst::[a] -{ - return reverseHelp(lst, []); -} -function reverseHelp -- do not use -[a] ::= lst::[a] sofar::[a] -{ - return if null(lst) then sofar - else reverseHelp(tail(lst), head(lst) :: sofar); -} +fun reverse [a] ::= lst::[a] = reverseHelp(lst, []); +fun reverseHelp [a] ::= lst::[a] sofar::[a] = + if null(lst) then sofar + else reverseHelp(tail(lst), head(lst) :: sofar); -function sortBy -[a] ::= lte::(Boolean ::= a a) lst::[a] -{ - return sortByHelp(lte, lst, length(lst)); -} +fun sortBy [a] ::= lte::(Boolean ::= a a) lst::[a] = sortByHelp(lte, lst, length(lst)); -function sortByKey -Ord b => [a] ::= key::(b ::= a) lst::[a] -{ - return sortBy(\l::a r::a -> key(l) <= key(r), - lst); -} +fun sortByKey Ord b => [a] ::= key::(b ::= a) lst::[a] = + sortBy(\l::a r::a -> key(l) <= key(r), + lst); -function sort -Ord a => [a] ::= lst::[a] -{ - return sortByHelp(lte, lst, length(lst)); -} +fun sort Ord a => [a] ::= lst::[a] = sortByHelp(lte, lst, length(lst)); function sortByHelp -- do not use [a] ::= lte::(Boolean ::= a a) lst::[a] upTo::Integer @@ -538,15 +418,12 @@ function sortByHelp -- do not use local attribute middle :: Integer; middle = toInteger(toFloat(upTo) / 2.0); } -function mergeBy -- do not use -[a] ::= lte::(Boolean ::= a a) l1::[a] l2::[a] -{ - return if null(l1) then l2 +fun mergeBy [a] ::= lte::(Boolean ::= a a) l1::[a] l2::[a] = + if null(l1) then l2 else if null(l2) then l1 else if lte(head(l1), head(l2)) then head(l1) :: mergeBy(lte, tail(l1), l2) else head(l2) :: mergeBy(lte, l1, tail(l2)); -} function groupBy [[a]] ::= eq::(Boolean ::= a a) l::[a] @@ -571,96 +448,56 @@ Pair<[a] [a]> ::= eq::(Boolean ::= a a) f::a l::[a] else (head(l) :: recurse.fst, recurse.snd); } -function group -Eq a => [[a]] ::= l::[a] -{ - return groupBy(eq, l); -} +fun group Eq a => [[a]] ::= l::[a] = groupBy(eq, l); @{-- - Inserts the separator in between all elements of the list. -} -function intersperse -[a] ::= sep::a xs::[a] -{ return if null(xs) then [] - else if null(tail(xs)) then xs - else head(xs) :: sep :: intersperse(sep, tail(xs)); -} +fun intersperse [a] ::= sep::a xs::[a] = + if null(xs) then [] + else if null(tail(xs)) then xs + else head(xs) :: sep :: intersperse(sep, tail(xs)); -- Set operations -function unionBy -[a] ::= eq::(Boolean ::= a a) l::[a] r::[a] -{ - return if null(l) then r - else - (if containsBy(eq, head(l), r) - then [] - else [head(l)]) - ++ unionBy(eq, tail(l), r); -} - -function union -Eq a => [a] ::= l::[a] r::[a] -{ - return unionBy(eq, l, r); -} - -function intersectBy -[a] ::= eq::(Boolean ::= a a) l::[a] r::[a] -{ - return if null(l) then [] - else - (if containsBy(eq, head(l), r) - then [head(l)] - else []) - ++ intersectBy(eq, tail(l), r); -} - -function intersect -Eq a => [a] ::= l::[a] r::[a] -{ - return intersectBy(eq, l, r); -} - -function unionsBy -[a] ::= eq::(Boolean ::= a a) ss::[[a]] -{ - return nubBy(eq, concat(ss)); -} - -function unions -Eq a => [a] ::= ss::[[a]] -{ - return nub(concat(ss)); -} - -function powerSet -[[a]] ::= xs::[a] -{ - return - case xs of - | h :: t -> - let rest::[[a]] = powerSet(t) - in rest ++ map(cons(h, _), rest) - end - | [] -> [[]] - end; -} +fun unionBy [a] ::= eq::(Boolean ::= a a) l::[a] r::[a] = + if null(l) then r + else + (if containsBy(eq, head(l), r) + then [] + else [head(l)]) + ++ unionBy(eq, tail(l), r); + +fun union Eq a => [a] ::= l::[a] r::[a] = unionBy(eq, l, r); + +fun intersectBy [a] ::= eq::(Boolean ::= a a) l::[a] r::[a] = + if null(l) then [] + else + (if containsBy(eq, head(l), r) + then [head(l)] + else []) + ++ intersectBy(eq, tail(l), r); + +fun intersect Eq a => [a] ::= l::[a] r::[a] = intersectBy(eq, l, r); + +fun unionsBy [a] ::= eq::(Boolean ::= a a) ss::[[a]] = nubBy(eq, concat(ss)); + +fun unions Eq a => [a] ::= ss::[[a]] = nub(concat(ss)); + +fun powerSet [[a]] ::= xs::[a] = + case xs of + | h :: t -> + let rest::[[a]] = powerSet(t) + in rest ++ map(cons(h, _), rest) + end + | [] -> [[]] + end; -- Boolean list operations -function all -Boolean ::= l::[Boolean] -{ - return foldr(\ a::Boolean b::Boolean -> a && b, true, l); -} +fun all Boolean ::= l::[Boolean] = foldr(\ a::Boolean b::Boolean -> a && b, true, l); -function any -Boolean ::= l::[Boolean] -{ - return foldr(\ a::Boolean b::Boolean -> a || b, false, l); -} +fun any Boolean ::= l::[Boolean] = foldr(\ a::Boolean b::Boolean -> a || b, false, l); -------------------------------------------------------------------------------- diff --git a/grammars/silver/core/Location.sv b/grammars/silver/core/Location.sv index 006e5fd7d..ca531f997 100644 --- a/grammars/silver/core/Location.sv +++ b/grammars/silver/core/Location.sv @@ -87,10 +87,9 @@ top::Location ::= text::String - terminal in the host language. use linesOffset, firstLineColsOffset, allLinesColsOffset, indexOffset if some - part of the terminal is munged before being passed to the child parser (e.g. the {- and -} are removed from a comment.) -} -function childParserLoc -Location ::= parent::Location child::Location linesOffset::Integer firstLineColsOffset::Integer allLinesColsOffset::Integer indexOffset::Integer -{ - return loc( +fun childParserLoc +Location ::= parent::Location child::Location linesOffset::Integer firstLineColsOffset::Integer allLinesColsOffset::Integer indexOffset::Integer = + loc( parent.filename, parent.line - 1 + linesOffset + child.line, allLinesColsOffset + (if child.line == 1 then parent.column + firstLineColsOffset + child.column else child.column), @@ -99,7 +98,6 @@ Location ::= parent::Location child::Location linesOffset::Integer firstLineCols parent.index + indexOffset + child.index, parent.endIndex + indexOffset + child.endIndex ); -} @{-- @@ -107,17 +105,9 @@ Location ::= parent::Location child::Location linesOffset::Integer firstLineCols - - @param module The name of the extension/modification/module defining the location -} -function builtinLoc -Location ::= module::String -{ - return txtLoc("Built in from " ++ module); -} +fun builtinLoc Location ::= module::String = txtLoc("Built in from " ++ module); @{-- - A helper constructor for location information, for invalid or undefined bogus locations -} -function bogusLoc -Location ::= -{ - return txtLoc("Invalid or undefined bogus location"); -} +fun bogusLoc Location ::= = txtLoc("Invalid or undefined bogus location"); diff --git a/grammars/silver/core/Maybe.sv b/grammars/silver/core/Maybe.sv index 5403458d3..79032028d 100644 --- a/grammars/silver/core/Maybe.sv +++ b/grammars/silver/core/Maybe.sv @@ -93,11 +93,7 @@ top::MaybeT ::= x::m> @{-- - Transform the computation inside a MaybeT. -} -function mapMaybeT -MaybeT ::= f::(n> ::= m>) x::MaybeT -{ - return maybeT(f(x.run)); -} +fun mapMaybeT MaybeT ::= f::(n> ::= m>) x::MaybeT = maybeT(f(x.run)); instance Functor m => Functor MaybeT { map = \ f::(b ::= a) x::MaybeT -> mapMaybeT(map(map(f, _), _), x); @@ -174,11 +170,8 @@ instance MonadTrans MaybeT { - @param ifJust The maybe value to scrutinize - @return Either the contents of the Maybe (if 'just'), or the otherwise element. -} -function fromMaybe -a ::= otherwise::a ifJust::Maybe -{ - return if ifJust.isJust then ifJust.fromJust else otherwise; -} +fun fromMaybe a ::= otherwise::a ifJust::Maybe = + if ifJust.isJust then ifJust.fromJust else otherwise; @{-- - Selects the first existing element, favoring the left. @@ -187,25 +180,17 @@ a ::= otherwise::a ifJust::Maybe - @param r The second element - @return A wrapped element, if any, favoring 'l' -} -function orElse -Maybe ::= l::Maybe r::Maybe -{ - return if l.isJust then l else r; -} +fun orElse Maybe ::= l::Maybe r::Maybe = if l.isJust then l else r; @{-- - The eliminator for Maybe. Runs ifJust on the wrapped value if there is one, - otherwise returns ifNothing. -} -function mapOrElse -b ::= ifNothing::b ifJust::(b ::= a) value::Maybe -{ - return - case value of - | just(x) -> ifJust(x) - | nothing() -> ifNothing - end; -} +fun mapOrElse b ::= ifNothing::b ifJust::(b ::= a) value::Maybe = + case value of + | just(x) -> ifJust(x) + | nothing() -> ifNothing + end; @{-- - Maybe cons a value to a list, or not. @@ -214,11 +199,7 @@ b ::= ifNothing::b ifJust::(b ::= a) value::Maybe - @param t The list to amend, if there's a value - @return The list, possibly with a new value at its head. -} -function consMaybe -[a] ::= h::Maybe t::[a] -{ - return if h.isJust then h.fromJust :: t else t; -} +fun consMaybe [a] ::= h::Maybe t::[a] = if h.isJust then h.fromJust :: t else t; @{-- - Turn a list of possible values into a list of values, skipping over @@ -227,22 +208,15 @@ function consMaybe - @param l A list of optional values - @return The list with all absent values removed, and present values unwrapped. -} -function catMaybes -[a] ::= l::[Maybe] -{ - return foldr(consMaybe, [], l); -} +fun catMaybes [a] ::= l::[Maybe] = foldr(consMaybe, [], l); @{-- - Finds the first value matching a predicate. -} -function find -Maybe ::= f::(Boolean ::= a) l::[a] -{ - return if null(l) then +fun find Maybe ::= f::(Boolean ::= a) l::[a] = + if null(l) then nothing() else if f(head(l)) then just(head(l)) else find(f, tail(l)); -} diff --git a/grammars/silver/core/Monad.sv b/grammars/silver/core/Monad.sv index 68b8b5bf5..9e1a2ab36 100644 --- a/grammars/silver/core/Monad.sv +++ b/grammars/silver/core/Monad.sv @@ -14,23 +14,16 @@ class Applicative m, Bind m => Monad m {} -- Prefer `fmap` to this function. However, it can be useful to get a `Functor` -- instance for free, given an existing `Monad` instance. -function liftM1 -Monad m => m ::= f::(b ::= a) x::m -{ return bind(x, \x::a -> pure(f(x))); } +fun liftM1 Monad m => m ::= f::(b ::= a) x::m = bind(x, \x::a -> pure(f(x))); -- Prefer `ap` to this function. However, it can be useful to get an -- `Applicative` instance for free, given an existing `Monad` instance. -function apM -Monad m => m ::= f::m<(b ::= a)> x::m -{ return bind(f, \f::(b ::= a) -> bind(x, \x::a -> pure(f(x)))); } +fun apM Monad m => m ::= f::m<(b ::= a)> x::m = + bind(f, \f::(b ::= a) -> bind(x, \x::a -> pure(f(x)))); -function whenM -Monad m => m ::= cond::m body::m -{ return bind(cond, when_(_, body)); } +fun whenM Monad m => m ::= cond::m body::m = bind(cond, when_(_, body)); -function unlessM -Monad m => m ::= cond::m body::m -{ return bind(cond, unless(_, body)); } +fun unlessM Monad m => m ::= cond::m body::m = bind(cond, unless(_, body)); @{- Monads that support failure with an error message. diff --git a/grammars/silver/core/Monoid.sv b/grammars/silver/core/Monoid.sv index ad4791a41..361a409a6 100644 --- a/grammars/silver/core/Monoid.sv +++ b/grammars/silver/core/Monoid.sv @@ -43,11 +43,7 @@ instance Monoid Unit { - @param lst A list - @return The combined list -} -function flatMap -Monoid m => m ::= f::(m ::= a) lst::[a] -{ - return concat(map(f, lst)); -} +fun flatMap Monoid m => m ::= f::(m ::= a) lst::[a] = concat(map(f, lst)); @{- Computes the integer exponent of some monoid (treating the semigroup as - multiplication, as is standard in algebra). @@ -55,11 +51,8 @@ Monoid m => m ::= f::(m ::= a) lst::[a] - Note that for negative `n`, this errors out. If your type is a `Group`, use - `power` instead. -} -function mpower -Monoid m => m ::= x::m n::Integer -{ - return case power(mPowerHelper(x), n) of mPowerHelper(y) -> y end; -} +fun mpower Monoid m => m ::= x::m n::Integer = + case power(mPowerHelper(x), n) of mPowerHelper(y) -> y end; @{- @hide -} data nonterminal MPowerHelper; @@ -70,15 +63,11 @@ top::MPowerHelper ::= m {} @{- @hide -} -function mPowerHelperAppend -Semigroup m => MPowerHelper ::= xH::MPowerHelper yH::MPowerHelper -{ - return - case xH, yH of - | mPowerHelper(x), mPowerHelper(y) -> - mPowerHelper(append(x, y)) - end; -} +fun mPowerHelperAppend Semigroup m => MPowerHelper ::= xH::MPowerHelper yH::MPowerHelper = + case xH, yH of + | mPowerHelper(x), mPowerHelper(y) -> + mPowerHelper(append(x, y)) + end; instance Semigroup m => Semigroup MPowerHelper { append = mPowerHelperAppend; } instance Monoid m => Monoid MPowerHelper { mempty = mPowerHelper(mempty); } diff --git a/grammars/silver/core/Ord.sv b/grammars/silver/core/Ord.sv index 3cf99623f..cb424f649 100644 --- a/grammars/silver/core/Ord.sv +++ b/grammars/silver/core/Ord.sv @@ -131,26 +131,10 @@ instance Ord Boolean { gt = gtBoolean; gte = gteBoolean; } -function ltBoolean -Boolean ::= x::Boolean y::Boolean -{ - return x == false && y == true; -} -function lteBoolean -Boolean ::= x::Boolean y::Boolean -{ - return x != true || y != false; -} -function gtBoolean -Boolean ::= x::Boolean y::Boolean -{ - return x == true && y == false; -} -function gteBoolean -Boolean ::= x::Boolean y::Boolean -{ - return x != true || y != false; -} +fun ltBoolean Boolean ::= x::Boolean y::Boolean = x == false && y == true; +fun lteBoolean Boolean ::= x::Boolean y::Boolean = x != true || y != false; +fun gtBoolean Boolean ::= x::Boolean y::Boolean = x == true && y == false; +fun gteBoolean Boolean ::= x::Boolean y::Boolean = x != true || y != false; instance Ord String { compare = compareString; diff --git a/grammars/silver/core/Origins.sv b/grammars/silver/core/Origins.sv index f86eef682..631e53927 100644 --- a/grammars/silver/core/Origins.sv +++ b/grammars/silver/core/Origins.sv @@ -143,85 +143,58 @@ top::OriginNote ::= attributeName::String sourceGrammar::String prod::String nt: @{- - Compute the 'chain' of origins leading back to whatever the first thing without an origin (really without - an origin that has an `origin` field.) -} -function getOriginInfoChain -[OriginInfo] ::= l::a -{ - return case getOriginInfo(l) of - | just(info) -> - case info of - | originOriginInfo(o, _) -> info :: getOriginInfoChain(o) - | originAndRedexOriginInfo(o, _, _, _) -> info :: getOriginInfoChain(o) - | _ -> [info] - end - | _ -> [] - end; -} +fun getOriginInfoChain [OriginInfo] ::= l::a = + case getOriginInfo(l) of + | just(info) -> + case info of + | originOriginInfo(o, _) -> info :: getOriginInfoChain(o) + | originAndRedexOriginInfo(o, _, _, _) -> info :: getOriginInfoChain(o) + | _ -> [info] + end + | _ -> [] + end; @{- Low level accessor for getting OriginInfo (maybe) from a node. -} -function getOriginInfo -Maybe ::= arg::a -{ - return javaGetOrigin(arg); -} +fun getOriginInfo Maybe ::= arg::a = javaGetOrigin(arg); @{- Walk back to the first thing with an origin in the history of `a`. -} -function getUrOrigin -Maybe ::= arg::a -{ - return case getOriginInfoChain(arg) of - | [] -> nothing() - | l -> just(last(l)) - end; -} +fun getUrOrigin Maybe ::= arg::a = + case getOriginInfoChain(arg) of + | [] -> nothing() + | l -> just(last(l)) + end; @{- Try to walk back to a parsedOriginInfo and extract the location the node came from in the source -} -function getParsedOriginLocation -Maybe ::= arg::a -{ - return getParsedOriginLocationFromChain(getOriginInfoChain(arg)); -} - -function getParsedOriginLocationFromChain -Maybe ::= chain::[OriginInfo] -{ - return case chain of - | [] -> nothing() - | link::rest -> - case link of - | parsedOriginInfo(l) -> just(l) - | other -> case getParsedOriginLocation_findLogicalLocationNote(other.originNotes) of - | nothing() -> getParsedOriginLocationFromChain(rest) - | x -> x - end - end - end; -} +fun getParsedOriginLocation Maybe ::= arg::a = + getParsedOriginLocationFromChain(getOriginInfoChain(arg)); + +fun getParsedOriginLocationFromChain Maybe ::= chain::[OriginInfo] = + case chain of + | [] -> nothing() + | link::rest -> + case link of + | parsedOriginInfo(l) -> just(l) + | other -> case getParsedOriginLocation_findLogicalLocationNote(other.originNotes) of + | nothing() -> getParsedOriginLocationFromChain(rest) + | x -> x + end + end + end; @{- @hide -} -function getParsedOriginLocation_findLogicalLocationNote -Maybe ::= notes::[OriginNote] -{ - return case notes of - | [] -> nothing() - | logicalLocationNote(l)::_ -> just(l) - | x::r -> getParsedOriginLocation_findLogicalLocationNote(r) - end; -} +fun getParsedOriginLocation_findLogicalLocationNote Maybe ::= notes::[OriginNote] = + case notes of + | [] -> nothing() + | logicalLocationNote(l)::_ -> just(l) + | x::r -> getParsedOriginLocation_findLogicalLocationNote(r) + end; -function originNotesToString -String ::= ns::[OriginNote] -{ - return implode(", ", filterMap((.notepp), ns)); -} +fun originNotesToString String ::= ns::[OriginNote] = implode(", ", filterMap((.notepp), ns)); -function getOriginNotesString -String ::= arg::a -{ - return - case getOriginInfo(arg) of - | just(oi) -> originNotesToString(oi.originNotes) - | nothing() -> "" - end; -} +fun getOriginNotesString String ::= arg::a = + case getOriginInfo(arg) of + | just(oi) -> originNotesToString(oi.originNotes) + | nothing() -> "" + end; @{- - Dump out two objects in a format for svdraw2 to consume and draw their @@ -229,15 +202,12 @@ String ::= arg::a - objects. The only difference between `start` and `stop` is that they will - be specially colored in the visualization diagram.) -} -function printObjectPairForOriginsViz -IOToken ::= start::a stop::b io::IOToken -{ - return printT( +fun printObjectPairForOriginsViz IOToken ::= start::a stop::b io::IOToken = + printT( "\n\n\n---SVDRAW2 START---" ++ "\n" ++ sexprify(start) ++ "\n" ++ sexprify(stop) ++ "\n" ++ "---SVDRAW2 END---\n\n\n", io); -} @{- @hide -} function sexprify @@ -276,11 +246,8 @@ top::AmbientOriginNT ::= } @{- Call fn in a context where notes have been added to the origins context -} -function callWithListOfNotes -a ::= notes::[OriginNote] fn::(a::=) -{ - return case notes of - | [] -> fn() - | x::xs -> attachNote x on callWithListOfNotes(xs, fn) end - end; -} +fun callWithListOfNotes a ::= notes::[OriginNote] fn::(a::=) = + case notes of + | [] -> fn() + | x::xs -> attachNote x on callWithListOfNotes(xs, fn) end + end; diff --git a/grammars/silver/core/Pair.sv b/grammars/silver/core/Pair.sv index b0e6ce0bb..83f4d9749 100644 --- a/grammars/silver/core/Pair.sv +++ b/grammars/silver/core/Pair.sv @@ -10,13 +10,8 @@ data Pair = pair with fst, snd; derive Eq, Ord on Pair; -function fst -a ::= p::Pair -{ return p.fst; } - -function snd -b ::= p::Pair -{ return p.snd; } +global fst :: (a ::= Pair) = (.fst); +global snd :: (b ::= Pair) = (.snd); @{-- - Look up an element in an association list, using the specified equality @@ -28,15 +23,12 @@ b ::= p::Pair - @return The first association pair found in the list, where the element - equaled the first element of the pair. -} -function lookupBy -Maybe ::= eqf::(Boolean ::= a a) elem::a lst::[Pair] -{ - return if null(lst) - then nothing() - else if eqf(elem, head(lst).fst) - then just(head(lst).snd) - else lookupBy(eqf, elem, tail(lst)); -} +fun lookupBy Maybe ::= eqf::(Boolean ::= a a) elem::a lst::[Pair] = + if null(lst) + then nothing() + else if eqf(elem, head(lst).fst) + then just(head(lst).snd) + else lookupBy(eqf, elem, tail(lst)); @{-- - Look up an element in an association list, using ==. @@ -46,27 +38,16 @@ Maybe ::= eqf::(Boolean ::= a a) elem::a lst::[Pair] - @return The first association pair found in the list, where the element - equaled the first element of the pair. -} -function lookup -Eq a => Maybe ::= elem::a lst::[Pair] -{ - return lookupBy(eq, elem, lst); -} +fun lookup Eq a => Maybe ::= elem::a lst::[Pair] = lookupBy(eq, elem, lst); -function lookupAllBy -[b] ::= eqf::(Boolean ::= a a) elem::a lst::[Pair] -{ - return if null(lst) - then [] - else if eqf(elem, head(lst).fst) - then head(lst).snd :: lookupAllBy(eqf, elem, tail(lst)) - else lookupAllBy(eqf, elem, tail(lst)); -} +fun lookupAllBy [b] ::= eqf::(Boolean ::= a a) elem::a lst::[Pair] = + if null(lst) + then [] + else if eqf(elem, head(lst).fst) + then head(lst).snd :: lookupAllBy(eqf, elem, tail(lst)) + else lookupAllBy(eqf, elem, tail(lst)); -function lookupAll -Eq a => [b] ::= elem::a lst::[Pair] -{ - return lookupAllBy(eq, elem, lst); -} +fun lookupAll Eq a => [b] ::= elem::a lst::[Pair] = lookupAllBy(eq, elem, lst); @{-- - Decomposes a list of pairs into a pair of lists. diff --git a/grammars/silver/core/ParseResult.sv b/grammars/silver/core/ParseResult.sv index fcf445c79..e4b54d9d1 100644 --- a/grammars/silver/core/ParseResult.sv +++ b/grammars/silver/core/ParseResult.sv @@ -74,11 +74,8 @@ top::ParseResult ::= t::a terminals::[TerminalDescriptor] - @param pr The ParseResult returned by the parser - @return The syntax tree reported by the parser. Does not return if parsing fails. -} -function parseTreeOrDieWithoutStackTrace -a ::= pr::ParseResult -{ - return unsafeTrace(pr.parseTree, if pr.parseSuccess then unsafeIO() else exitT(-1, printT(pr.parseErrors ++ "\n\n", unsafeIO()))); -} +fun parseTreeOrDieWithoutStackTrace a ::= pr::ParseResult = + unsafeTrace(pr.parseTree, if pr.parseSuccess then unsafeIO() else exitT(-1, printT(pr.parseErrors ++ "\n\n", unsafeIO()))); @{-- diff --git a/grammars/silver/core/Ring.sv b/grammars/silver/core/Ring.sv index f878d0a18..1a66e46b2 100644 --- a/grammars/silver/core/Ring.sv +++ b/grammars/silver/core/Ring.sv @@ -59,12 +59,8 @@ Float ::= a::Float } @{- Converts an integer into an arbitrary ring. -} -function fromInteger -Ring a => a ::= n::Integer -{ - return - if n < 0 then - negate(fromNonnegativeInteger(-n)) - else - fromNonnegativeInteger(n); -} +fun fromInteger Ring a => a ::= n::Integer = + if n < 0 then + negate(fromNonnegativeInteger(-n)) + else + fromNonnegativeInteger(n); diff --git a/grammars/silver/core/String.sv b/grammars/silver/core/String.sv index 78babe358..03e6531f8 100644 --- a/grammars/silver/core/String.sv +++ b/grammars/silver/core/String.sv @@ -25,15 +25,12 @@ Integer ::= s::String - @param lst The list of string to collapse. - @return The combined string. -} -function implode -String ::= sep::String lst::[String] -{ - return if null(lst) - then "" - else head(lst) ++ if null(tail(lst)) - then "" - else sep ++ implode(sep, tail(lst)); -} +fun implode String ::= sep::String lst::[String] = + if null(lst) + then "" + else head(lst) ++ if null(tail(lst)) + then "" + else sep ++ implode(sep, tail(lst)); @{-- - Split a string into a list of strings by a separator. If the separtor @@ -43,13 +40,10 @@ String ::= sep::String lst::[String] - @param str The original string. - @return The list of strings separated by sep in the original string. -} -function explode -[String] ::= sep::String str::String -{ - return if sep=="" then explodeSingle(str) - else if str == "" then [] - else explodeNormal(sep, str); -} +fun explode [String] ::= sep::String str::String = + if sep=="" then explodeSingle(str) + else if str == "" then [] + else explodeNormal(sep, str); function explodeNormal -- do not use [String] ::= sep::String str::String { @@ -61,14 +55,11 @@ function explodeNormal -- do not use else substring(0, i, str) :: explodeNormal(sep, substring(i+length(sep), length(str), str)); } -function explodeSingle -- do not use -[String] ::= str::String -{ - return if length(str) == 0 - then [] - else substring(0,1,str) :: - explodeSingle (substring(1,length(str),str)); -} +fun explodeSingle [String] ::= str::String = + if length(str) == 0 + then [] + else substring(0,1,str) :: + explodeSingle (substring(1,length(str),str)); @{-- - Find the index of a needle in the haystack. (Indices are 0-based.) @@ -368,9 +359,7 @@ function stripExtraWhiteSpaceHelper @{-- - Strips all whitespace from a string. -} -function stripWhiteSpace -String ::= s::String -{ return implode ("", stripWhiteSpaceHelper(explode("",s))) ; } +fun stripWhiteSpace String ::= s::String = implode ("", stripWhiteSpaceHelper(explode("",s))); function stripWhiteSpaceHelper [String] ::= ss::[String] diff --git a/grammars/silver/core/TerminalId.sv b/grammars/silver/core/TerminalId.sv index 5184e2835..85ca1d564 100644 --- a/grammars/silver/core/TerminalId.sv +++ b/grammars/silver/core/TerminalId.sv @@ -1,15 +1,9 @@ grammar silver:core; -- TODO: Should these be generic list functions? -function terminalSetEq -Boolean ::= ts1::[TerminalId] ts2::[TerminalId] -{ - return length(ts1) == length(ts2) && all(zipWith(eq, sort(ts1), sort(ts2))); -} +fun terminalSetEq Boolean ::= ts1::[TerminalId] ts2::[TerminalId] = + length(ts1) == length(ts2) && all(zipWith(eq, sort(ts1), sort(ts2))); -function terminalSubset -Boolean ::= ts1::[TerminalId] ts2::[TerminalId] -{ +fun terminalSubset Boolean ::= ts1::[TerminalId] ts2::[TerminalId] = -- Probably more efficient than sorting if ts1 is small? - return all(map(contains(_, ts2), ts1)); -} + all(map(contains(_, ts2), ts1)); diff --git a/grammars/silver/langutil/Message.sv b/grammars/silver/langutil/Message.sv index 05f00e8ea..0509b224e 100644 --- a/grammars/silver/langutil/Message.sv +++ b/grammars/silver/langutil/Message.sv @@ -62,11 +62,7 @@ top::Message ::= l::Location m::String top.severity = 2; } -function errFromOrigin -Message ::= a::a m::String -{ - return err(getParsedOriginLocationOrFallback(a), m); -} +fun errFromOrigin Message ::= a::a m::String = err(getParsedOriginLocationOrFallback(a), m); @{-- - A warning that is not required to halt compilation before translation @@ -80,11 +76,7 @@ top::Message ::= l::Location m::String top.severity = 1; } -function wrnFromOrigin -Message ::= a::a m::String -{ - return wrn(getParsedOriginLocationOrFallback(a), m); -} +fun wrnFromOrigin Message ::= a::a m::String = wrn(getParsedOriginLocationOrFallback(a), m); @{-- - An informational message that does not halt compilation, but is usually @@ -98,11 +90,7 @@ top::Message ::= l::Location m::String top.severity = 0; } -function infoFromOrigin -Message ::= a::a m::String -{ - return info(getParsedOriginLocationOrFallback(a), m); -} +fun infoFromOrigin Message ::= a::a m::String = info(getParsedOriginLocationOrFallback(a), m); @{-- - A group of messages. @@ -162,17 +150,10 @@ String ::= m::Message @{-- - Returns a list of strings, ready to be printed to the command line. -} -function messagesToString -String ::= msgs::[Message] -{ - return implode("\n", map(showMessage, sortBy(messageLte, msgs))); -} +fun messagesToString String ::= msgs::[Message] = + implode("\n", map(showMessage, sortBy(messageLte, msgs))); -- for use with sortBy -- not an instance of Eq/Ord for now, does it really make sense to compare messages for equality? -function messageLte -Boolean ::= m1::Message m2::Message -{ - return m1.where <= m2.where; -} +fun messageLte Boolean ::= m1::Message m2::Message = m1.where <= m2.where; diff --git a/grammars/silver/langutil/Origins.sv b/grammars/silver/langutil/Origins.sv index 05ee9585a..f499c5611 100644 --- a/grammars/silver/langutil/Origins.sv +++ b/grammars/silver/langutil/Origins.sv @@ -113,11 +113,8 @@ top::OriginInfo ::= origin :: a top.pp = pp"${genericPP(origin)}${constructionNote}${originNotesPP(top.originNotes)}, redex ${genericPP(redex)}${originNotesPP(redexNotes)}"; } -function originNotesPP -Document ::= ns::[OriginNote] -{ - return if null(ns) then pp"" else pp": ${text(originNotesToString(ns))}"; -} +fun originNotesPP Document ::= ns::[OriginNote] = + if null(ns) then pp"" else pp": ${text(originNotesToString(ns))}"; @{- - This note can be attached to indicate that code is generated by an extension, @@ -134,54 +131,38 @@ top::OriginNote ::= extName::String - Try to walk back to a parsedOriginInfo and extract the location the node came from in the source, - giving diagnostic garbage if failed. -} -function getParsedOriginLocationOrFallback -Location ::= arg::a -{ - return - case getParsedOriginLocationFromChain(getOriginInfoChain(arg)) of - | just(l) -> l - | _ -> txtLoc("") - end; -} +fun getParsedOriginLocationOrFallback Location ::= arg::a = + case getParsedOriginLocationFromChain(getOriginInfoChain(arg)) of + | just(l) -> l + | _ -> txtLoc("") + end; @{- - Render the origin chain for a term as a human-readable string. -} -function showOriginInfoChain -String ::= arg::a -{ - return show(80, ppImplode(pp"${line()} -> ", genericPP(arg) :: map((.pp), getOriginInfoChain(arg)))); -} +fun showOriginInfoChain String ::= arg::a = + show(80, ppImplode(pp"${line()} -> ", genericPP(arg) :: map((.pp), getOriginInfoChain(arg)))); @{- - Shorthand for note specifying logical location as some object's origin -} -function logicalLocationFromOrigin -OriginNote ::= arg::a -{ - return logicalLocationNote(getParsedOriginLocationOrFallback(arg)); -} +fun logicalLocationFromOrigin OriginNote ::= arg::a = + logicalLocationNote(getParsedOriginLocationOrFallback(arg)); @{- - Walk back an orgin chain to determine if an object was generated by an extension. -} -function originatesInExt -Maybe ::= chain::[OriginInfo] -{ - return case chain of - | [] -> nothing() - | link::rest -> - orElse(findExtensionGeneratedNote(link.originNotes), - originatesInExt(rest)) - end; -} - -function findExtensionGeneratedNote -Maybe ::= notes::[OriginNote] -{ - return case notes of - | [] -> nothing() - | extensionGenerated(l)::_ -> just(l) - | x::r -> findExtensionGeneratedNote(r) - end; -} +fun originatesInExt Maybe ::= chain::[OriginInfo] = + case chain of + | [] -> nothing() + | link::rest -> + orElse(findExtensionGeneratedNote(link.originNotes), + originatesInExt(rest)) + end; + +fun findExtensionGeneratedNote Maybe ::= notes::[OriginNote] = + case notes of + | [] -> nothing() + | extensionGenerated(l)::_ -> just(l) + | x::r -> findExtensionGeneratedNote(r) + end; diff --git a/grammars/silver/langutil/pp/Document.sv b/grammars/silver/langutil/pp/Document.sv index cf388404f..d350054f9 100644 --- a/grammars/silver/langutil/pp/Document.sv +++ b/grammars/silver/langutil/pp/Document.sv @@ -31,106 +31,55 @@ instance Monoid Document { @{-- - Concatenates a list of fragments into one fragment. -} -function ppConcat -Document ::= ds::[Document] -{ - return if null(ds) then notext() - else foldl(cat, head(ds), tail(ds)); -} +fun ppConcat Document ::= ds::[Document] = + if null(ds) then notext() + else foldl(cat, head(ds), tail(ds)); @{-- - Intersperse a separator fragment between a list of fragments. - e.g. implode(text(", "), list) -} -function ppImplode -Document ::= sep::Document ds::[Document] -{ - return if null(ds) then notext() - else if null(tail(ds)) then head(ds) - else cat(cat(head(ds), sep), ppImplode(sep, tail(ds))); -} +fun ppImplode Document ::= sep::Document ds::[Document] = + if null(ds) then notext() + else if null(tail(ds)) then head(ds) + else cat(cat(head(ds), sep), ppImplode(sep, tail(ds))); @{-- - Introduce a separator fragment after every element of a list of fragments. - Including the last. -} -function terminate -Document ::= sep::Document ds::[Document] -{ - return if null(ds) - then notext() - else cat(cat(head(ds), sep), terminate(sep, tail(ds))); -} +fun terminate Document ::= sep::Document ds::[Document] = + if null(ds) + then notext() + else cat(cat(head(ds), sep), terminate(sep, tail(ds))); @{-- - Introduce a separator fragment before every element of a list of fragments. - Including the first. -} -function initiate -Document ::= sep::Document ds::[Document] -{ - return if null(ds) - then notext() - else cat(cat(sep, head(ds)), initiate(sep, tail(ds))); -} +fun initiate Document ::= sep::Document ds::[Document] = + if null(ds) + then notext() + else cat(cat(sep, head(ds)), initiate(sep, tail(ds))); @{-- - Insert lines before and after the inner fragment, with proper nesting. - (That is, usually you want the first line inside the nest, but the second - OUTSIDE the nest.) -} -function nestlines -Document ::= n::Integer inner::Document -{ - return cat(nest(n, cat(line(), inner)), line()); -} -function groupnest -Document ::= n::Integer inner::Document -{ - return group(nest(n, inner)); -} -function groupnestlines -Document ::= n::Integer inner::Document -{ - return group(cat(nest(n, cat(line(), inner)), line())); -} -function softbreak -Document ::= -{ - return group(line()); -} +fun nestlines Document ::= n::Integer inner::Document = cat(nest(n, cat(line(), inner)), line()); +fun groupnest Document ::= n::Integer inner::Document = group(nest(n, inner)); +fun groupnestlines Document ::= n::Integer inner::Document = + group(cat(nest(n, cat(line(), inner)), line())); +fun softbreak Document ::= = group(line()); -- TODO: consider these "helpers" deprecated -function space -Document ::= -{ - return text(" "); -} -function semi -Document ::= -{ - return text(";"); -} -function comma -Document ::= -{ - return text(","); -} -function braces -Document ::= d::Document -{ - return cat(cat(text("{"), d), text("}")); -} -function parens -Document ::= d::Document -{ - return cat(cat(text("("), d), text(")")); -} -function brackets -Document ::= d::Document -{ - return cat(cat(text("["), d), text("]")); -} +fun space Document ::= = text(" "); +fun semi Document ::= = text(";"); +fun comma Document ::= = text(","); +fun braces Document ::= d::Document = cat(cat(text("{"), d), text("}")); +fun parens Document ::= d::Document = cat(cat(text("("), d), text(")")); +fun brackets Document ::= d::Document = cat(cat(text("["), d), text("]")); @@{- Below this line: text Document ::= String diff --git a/grammars/silver/langutil/unparse/Unparse.sv b/grammars/silver/langutil/unparse/Unparse.sv index 6e6a7e081..3bbaa0692 100644 --- a/grammars/silver/langutil/unparse/Unparse.sv +++ b/grammars/silver/langutil/unparse/Unparse.sv @@ -68,17 +68,13 @@ Document ::= origText::String tree::a return ast.unparseWithLayout; } -function getParseTree -AST ::= ast::a -{ - return - case getOriginInfo(ast) of - | just(parsedOriginInfo(l)) -> reflect(ast) - | just(originOriginInfo(o, _)) -> getParseTree(o) - | just(originAndRedexOriginInfo(o, _, _, _)) -> getParseTree(o) - | _ -> error("Tree does not have a parsed origin: " ++ showOriginInfoChain(ast)) - end; -} +fun getParseTree AST ::= ast::a = + case getOriginInfo(ast) of + | just(parsedOriginInfo(l)) -> reflect(ast) + | just(originOriginInfo(o, _)) -> getParseTree(o) + | just(originAndRedexOriginInfo(o, _, _, _)) -> getParseTree(o) + | _ -> error("Tree does not have a parsed origin: " ++ showOriginInfoChain(ast)) + end; -- Attributes computed on parseTree inherited attribute origText::String occurs on AST, ASTs; diff --git a/grammars/silver/reflect/Util.sv b/grammars/silver/reflect/Util.sv index 342ae837d..67a358d33 100644 --- a/grammars/silver/reflect/Util.sv +++ b/grammars/silver/reflect/Util.sv @@ -5,11 +5,7 @@ exports silver:reflect:util; imports silver:reflect:concretesyntax; import silver:langutil; -function serialize -Either ::= x::a -{ - return reflect(x).serialize; -} +fun serialize Either ::= x::a = reflect(x).serialize; parser astParser :: AST_c { silver:reflect:concretesyntax; @@ -29,8 +25,5 @@ Either ::= fileName::String text::String else right(parseTree.ast); } -function deserialize -runtimeTypeable a => Either ::= fileName::String text::String -{ - return bind(deserializeAST(fileName, text), reify); -} +fun deserialize runtimeTypeable a => Either ::= fileName::String text::String = + bind(deserializeAST(fileName, text), reify); diff --git a/grammars/silver/reflect/util/Util.sv b/grammars/silver/reflect/util/Util.sv index 3ef3d5d27..7040cdaba 100644 --- a/grammars/silver/reflect/util/Util.sv +++ b/grammars/silver/reflect/util/Util.sv @@ -42,15 +42,11 @@ Either ::= fn::AST args::[Maybe] namedArgs::[Pair a ::= x::AST -{ - return - case reify(x) of - | left(msg) -> error(msg) - | right(a) -> a - end; -} +fun reifyUnchecked runtimeTypeable a => a ::= x::AST = + case reify(x) of + | left(msg) -> error(msg) + | right(a) -> a + end; -- TODO: We could add lazy versions of these, if needed. diff --git a/grammars/silver/regex/AbstractSyntax.sv b/grammars/silver/regex/AbstractSyntax.sv index 364282d06..e71f8ef7d 100644 --- a/grammars/silver/regex/AbstractSyntax.sv +++ b/grammars/silver/regex/AbstractSyntax.sv @@ -124,38 +124,26 @@ top::Regex ::= r::Regex - Returns a regex that matches a string literal. - (i.e. no interpretation of special characters.) -} -function regexLiteral -Regex ::= s::String -{ - return - if s == "" then epsilon() - else foldr1(seq, map(char, stringToChars(s))); -} - -function escapeRegexChar -Document ::= char::String -{ - return - case char of - | "+" -> pp"\\+" - | "*" -> pp"\\*" - | "?" -> pp"\\?" - | "|" -> pp"\\|" - | "[" -> pp"\\[" - | "(" -> pp"\\(" - | ")" -> pp"\\)" - | "." -> pp"\\." - | _ -> text(escapeString(char)) - end; -} - -function escapeRegexClassChar -Document ::= char::String -{ - return - case char of - | "-" -> pp"\\-" - | "]" -> pp"\\]" - | _ -> text(escapeString(char)) - end; -} +fun regexLiteral Regex ::= s::String = + if s == "" then epsilon() + else foldr1(seq, map(char, stringToChars(s))); + +fun escapeRegexChar Document ::= char::String = + case char of + | "+" -> pp"\\+" + | "*" -> pp"\\*" + | "?" -> pp"\\?" + | "|" -> pp"\\|" + | "[" -> pp"\\[" + | "(" -> pp"\\(" + | ")" -> pp"\\)" + | "." -> pp"\\." + | _ -> text(escapeString(char)) + end; + +fun escapeRegexClassChar Document ::= char::String = + case char of + | "-" -> pp"\\-" + | "]" -> pp"\\]" + | _ -> text(escapeString(char)) + end; diff --git a/grammars/silver/regex/Matching.sv b/grammars/silver/regex/Matching.sv index 85b03bbba..45a4a6e33 100644 --- a/grammars/silver/regex/Matching.sv +++ b/grammars/silver/regex/Matching.sv @@ -32,11 +32,7 @@ Regex ::= r::Regex c::Integer return r.simplDeriv; } -function matches -Boolean ::= r::Regex s::String -{ - return foldl(matchStep, r, stringToChars(s)).nullable; -} +fun matches Boolean ::= r::Regex s::String = foldl(matchStep, r, stringToChars(s)).nullable; propagate simpl, simplDeriv on Regex; diff --git a/grammars/silver/rewrite/Strategy.sv b/grammars/silver/rewrite/Strategy.sv index 973cb1436..3df429f60 100644 --- a/grammars/silver/rewrite/Strategy.sv +++ b/grammars/silver/rewrite/Strategy.sv @@ -6,11 +6,8 @@ grammar silver:rewrite; imports silver:core hiding all, fail, id, one, repeat, sequence; -function rewriteWith -runtimeTypeable a => Maybe ::= s::Strategy x::a -{ - return map(reifyUnchecked, decorate s with {term = reflect(x);}.result); -} +fun rewriteWith runtimeTypeable a => Maybe ::= s::Strategy x::a = + map(reifyUnchecked, decorate s with {term = reflect(x);}.result); inherited attribute term::AST; synthesized attribute result::Maybe; diff --git a/grammars/silver/util/deque/Deque.sv b/grammars/silver/util/deque/Deque.sv index 315136e1a..aeaa2155d 100644 --- a/grammars/silver/util/deque/Deque.sv +++ b/grammars/silver/util/deque/Deque.sv @@ -10,11 +10,7 @@ abstract production deque top::Deque ::= ln::Integer l::[a] rn::Integer r::[a] {} -function empty -Deque ::= -{ - return deque(0, [], 0, []); -} +fun empty Deque ::= = deque(0, [], 0, []); function cons Deque ::= e::a q::Deque diff --git a/grammars/silver/util/graph/Graph.sv b/grammars/silver/util/graph/Graph.sv index 22e565cdf..1002cb211 100644 --- a/grammars/silver/util/graph/Graph.sv +++ b/grammars/silver/util/graph/Graph.sv @@ -11,11 +11,7 @@ type Graph foreign = "java.util.TreeMap>"; @{-- - Returns an empty graph using Ord for comparison. -} -function empty -Ord a => Graph ::= -{ - return emptyWith(compare); -} +fun empty Ord a => Graph ::= = emptyWith(compare); @{-- - Returns an empty graph using the specified vertex comparator. diff --git a/grammars/silver/util/random/Util.sv b/grammars/silver/util/random/Util.sv index ad26e5246..e2699fcfa 100644 --- a/grammars/silver/util/random/Util.sv +++ b/grammars/silver/util/random/Util.sv @@ -6,19 +6,15 @@ Randomly shuffle the elements of a list. @param elems The list to shuffle. @return A RandomGen monadic action to shuffle the list. -} -function randomShuffle -RandomGen<[a]> ::= elems::[a] -{ - return - if null(elems) then pure([]) - else do { - i :: Integer <- randomRange(0, length(elems) - 1); - let hd :: [a] = take(i, elems); - let tl :: [a] = drop(i, elems); - rest :: [a] <- randomShuffle(hd ++ tail(tl)); - return head(tl) :: rest; - }; -} +fun randomShuffle RandomGen<[a]> ::= elems::[a] = + if null(elems) then pure([]) + else do { + i :: Integer <- randomRange(0, length(elems) - 1); + let hd :: [a] = take(i, elems); + let tl :: [a] = drop(i, elems); + rest :: [a] <- randomShuffle(hd ++ tail(tl)); + return head(tl) :: rest; + }; @{-- Select a random element from a non-empty list. @@ -27,15 +23,12 @@ An error is raised when the list is empty. @param elems The list from which to select an element. @return A RandomGen monadic action to select an element from the list. -} -function randomElem -RandomGen ::= elems::[a] -{ - return if null(elems) then error("randomElem of empty list!") else +fun randomElem RandomGen ::= elems::[a] = + if null(elems) then error("randomElem of empty list!") else do { i :: Integer <- randomRange(0, length(elems) - 1); return head(drop(i, elems)); }; -} @{-- @@ -45,7 +38,7 @@ Example: thread randomIn, randomOut on top, foo, top; local fooVal::Integer = foo.randomValue; -} -nonterminal RandomVal with randomIn, randomOut, randomValue; + nonterminal RandomVal with randomIn, randomOut, randomValue; synthesized attribute randomValue::a; diff --git a/grammars/silver/util/treemap/TreeMap.sv b/grammars/silver/util/treemap/TreeMap.sv index 34d14fcf2..fafbdee43 100644 --- a/grammars/silver/util/treemap/TreeMap.sv +++ b/grammars/silver/util/treemap/TreeMap.sv @@ -10,11 +10,7 @@ type Map foreign = "java.util.TreeMap"; @{-- - Returns a new, empty, multimap using Ord for comparison. -} -function empty -Ord a => Map ::= -{ - return emptyWith(compare); -} +fun empty Ord a => Map ::= = emptyWith(compare); @{-- - Returns a new, empty, multimap using the specified comparator. @@ -65,11 +61,7 @@ function lookup @{-- - Converts a list of pairs to a multimap. -} -function fromList -Ord a => Map ::= l::[Pair] -{ - return add(l, empty()); -} +fun fromList Ord a => Map ::= l::[Pair] = add(l, empty()); @{-- - Converts a multimap back to a list of pairs, in sorted order by key. diff --git a/grammars/silver/util/treeset/TreeSet.sv b/grammars/silver/util/treeset/TreeSet.sv index 5700a354d..d5cb1a35a 100644 --- a/grammars/silver/util/treeset/TreeSet.sv +++ b/grammars/silver/util/treeset/TreeSet.sv @@ -10,11 +10,7 @@ type Set foreign = "java.util.TreeSet"; @{-- - Returns a new, empty, set using Ord for comparison. -} -function empty -Ord a => Set ::= -{ - return emptyWith(compare); -} +fun empty Ord a => Set ::= = emptyWith(compare); @{-- - Returns a new, empty, set using the specified comparator. @@ -43,11 +39,7 @@ Set ::= lst::[a] set::Set @{-- - Converts a list to a set. -} -function fromList -Ord a => Set ::= lst::[a] -{ - return add(lst, empty()); -} +fun fromList Ord a => Set ::= lst::[a] = add(lst, empty()); @{-- - Converts a set back to a list, in sorted order. From 8f3d61759060192a465ba536e8ea29027b9af177 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 20 Nov 2023 18:26:55 -0600 Subject: [PATCH 162/283] Revert some problematic concise functions --- .../analysis/warnings/flow/MwdaFlag.sv | 8 ++++--- grammars/silver/core/Origins.sv | 21 ++++++++++++------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/grammars/silver/compiler/analysis/warnings/flow/MwdaFlag.sv b/grammars/silver/compiler/analysis/warnings/flow/MwdaFlag.sv index 7d6ffb62d..5a94536b5 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/MwdaFlag.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/MwdaFlag.sv @@ -44,10 +44,12 @@ fun mwdaWrn Message ::= config::Decorated CmdArgs l::Location m::String = then err(l, m) else wrn(l, m); -fun mwdaWrnFromOrigin +function mwdaWrnFromOrigin attribute config occurs on a => -Message ::= a::Decorated a with {config} m::String = - mwdaWrn(a.config, getParsedOriginLocationOrFallback(a), m); +Message ::= a::Decorated a with {config} m::String +{ + return mwdaWrn(a.config, getParsedOriginLocationOrFallback(a), m); +} fun mwdaWrnAmbientOrigin Message ::= config::Decorated CmdArgs m::String = mwdaWrn(config, getParsedOriginLocationOrFallback(ambientOrigin()), m); diff --git a/grammars/silver/core/Origins.sv b/grammars/silver/core/Origins.sv index 631e53927..aeb380509 100644 --- a/grammars/silver/core/Origins.sv +++ b/grammars/silver/core/Origins.sv @@ -165,8 +165,11 @@ fun getUrOrigin Maybe ::= arg::a = end; @{- Try to walk back to a parsedOriginInfo and extract the location the node came from in the source -} -fun getParsedOriginLocation Maybe ::= arg::a = - getParsedOriginLocationFromChain(getOriginInfoChain(arg)); +function getParsedOriginLocation +Maybe ::= arg::a +{ + return getParsedOriginLocationFromChain(getOriginInfoChain(arg)); +} fun getParsedOriginLocationFromChain Maybe ::= chain::[OriginInfo] = case chain of @@ -190,11 +193,15 @@ fun getParsedOriginLocation_findLogicalLocationNote Maybe ::= notes::[ fun originNotesToString String ::= ns::[OriginNote] = implode(", ", filterMap((.notepp), ns)); -fun getOriginNotesString String ::= arg::a = - case getOriginInfo(arg) of - | just(oi) -> originNotesToString(oi.originNotes) - | nothing() -> "" - end; +function getOriginNotesString +String ::= arg::a +{ + return + case getOriginInfo(arg) of + | just(oi) -> originNotesToString(oi.originNotes) + | nothing() -> "" + end; +} @{- - Dump out two objects in a format for svdraw2 to consume and draw their From 015ae8d14de6d0ddec36e8b4ac05b04485b65e43 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 21 Dec 2023 19:44:56 -0600 Subject: [PATCH 163/283] Remove unused import --- .../silver/compiler/modification/concisefunctions/Project.sv | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/grammars/silver/compiler/modification/concisefunctions/Project.sv b/grammars/silver/compiler/modification/concisefunctions/Project.sv index 492334576..36939dc07 100644 --- a/grammars/silver/compiler/modification/concisefunctions/Project.sv +++ b/grammars/silver/compiler/modification/concisefunctions/Project.sv @@ -1,8 +1,7 @@ grammar silver:compiler:modification:concisefunctions; imports silver:compiler:definition:core; -imports silver:compiler:modification:lambda_fn; -imports silver:compiler:definition:type:syntax hiding Arrow_t; -- We use lambda_fn:Arrow_t +imports silver:compiler:definition:type:syntax; imports silver:compiler:definition:type; imports silver:compiler:definition:env; imports silver:compiler:definition:flow:env; From 17c38cfc79be55aed06ea8a33b64d358a4b89f1c Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 21 Dec 2023 19:53:23 -0600 Subject: [PATCH 164/283] Revert "Revert some problematic concise functions" This reverts commit 8f3d61759060192a465ba536e8ea29027b9af177. --- .../analysis/warnings/flow/MwdaFlag.sv | 8 +++---- grammars/silver/core/Origins.sv | 21 +++++++------------ 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/grammars/silver/compiler/analysis/warnings/flow/MwdaFlag.sv b/grammars/silver/compiler/analysis/warnings/flow/MwdaFlag.sv index 5a94536b5..7d6ffb62d 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/MwdaFlag.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/MwdaFlag.sv @@ -44,12 +44,10 @@ fun mwdaWrn Message ::= config::Decorated CmdArgs l::Location m::String = then err(l, m) else wrn(l, m); -function mwdaWrnFromOrigin +fun mwdaWrnFromOrigin attribute config occurs on a => -Message ::= a::Decorated a with {config} m::String -{ - return mwdaWrn(a.config, getParsedOriginLocationOrFallback(a), m); -} +Message ::= a::Decorated a with {config} m::String = + mwdaWrn(a.config, getParsedOriginLocationOrFallback(a), m); fun mwdaWrnAmbientOrigin Message ::= config::Decorated CmdArgs m::String = mwdaWrn(config, getParsedOriginLocationOrFallback(ambientOrigin()), m); diff --git a/grammars/silver/core/Origins.sv b/grammars/silver/core/Origins.sv index aeb380509..631e53927 100644 --- a/grammars/silver/core/Origins.sv +++ b/grammars/silver/core/Origins.sv @@ -165,11 +165,8 @@ fun getUrOrigin Maybe ::= arg::a = end; @{- Try to walk back to a parsedOriginInfo and extract the location the node came from in the source -} -function getParsedOriginLocation -Maybe ::= arg::a -{ - return getParsedOriginLocationFromChain(getOriginInfoChain(arg)); -} +fun getParsedOriginLocation Maybe ::= arg::a = + getParsedOriginLocationFromChain(getOriginInfoChain(arg)); fun getParsedOriginLocationFromChain Maybe ::= chain::[OriginInfo] = case chain of @@ -193,15 +190,11 @@ fun getParsedOriginLocation_findLogicalLocationNote Maybe ::= notes::[ fun originNotesToString String ::= ns::[OriginNote] = implode(", ", filterMap((.notepp), ns)); -function getOriginNotesString -String ::= arg::a -{ - return - case getOriginInfo(arg) of - | just(oi) -> originNotesToString(oi.originNotes) - | nothing() -> "" - end; -} +fun getOriginNotesString String ::= arg::a = + case getOriginInfo(arg) of + | just(oi) -> originNotesToString(oi.originNotes) + | nothing() -> "" + end; @{- - Dump out two objects in a format for svdraw2 to consume and draw their From 39fb62df3a748d1f9e598e017371fde867b60b76 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 12 Feb 2024 17:35:54 -0600 Subject: [PATCH 165/283] Make PatternVarProjection a data nonterminal --- grammars/silver/compiler/definition/flow/ast/Flow.sv | 6 ++---- .../compiler/definition/flow/driver/ProductionGraph.sv | 7 ++----- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/grammars/silver/compiler/definition/flow/ast/Flow.sv b/grammars/silver/compiler/definition/flow/ast/Flow.sv index bcf1ee146..bb4d884c6 100644 --- a/grammars/silver/compiler/definition/flow/ast/Flow.sv +++ b/grammars/silver/compiler/definition/flow/ast/Flow.sv @@ -391,10 +391,8 @@ top::FlowDef ::= prod::String matchProd::String scrutinee::VertexType vars::[ top.flowEdges = []; } -nonterminal PatternVarProjection; -abstract production patternVarProjection -top::PatternVarProjection ::= child::String typeName::String patternVar::String -{} +data PatternVarProjection + = patternVarProjection child::String typeName::String patternVar::String; {-- - A sub-term with a flow vertex, that has a known decoration site. diff --git a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv index 429c764a6..0e80c7d8f 100644 --- a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv @@ -449,17 +449,14 @@ fun patternStitchPoints [StitchPoint] ::= realEnv::Env defs::[FlowDef] = patternStitchPoints(realEnv, rest) | _ :: rest -> patternStitchPoints(realEnv, rest) end; -function patVarStitchPoints -[StitchPoint] ::= matchProd::String scrutinee::VertexType realEnv::Env var::PatternVarProjection -{ - return case var of +fun patVarStitchPoints [StitchPoint] ::= matchProd::String scrutinee::VertexType realEnv::Env var::PatternVarProjection = + case var of | patternVarProjection(child, typeName, patternVar) -> projectionStitchPoint( matchProd, anonVertexType(patternVar), scrutinee, rhsVertexType(child), getInhAndInhOnTransAttrsOn(typeName, realEnv)) :: nonterminalStitchPoints(realEnv, typeName, anonVertexType(patternVar)) end; -} fun subtermDecSiteStitchPoints [StitchPoint] ::= flowEnv::FlowEnv realEnv::Env defs::[FlowDef] = flatMap(\ d::FlowDef -> case d of From 71c87d8d84afdd4062640a35d95c97e9248c886f Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 29 Feb 2024 10:49:50 -0600 Subject: [PATCH 166/283] Minor cleanup, removing instanceNum --- .../silver/compiler/definition/core/Type.sv | 28 +------------------ 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/grammars/silver/compiler/definition/core/Type.sv b/grammars/silver/compiler/definition/core/Type.sv index 72efe924b..b1bf5b421 100644 --- a/grammars/silver/compiler/definition/core/Type.sv +++ b/grammars/silver/compiler/definition/core/Type.sv @@ -6,25 +6,13 @@ synthesized attribute applicationDispatcher :: (Expr ::= Decorated! Expr Decora -- (See DclInfo for the next step) synthesized attribute accessHandler :: (Expr ::= Decorated! Expr Decorated! QNameAttrOccur); --- Used for poor man's type classes --- TODO: Finish removing these and replace with real type classes -synthesized attribute instanceNum :: Boolean; - -attribute applicationDispatcher, accessHandler, instanceNum occurs on Type; +attribute applicationDispatcher, accessHandler occurs on Type; aspect default production top::Type ::= { top.applicationDispatcher = errorApplication; top.accessHandler = errorAccessHandler; - top.instanceNum = false; -} - -aspect production errorType -top::Type ::= -{ - -- Allow these, to suppress raising additional unnecessary errors. - top.instanceNum = true; } aspect production appType @@ -32,7 +20,6 @@ top::Type ::= c::Type a::Type { top.applicationDispatcher = c.applicationDispatcher; top.accessHandler = c.accessHandler; - top.instanceNum = c.instanceNum; } aspect production skolemType @@ -41,18 +28,6 @@ top::Type ::= _ top.accessHandler = undecoratedAccessHandler; } -aspect production intType -top::Type ::= -{ - top.instanceNum = true; -} - -aspect production floatType -top::Type ::= -{ - top.instanceNum = true; -} - aspect production nonterminalType top::Type ::= fn::String _ data::Boolean _ { @@ -85,4 +60,3 @@ top::Type ::= _ _ { top.applicationDispatcher = functionApplication; } - From ea95a00d9ea6dfba8d8cb64de12d98b591483895 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 6 Mar 2024 16:42:37 -0600 Subject: [PATCH 167/283] Initial support for dispatch signatures --- .../analysis/typechecking/core/AspectDcl.sv | 4 +- .../typechecking/core/ProductionDcl.sv | 20 ++++- .../compiler/analysis/uniqueness/Expr.sv | 7 ++ .../analysis/uniqueness/ProductionBody.sv | 2 +- .../warnings/flow/FlowTypeCopyEquation.sv | 2 +- .../analysis/warnings/flow/MissingSynEq.sv | 2 +- .../warnings/flow/OrphanedProduction.sv | 2 +- .../concrete_syntax/ProductionDcl.sv | 7 +- .../compiler/definition/core/AspectDcl.sv | 7 +- .../compiler/definition/core/DclInfo.sv | 2 +- .../compiler/definition/core/DispatchDcl.sv | 87 +++++++++++++++++++ .../silver/compiler/definition/core/Expr.sv | 12 ++- .../compiler/definition/core/FunctionDcl.sv | 3 +- .../compiler/definition/core/ProductionDcl.sv | 68 ++++++++++++--- .../compiler/definition/core/Terminals.sv | 2 + .../silver/compiler/definition/core/Type.sv | 7 ++ .../silver/compiler/definition/env/DclInfo.sv | 22 ++++- .../silver/compiler/definition/env/Defs.sv | 4 +- .../silver/compiler/definition/env/Env.sv | 12 ++- .../compiler/definition/env/NamedSignature.sv | 10 ++- .../compiler/definition/flow/env/Expr.sv | 14 +++ .../definition/flow/env/ProductionDcl.sv | 8 +- .../definition/type/PrettyPrinting.sv | 6 ++ .../silver/compiler/definition/type/Type.sv | 7 ++ .../compiler/definition/type/Unification.sv | 10 +++ .../silver/compiler/definition/type/Util.sv | 6 ++ .../definition/type/syntax/ProductionDcl.sv | 2 +- .../compiler/extension/autoattr/Inherited.sv | 15 ++-- .../compiler/extension/autoattr/Propagate.sv | 4 +- .../compiler/extension/autoattr/Threaded.sv | 2 + .../extension/convenience/Productions.sv | 4 +- .../silver/compiler/extension/data/DataDcl.sv | 10 ++- .../compiler/extension/doc/core/AGDcl.sv | 11 ++- .../extension/doc/core/DocumentedAGDcl.sv | 2 +- .../extension/implicit_monads/Expr.sv | 14 +++ .../extension/patternmatching/PatternTypes.sv | 2 +- .../extension/testing/EqualityTest.sv | 1 + .../extension/testing/MainTestSuite.sv | 3 +- .../modification/copper/ActionCode.sv | 1 + .../compiler/modification/copper/ParserDcl.sv | 6 +- .../modification/defaultattr/DefaultAttr.sv | 2 +- .../compiler/modification/lambda_fn/Lambda.sv | 2 +- .../primitivepattern/PrimitiveMatch.sv | 4 +- .../modification/primitivepattern/Types.sv | 13 +++ .../primitivepattern/VarBinders.sv | 2 +- .../compiler/translation/java/core/Expr.sv | 16 ++++ .../translation/java/core/NamedSignature.sv | 8 +- .../translation/java/core/ProductionDcl.sv | 2 +- .../compiler/translation/java/type/Type.sv | 8 ++ .../.settings/org.eclipse.jdt.core.prefs | 2 +- 50 files changed, 397 insertions(+), 72 deletions(-) create mode 100644 grammars/silver/compiler/definition/core/DispatchDcl.sv diff --git a/grammars/silver/compiler/analysis/typechecking/core/AspectDcl.sv b/grammars/silver/compiler/analysis/typechecking/core/AspectDcl.sv index b63bc0c39..b938285c1 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/AspectDcl.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/AspectDcl.sv @@ -17,7 +17,7 @@ top::AGDcl ::= 'aspect' 'production' id::QName ns::AspectProductionSignature bod -- dcl is potentially not found, accessing it can crash. -- so check on dcls for this. case id.lookupValue.dcls of - | prodDcl (_, _) :: _ -> [] + | prodDcl (_, _, _) :: _ -> [] | funDcl (_) :: _ -> [errFromOrigin(top, "Production aspect for '" ++ id.name ++ "' should be a 'function' aspect instead.")] | _ -> [errFromOrigin(id, id.name ++ " is not a production.")] end; @@ -43,7 +43,7 @@ top::AGDcl ::= 'aspect' 'function' id::QName ns::AspectFunctionSignature body::P -- must be on dcls because lookup may have failed. case id.lookupValue.dcls of | funDcl (_) :: _ -> [] - | prodDcl (_, _) :: _ -> [errFromOrigin(top, "Function aspect for '" ++ id.name ++ "' should be a 'production' aspect instead.")] + | prodDcl (_, _, _) :: _ -> [errFromOrigin(top, "Function aspect for '" ++ id.name ++ "' should be a 'production' aspect instead.")] | _ -> [errFromOrigin(id, id.name ++ " is not a function.")] end; diff --git a/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv b/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv index bc325a8e1..b4d6a80a7 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv @@ -1,7 +1,7 @@ grammar silver:compiler:analysis:typechecking:core; aspect production productionDcl -top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::ProductionBody +top::AGDcl ::= 'abstract' 'production' id::Name d::ProductionImplements ns::ProductionSignature body::ProductionBody { body.downSubst = emptySubst(); } @@ -15,14 +15,32 @@ top::ProductionLHS ::= id::Name '::' t::TypeExpr checkNT.downSubst = emptySubst(); checkNT.finalSubst = emptySubst(); + local checkImplementedSig::TypeCheck = check(t.typerep, top.implementedSig.fromJust.typerep); + checkImplementedSig.downSubst = emptySubst(); + checkImplementedSig.finalSubst = emptySubst(); + top.errors <- if checkNT.typeerror then [errFromOrigin(top, "Production LHS type must be a nonterminal. Instead it is of type " ++ checkNT.leftpp)] else []; + + top.errors <- + if top.implementedSig.isJust && checkImplementedSig.typeerror + then [errFromOrigin(top, "Production LHS type does not match the type from the implemented dispatch signature, " ++ checkImplementedSig.rightpp ++ ". Instead it is of type " ++ checkImplementedSig.leftpp)] + else []; } aspect production productionRHSElem top::ProductionRHSElem ::= id::Name '::' t::TypeExpr { top.errors <- t.errorsKindStar; + + local checkImplementedSig::TypeCheck = check(t.typerep, top.implementedSig.fromJust.typerep); + checkImplementedSig.downSubst = emptySubst(); + checkImplementedSig.finalSubst = emptySubst(); + + top.errors <- + if top.implementedSig.isJust && checkImplementedSig.typeerror + then [errFromOrigin(top, "Child " ++ id.name ++ " does not match the type from the implemented dispatch signature " ++ checkImplementedSig.rightpp ++ ". Instead it is of type " ++ checkImplementedSig.leftpp)] + else []; } diff --git a/grammars/silver/compiler/analysis/uniqueness/Expr.sv b/grammars/silver/compiler/analysis/uniqueness/Expr.sv index b46a86bee..b80e517e0 100644 --- a/grammars/silver/compiler/analysis/uniqueness/Expr.sv +++ b/grammars/silver/compiler/analysis/uniqueness/Expr.sv @@ -179,6 +179,13 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp end; } +aspect production dispatchApplication +top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +{ + top.errors <- es.appExprUniquenessErrors ++ anns.appExprUniquenessErrors; + es.isNtUniquenessPreserving = true; +} + aspect production annoExpr top::AnnoExpr ::= qn::QName '=' e::AppExpr { diff --git a/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv b/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv index e65862d42..72e23bfa7 100644 --- a/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv +++ b/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv @@ -4,7 +4,7 @@ attribute uniqueRefs occurs on ProductionBody, ProductionStmts, ProductionStmt; propagate uniqueRefs on ProductionBody, ProductionStmts, ProductionStmt; aspect production productionDcl -top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::ProductionBody +top::AGDcl ::= 'abstract' 'production' id::Name d::ProductionImplements ns::ProductionSignature body::ProductionBody { top.errors <- if any(map((.isUniqueDecorated), namedSig.inputTypes)) && null(body.undecorateExpr) diff --git a/grammars/silver/compiler/analysis/warnings/flow/FlowTypeCopyEquation.sv b/grammars/silver/compiler/analysis/warnings/flow/FlowTypeCopyEquation.sv index e63c55b60..73b457368 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/FlowTypeCopyEquation.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/FlowTypeCopyEquation.sv @@ -14,7 +14,7 @@ grammar silver:compiler:analysis:warnings:flow; -- These may be from `options` and so requires the flowEnv. aspect production productionDcl -top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::ProductionBody +top::AGDcl ::= 'abstract' 'production' id::Name d::ProductionImplements ns::ProductionSignature body::ProductionBody { -- oh no again! local myFlow :: EnvTree = head(searchEnvTree(top.grammarName, top.compiledGrammars)).grammarFlowTypes; diff --git a/grammars/silver/compiler/analysis/warnings/flow/MissingSynEq.sv b/grammars/silver/compiler/analysis/warnings/flow/MissingSynEq.sv index f4f63355d..409195691 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/MissingSynEq.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/MissingSynEq.sv @@ -81,7 +81,7 @@ function raiseMissingProds - closer to the location where a fix would be requird. -} aspect production productionDcl -top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::ProductionBody +top::AGDcl ::= 'abstract' 'production' id::Name d::ProductionImplements ns::ProductionSignature body::ProductionBody { -- All locally known synthesized attributes. This does not need to be exhaustive, -- because this error message is a courtesy, not the basis of the analysis. diff --git a/grammars/silver/compiler/analysis/warnings/flow/OrphanedProduction.sv b/grammars/silver/compiler/analysis/warnings/flow/OrphanedProduction.sv index f73327994..ee4925f64 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/OrphanedProduction.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/OrphanedProduction.sv @@ -23,7 +23,7 @@ Either ::= args::[String] } aspect production productionDcl -top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::ProductionBody +top::AGDcl ::= 'abstract' 'production' id::Name d::ProductionImplements ns::ProductionSignature body::ProductionBody { local ntDefGram :: String = substring(0, lastIndexOf(":", namedSig.outputElement.typerep.typeName), namedSig.outputElement.typerep.typeName); diff --git a/grammars/silver/compiler/definition/concrete_syntax/ProductionDcl.sv b/grammars/silver/compiler/definition/concrete_syntax/ProductionDcl.sv index f1e44d344..605aef939 100644 --- a/grammars/silver/compiler/definition/concrete_syntax/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/concrete_syntax/ProductionDcl.sv @@ -14,6 +14,7 @@ top::AGDcl ::= 'concrete' 'production' id::Name ns::ProductionSignature pm::Prod production namedSig :: NamedSignature = ns.namedSignature; ns.signatureName = fName; + ns.implementedSig = nothing(); ns.env = newScopeEnv(ns.defs, top.env); pm.productionSig = ns.namedSignature; pm.env = newScopeEnv(ns.actionDefs, top.env); @@ -27,7 +28,7 @@ top::AGDcl ::= 'concrete' 'production' id::Name ns::ProductionSignature pm::Prod location=getParsedOriginLocationOrFallback(top), sourceGrammar=top.grammarName) ]; - forwards to productionDcl('abstract', $2, id, ns, body); + forwards to productionDcl('abstract', $2, id, productionImplementsNone(), ns, body); } action { insert semantic token IdFnProdDcl_t at id.nameLoc; sigNames = []; @@ -115,7 +116,7 @@ top::ProductionSignature ::= cl::ConstraintList '=>' lhs::ProductionLHS '::=' rh local lhsHasLocation :: Boolean = case top.namedSignature.namedInputElements of - | [namedSignatureElement("silver:core:location", _)] -> true + | [namedSignatureElement("silver:core:location", _, _)] -> true | _ -> false end; local lhsHasOrigin :: Boolean = top.namedSignature.outputElement.typerep.isTracked; @@ -123,7 +124,7 @@ top::ProductionSignature ::= cl::ConstraintList '=>' lhs::ProductionLHS '::=' rh top.concreteSyntaxTypeErrors <- case top.namedSignature.namedInputElements of | [] -> [] - | [namedSignatureElement("silver:core:location", _)] -> [] + | [namedSignatureElement("silver:core:location", _, _)] -> [] | _ -> [errFromOrigin(top, "Annotation(s) on this production are not handleable by the parser generator (only a single annotation, and only silver:core:location is supported.)")] end; diff --git a/grammars/silver/compiler/definition/core/AspectDcl.sv b/grammars/silver/compiler/definition/core/AspectDcl.sv index 330aaf757..001031d5d 100644 --- a/grammars/silver/compiler/definition/core/AspectDcl.sv +++ b/grammars/silver/compiler/definition/core/AspectDcl.sv @@ -197,7 +197,7 @@ top::AspectProductionLHS ::= id::Name t::Type production attribute rType :: Type; rType = if null(top.realSignature) then errorType() else head(top.realSignature).typerep; - top.outputElement = namedSignatureElement(id.name, t); + top.outputElement = namedSignatureElement(id.name, t, false); top.defs := [aliasedLhsDef(top.grammarName, id.nameLoc, fName, performSubstitution(t, top.upSubst), id.name)]; @@ -277,8 +277,9 @@ top::AspectRHSElem ::= id::Name t::Type fName = if null(top.realSignature) then id.name else head(top.realSignature).elementName; production attribute rType :: Type; rType = if null(top.realSignature) then errorType() else head(top.realSignature).typerep; + production shared::Boolean = !null(top.realSignature) && head(top.realSignature).elementShared; - top.inputElements = [namedSignatureElement(id.name, t)]; + top.inputElements = [namedSignatureElement(id.name, t, shared)]; top.defs := [aliasedChildDef(top.grammarName, id.nameLoc, fName, performSubstitution(t, top.upSubst), id.name)]; @@ -316,7 +317,7 @@ top::AspectFunctionLHS ::= t::TypeExpr production attribute rType :: Type; rType = if null(top.realSignature) then errorType() else head(top.realSignature).typerep; - top.outputElement = namedSignatureElement(fName, t.typerep); + top.outputElement = namedSignatureElement(fName, t.typerep, false); -- TODO: this needs thinking. is it broken? maybe __return? or wait, it's doing that automatically isnt it... top.defs := [aliasedLhsDef(top.grammarName, getParsedOriginLocationOrFallback(t), fName, performSubstitution(t.typerep, top.upSubst), fName)]; diff --git a/grammars/silver/compiler/definition/core/DclInfo.sv b/grammars/silver/compiler/definition/core/DclInfo.sv index 0f714696a..73cf9409d 100644 --- a/grammars/silver/compiler/definition/core/DclInfo.sv +++ b/grammars/silver/compiler/definition/core/DclInfo.sv @@ -72,7 +72,7 @@ top::ValueDclInfo ::= fn::String ty::Type _ -- -- interface values aspect production prodDcl -top::ValueDclInfo ::= ns::NamedSignature hasForward::Boolean +top::ValueDclInfo ::= ns::NamedSignature dispatch::Maybe hasForward::Boolean { top.refDispatcher = productionReference; -- Note that we still need production references, even though bug #16 removes the production type. diff --git a/grammars/silver/compiler/definition/core/DispatchDcl.sv b/grammars/silver/compiler/definition/core/DispatchDcl.sv new file mode 100644 index 000000000..77395b8b1 --- /dev/null +++ b/grammars/silver/compiler/definition/core/DispatchDcl.sv @@ -0,0 +1,87 @@ +grammar silver:compiler:definition:core; + +concrete production dispatchSigDcl +top::AGDcl ::= 'dispatch' id::Name '=' sig::DispatchSignature ';' +{ + top.unparse = "dispatch " ++ id.unparse ++ " = " ++ sig.unparse ++ ";"; + + production fName :: String = top.grammarName ++ ":" ++ id.name; + sig.signatureName = fName; + sig.env = newScopeEnv(sig.defs, top.env); + + top.errors <- + if length(getTypeDclAll(fName, top.env)) > 1 + then [errFromOrigin(id, "Type '" ++ fName ++ "' is already bound.")] + else []; + + top.errors <- + if isLower(substring(0,1,id.name)) + then [errFromOrigin(id, "Types must be capitalized. Invalid dispatch name " ++ id.name)] + else []; +} + +nonterminal DispatchSignature with config, grammarName, defs, env, unparse, errors, signatureName, namedSignature; +nonterminal DispatchRHS with config, grammarName, defs, env, unparse, errors, inputElements, elementCount; +nonterminal DispatchRHSElem with config, grammarName, defs, env, unparse, errors, inputElements, deterministicCount; +propagate config, grammarName, defs, env, errors on DispatchSignature, DispatchRHS, DispatchRHSElem; + +concrete production dispatchSignature +top::DispatchSignature ::= lhs::ProductionLHS '::=' rhs::DispatchRHS +{ + top.unparse = lhs.unparse ++ " ::= " ++ rhs.unparse; + top.namedSignature = + namedSignature( + top.signatureName, + nilContext(), + foldNamedSignatureElements(rhs.inputElements), + lhs.outputElement, + foldNamedSignatureElements(annotationsForNonterminal(lhs.outputElement.typerep, top.env))); + lhs.implementedSig = nothing(); +} + +concrete production dispatchRHSNil +top::DispatchRHS ::= +{ + top.unparse = ""; + + top.inputElements = []; + top.elementCount = 0; +} + +concrete production dispatchRHSCons +top::DispatchRHS ::= h::DispatchRHSElem t::DispatchRHS +{ + top.unparse = h.unparse ++ " " ++ t.unparse; + + top.inputElements = h.inputElements ++ t.inputElements; + top.elementCount = 1 + t.elementCount; + h.deterministicCount = t.elementCount; +} + +concrete production dispatchRHSElem +top::DispatchRHSElem ::= ms::MaybeShared id::Name '::' t::TypeExpr +{ + top.unparse = ms.unparse ++ id.unparse ++ "::" ++ t.unparse; + + top.inputElements = [namedSignatureElement(id.name, t.typerep, ms.elementShared)]; + + top.defs <- [childDef(top.grammarName, id.nameLoc, id.name, t.typerep)]; + + top.errors <- + if length(getValueDclInScope(id.name, top.env)) > 1 + then [errFromOrigin(id, "Value '" ++ id.name ++ "' is already bound.")] + else []; +} + +concrete production dispatchRHSElemType +top::DispatchRHSElem ::= ms::MaybeShared t::TypeExpr +{ + top.unparse = t.unparse; + + forwards to dispatchRHSElem(@ms, name("_G_" ++ toString(top.deterministicCount)), '::', @t); +} + +nonterminal MaybeShared with unparse, elementShared; +concrete productions top::MaybeShared +| '@' { top.unparse = "@"; top.elementShared = true; } +| { top.unparse = ""; top.elementShared = false; } diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index 55448a8b2..7db2765de 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -277,7 +277,8 @@ top::Expr ::= e::Expr '(' es::AppExprs ',' anns::AnnoAppExprs ')' -- NOTE: REVERSED ORDER -- We may need to resolve e's type to get at the actual 'function type' - local t :: Type = performSubstitution(e.typerep, e.upSubst); + local t :: Type = asFunctionType(performSubstitution(e.typerep, e.upSubst), top.env); + -- TODO: These should maybe be supplied after forwarding? es.appExprTypereps = reverse(correctNumTypes); es.appExprApplied = e.unparse; anns.appExprApplied = e.unparse; @@ -370,6 +371,15 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp es.missingTypereps ++ anns.partialAnnoTypereps ++ map(snd, anns.missingAnnotations) ++ [ety.outputType]); } +abstract production dispatchApplication +top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +{ + undecorates to application(e, '(', es, ',', anns, ')'); + top.unparse = e.unparse ++ "(" ++ es.unparse ++ "," ++ anns.unparse ++ ")"; + + top.typerep = asFunctionType(performSubstitution(e.typerep, e.upSubst), top.env).outputType; +} + concrete production noteAttachment top::Expr ::= 'attachNote' note::Expr 'on' e::Expr 'end' { diff --git a/grammars/silver/compiler/definition/core/FunctionDcl.sv b/grammars/silver/compiler/definition/core/FunctionDcl.sv index e84b4a66d..48b35acb4 100644 --- a/grammars/silver/compiler/definition/core/FunctionDcl.sv +++ b/grammars/silver/compiler/definition/core/FunctionDcl.sv @@ -54,6 +54,7 @@ top::FunctionSignature ::= cl::ConstraintList '=>' lhs::FunctionLHS '::=' rhs::P cl.env = top.env; lhs.env = top.env; rhs.env = occursEnv(cl.occursDefs, top.env); + rhs.implementedSig = nothing(); top.defs := lhs.defs ++ rhs.defs; top.constraintDefs = cl.defs; @@ -90,7 +91,7 @@ top::FunctionLHS ::= t::TypeExpr production attribute fName :: String; fName = "__func__lhs"; - top.outputElement = namedSignatureElement(fName, t.typerep); + top.outputElement = namedSignatureElement(fName, t.typerep, false); -- TODO: think about this. lhs doesn't really have an fName. top.defs := [lhsDef(top.grammarName, getParsedOriginLocationOrFallback(t), fName, t.typerep)]; diff --git a/grammars/silver/compiler/definition/core/ProductionDcl.sv b/grammars/silver/compiler/definition/core/ProductionDcl.sv index f6d64ea2e..27031e9c4 100644 --- a/grammars/silver/compiler/definition/core/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/core/ProductionDcl.sv @@ -1,20 +1,25 @@ grammar silver:compiler:definition:core; -tracked nonterminal ProductionSignature with config, grammarName, env, unparse, errors, defs, constraintDefs, occursDefs, namedSignature, signatureName; -tracked nonterminal ProductionLHS with config, grammarName, env, unparse, errors, defs, outputElement; -tracked nonterminal ProductionRHS with config, grammarName, env, unparse, errors, defs, inputElements, elementCount; -tracked nonterminal ProductionRHSElem with config, grammarName, env, unparse, errors, defs, inputElements, deterministicCount; +tracked nonterminal ProductionImplements with config, grammarName, env, unparse, errors, implementsSig; +tracked nonterminal ProductionSignature with config, grammarName, env, unparse, errors, defs, constraintDefs, occursDefs, namedSignature, signatureName, implementedSig; +tracked nonterminal ProductionLHS with config, grammarName, env, unparse, errors, defs, outputElement, implementedSig; +tracked nonterminal ProductionRHS with config, grammarName, env, unparse, errors, defs, inputElements, elementCount, implementedSig; +tracked nonterminal ProductionRHSElem with config, grammarName, env, unparse, errors, defs, inputElements, deterministicCount, implementedSig; flowtype forward {env, signatureName} on ProductionSignature; flowtype forward {env} on ProductionLHS, ProductionRHS; flowtype forward {deterministicCount, env} on ProductionRHSElem; -flowtype decorate {forward, grammarName, flowEnv} on ProductionSignature, ProductionLHS, ProductionRHS, ProductionRHSElem; +flowtype decorate {forward, grammarName, flowEnv, implementedSig} on ProductionSignature, ProductionLHS, ProductionRHS, ProductionRHSElem; propagate config, grammarName, errors on - ProductionSignature, ProductionLHS, ProductionRHS, ProductionRHSElem; + ProductionImplements, ProductionSignature, ProductionLHS, ProductionRHS, ProductionRHSElem; +propagate env on ProductionImplements; propagate env, defs on ProductionRHS; +synthesized attribute implementsSig::Maybe; +inherited attribute implementedSig::Maybe; + {-- - Used to help give names to children, when names are omitted. -} @@ -38,14 +43,14 @@ synthesized attribute constraintDefs::[Def]; parser attribute sigNames::[String] action { sigNames = []; }; concrete production productionDcl -top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::ProductionBody +top::AGDcl ::= 'abstract' 'production' id::Name d::ProductionImplements ns::ProductionSignature body::ProductionBody { - top.unparse = "abstract production " ++ id.unparse ++ "\n" ++ ns.unparse ++ "\n" ++ body.unparse; + top.unparse = "abstract production " ++ id.unparse ++ " " ++ d.unparse ++ "\n" ++ ns.unparse ++ "\n" ++ body.unparse; production fName :: String = top.grammarName ++ ":" ++ id.name; production namedSig :: NamedSignature = ns.namedSignature; - top.defs := prodDef(top.grammarName, id.nameLoc, namedSig, length(body.forwardExpr) > 0) :: + top.defs := prodDef(top.grammarName, id.nameLoc, namedSig, map((.fullName), d.implementsSig), length(body.forwardExpr) > 0) :: if null(body.productionAttributes) then [] else [prodOccursDef(top.grammarName, id.nameLoc, namedSig, body.productionAttributes)]; @@ -53,7 +58,7 @@ top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::Pr local sameNTProds::[ValueDclInfo] = filter( \ v::ValueDclInfo -> case v of - | prodDcl(ns, _) -> ns.outputElement.typerep == namedSig.outputElement.typerep + | prodDcl(ns, _, _) -> ns.outputElement.typerep == namedSig.outputElement.typerep | _ -> false end, getValueDclAll(id.name, top.env)); @@ -81,8 +86,11 @@ top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::Pr production attribute sigDefs :: [Def] with ++; sigDefs := ns.defs; + d.env = top.env; + ns.signatureName = fName; ns.env = newScopeEnv(sigDefs, top.env); + ns.implementedSig = d.implementsSig; local attribute prodAtts :: [Def]; prodAtts = defsFromPADcls(getProdAttrs(fName, top.env), namedSig); @@ -94,6 +102,30 @@ top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::Pr sigNames = []; } +concrete production productionImplementsSome +top::ProductionImplements ::= 'implements' id::QName +{ + top.unparse = "implements " ++ id.unparse; + top.implementsSig = + if id.lookupType.found + then just(id.lookupType.dcl.dispatchSignature) + else nothing(); + + top.errors <- id.lookupType.errors; + top.errors <- if !id.lookupType.found then [] else + case id.lookupType.dcl of + | dispatchDcl(_) -> [] + | _ -> [errFromOrigin(id, "Type '" ++ id.unparse ++ "' is not a dispatch signature type.")] + end; +} + +concrete production productionImplementsNone +top::ProductionImplements ::= +{ + top.unparse = ""; + top.implementsSig = nothing(); +} + concrete production productionSignature top::ProductionSignature ::= cl::ConstraintList '=>' lhs::ProductionLHS '::=' rhs::ProductionRHS { @@ -103,6 +135,8 @@ top::ProductionSignature ::= cl::ConstraintList '=>' lhs::ProductionLHS '::=' rh cl.constraintPos = signaturePos(top.namedSignature, sourceGrammar=top.grammarName); lhs.env = top.env; rhs.env = occursEnv(cl.occursDefs, top.env); + lhs.implementedSig = map((.outputElement), top.implementedSig); + rhs.implementedSig = map(compose(foldNamedSignatureElements, (.inputElements)), top.implementedSig); top.defs := lhs.defs ++ rhs.defs; top.constraintDefs = cl.defs; @@ -134,7 +168,7 @@ top::ProductionLHS ::= id::Name '::' t::TypeExpr top.unparse = id.unparse ++ "::" ++ t.unparse; propagate env; - top.outputElement = namedSignatureElement(id.name, t.typerep); + top.outputElement = namedSignatureElement(id.name, t.typerep, false); top.defs := [lhsDef(top.grammarName, id.nameLoc, id.name, t.typerep)]; @@ -163,6 +197,11 @@ top::ProductionRHS ::= h::ProductionRHSElem t::ProductionRHS top.inputElements = h.inputElements ++ t.inputElements; top.elementCount = 1 + t.elementCount; h.deterministicCount = t.elementCount; + + h.implementedSig = + case top.implementedSig of just(consNamedSignatureElement(h, _)) -> just(h) | _ -> nothing() end; + t.implementedSig = + case top.implementedSig of just(consNamedSignatureElement(_, t)) -> just(t) | _ -> nothing() end; } concrete production productionRHSElem @@ -171,7 +210,12 @@ top::ProductionRHSElem ::= id::Name '::' t::TypeExpr top.unparse = id.unparse ++ "::" ++ t.unparse; propagate env; - top.inputElements = [namedSignatureElement(id.name, t.typerep)]; + local shared::Boolean = + case top.implementedSig of + | just(e) -> e.elementShared + | nothing() -> false + end; + top.inputElements = [namedSignatureElement(id.name, t.typerep, shared)]; top.defs := [childDef(top.grammarName, id.nameLoc, id.name, t.typerep)]; diff --git a/grammars/silver/compiler/definition/core/Terminals.sv b/grammars/silver/compiler/definition/core/Terminals.sv index 6b4682b28..43c14c7b7 100644 --- a/grammars/silver/compiler/definition/core/Terminals.sv +++ b/grammars/silver/compiler/definition/core/Terminals.sv @@ -37,6 +37,7 @@ terminal Closed_kwd 'closed' lexer classes {KEYWORD}; terminal Concrete_kwd 'concrete' lexer classes {KEYWORD,RESERVED}; terminal Data_kwd 'data' lexer classes {KEYWORD}; terminal Decorate_kwd 'decorate' lexer classes {KEYWORD,RESERVED}; +terminal Dispatch_kwd 'dispatch' lexer classes {KEYWORD}; terminal Else_kwd 'else' lexer classes {KEYWORD,RESERVED}, precedence = 4, association = left; -- Association needed for dangling else in action code. terminal End_kwd 'end' lexer classes {KEYWORD,RESERVED}; terminal Forwarding_kwd 'forwarding' lexer classes {KEYWORD,RESERVED}; @@ -45,6 +46,7 @@ terminal Forwards_kwd 'forwards' lexer classes {KEYWORD,RESERVED}; terminal Function_kwd 'function' lexer classes {KEYWORD,RESERVED}; terminal Global_kwd 'global' lexer classes {KEYWORD,RESERVED}; terminal If_kwd 'if' lexer classes {KEYWORD,RESERVED}; +terminal Implements_kwd 'implements' lexer classes {KEYWORD,RESERVED}; terminal Inherited_kwd 'inherited' lexer classes {KEYWORD,RESERVED}; terminal Instance_kwd 'instance' lexer classes {KEYWORD}; terminal Local_kwd 'local' lexer classes {KEYWORD,RESERVED}; diff --git a/grammars/silver/compiler/definition/core/Type.sv b/grammars/silver/compiler/definition/core/Type.sv index b1bf5b421..8c4821550 100644 --- a/grammars/silver/compiler/definition/core/Type.sv +++ b/grammars/silver/compiler/definition/core/Type.sv @@ -60,3 +60,10 @@ top::Type ::= _ _ { top.applicationDispatcher = functionApplication; } + +aspect production dispatchType +top::Type ::= _ +{ + top.applicationDispatcher = dispatchApplication; +} + diff --git a/grammars/silver/compiler/definition/env/DclInfo.sv b/grammars/silver/compiler/definition/env/DclInfo.sv index f0d16cdbe..e63212826 100644 --- a/grammars/silver/compiler/definition/env/DclInfo.sv +++ b/grammars/silver/compiler/definition/env/DclInfo.sv @@ -20,6 +20,7 @@ synthesized attribute isTypeAlias :: Boolean; synthesized attribute isClass :: Boolean; synthesized attribute classMembers :: [Pair]; synthesized attribute isClosed :: Boolean; +synthesized attribute dispatchSignature :: NamedSignature; -- instances inherited attribute givenInstanceType :: Type; @@ -102,12 +103,16 @@ top::ValueDclInfo ::= ty::Type -- ValueDclInfos that DO appear in interface files: abstract production prodDcl -top::ValueDclInfo ::= ns::NamedSignature hasForward::Boolean +top::ValueDclInfo ::= ns::NamedSignature dispatch::Maybe hasForward::Boolean { top.fullName = ns.fullName; top.namedSignature = ns; - top.typeScheme = ns.typeScheme; + top.typeScheme = + case dispatch of + | nothing() -> ns.typeScheme + | just(fn) -> monoType(dispatchType(fn)) + end; top.hasForward = hasForward; } abstract production funDcl @@ -153,7 +158,8 @@ top::ValueDclInfo ::= fn::String closed nonterminal TypeDclInfo with sourceGrammar, sourceLocation, fullName, compareTo, isEqual, - typeScheme, kindrep, givenNonterminalType, isType, isTypeAlias, mentionedAliases, isClass, classMembers, givenInstanceType, superContexts, isClosed; + typeScheme, kindrep, givenNonterminalType, isType, isTypeAlias, mentionedAliases, + isClass, classMembers, givenInstanceType, superContexts, isClosed, dispatchSignature; propagate isEqual, compareTo on TypeDclInfo excluding typeAliasDcl, clsDcl; aspect default production @@ -167,6 +173,7 @@ top::TypeDclInfo ::= top.classMembers = []; top.superContexts = []; top.isClosed = false; + top.dispatchSignature = bogusNamedSignature(); } abstract production ntDcl @@ -237,6 +244,15 @@ top::TypeDclInfo ::= fn::String supers::[Context] tv::TyVar k::Kind members::[Pa top.superContexts = map(performContextRenaming(_, tvSubst), supers); top.classMembers = members; } +abstract production dispatchDcl +top::TypeDclInfo ::= ns::NamedSignature +{ + top.fullName = ns.fullName; + + top.typeScheme = monoType(dispatchType(ns.fullName)); + top.dispatchSignature = ns; + top.isType = true; +} closed nonterminal AttributeDclInfo with sourceGrammar, sourceLocation, fullName, compareTo, compareKey, isEqual, diff --git a/grammars/silver/compiler/definition/env/Defs.sv b/grammars/silver/compiler/definition/env/Defs.sv index baa1cee73..8c94bc60a 100644 --- a/grammars/silver/compiler/definition/env/Defs.sv +++ b/grammars/silver/compiler/definition/env/Defs.sv @@ -126,8 +126,8 @@ fun lhsDef Def ::= sg::String sl::Location fn::String ty::Type = valueDef(defaultEnvItem(lhsDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); fun localDef Def ::= sg::String sl::Location fn::String ty::Type isForward::Boolean = valueDef(defaultEnvItem(localDcl(fn,ty,isForward,sourceGrammar=sg,sourceLocation=sl))); -fun prodDef Def ::= sg::String sl::Location ns::NamedSignature hasForward::Boolean = - prodDclDef(defaultEnvItem(prodDcl(ns,hasForward,sourceGrammar=sg,sourceLocation=sl))); +fun prodDef Def ::= sg::String sl::Location ns::NamedSignature dispatch::Maybe hasForward::Boolean = + prodDclDef(defaultEnvItem(prodDcl(ns,dispatch,hasForward,sourceGrammar=sg,sourceLocation=sl))); fun funDef Def ::= sg::String sl::Location ns::NamedSignature = valueDef(defaultEnvItem(funDcl(ns,sourceGrammar=sg,sourceLocation=sl))); fun globalDef diff --git a/grammars/silver/compiler/definition/env/Env.sv b/grammars/silver/compiler/definition/env/Env.sv index c44331ccc..e9a5b6f2c 100644 --- a/grammars/silver/compiler/definition/env/Env.sv +++ b/grammars/silver/compiler/definition/env/Env.sv @@ -268,7 +268,7 @@ NamedSignatureElement ::= nt::Type anno::OccursDclInfo -- Used to compute the local typerep for this nonterminal anno.givenNonterminalType = nt; - return namedSignatureElement(anno.attrOccurring, anno.typeScheme.typerep); + return namedSignatureElement(anno.attrOccurring, anno.typeScheme.typerep, false); } -- Looks up class instances matching a type @@ -345,3 +345,13 @@ Maybe<[String]> ::= t::Type e::Env | _ -> just([]) end; } + +function asFunctionType +Type ::= t::Type e::Env +{ + return + case t.baseType of + | dispatchType(fn) when getTypeDcl(fn, e) matches dispatchDcl(ns) :: _ -> ns.typerep + | _ -> t + end; +} diff --git a/grammars/silver/compiler/definition/env/NamedSignature.sv b/grammars/silver/compiler/definition/env/NamedSignature.sv index d04ec3dce..607f068a8 100644 --- a/grammars/silver/compiler/definition/env/NamedSignature.sv +++ b/grammars/silver/compiler/definition/env/NamedSignature.sv @@ -125,20 +125,22 @@ global foldNamedSignatureElements::(NamedSignatureElements ::= [NamedSignatureEl {-- - Represents an elements of a signature, whether input, output, or annotation. -} -nonterminal NamedSignatureElement with elementName, elementShortName, typerep, freeVariables, boundVariables; +nonterminal NamedSignatureElement with elementName, elementShortName, elementShared, typerep, freeVariables, boundVariables; propagate boundVariables on NamedSignatureElement; synthesized attribute elementName :: String; synthesized attribute elementShortName :: String; +synthesized attribute elementShared :: Boolean; {-- - Represents an element of the function/production signature. -} abstract production namedSignatureElement -top::NamedSignatureElement ::= n::String ty::Type +top::NamedSignatureElement ::= n::String ty::Type shared::Boolean { top.elementName = n; - top.typerep = ty; + top.typerep = if shared then decoratedType(inhSetType([]), ty) else ty; + top.elementShared = shared; top.freeVariables = ty.freeVariables; -- When we convert from a SignatureElement to a functionType, we cut down to the short name only: @@ -153,7 +155,7 @@ top::NamedSignatureElement ::= n::String ty::Type abstract production bogusNamedSignatureElement top::NamedSignatureElement ::= { - forwards to namedSignatureElement("__SV_BOGUS_ELEM", errorType()); + forwards to namedSignatureElement("__SV_BOGUS_ELEM", errorType(), false); } ---------------- diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index ba79abdb0..7618e9681 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -216,6 +216,20 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp es.alwaysDecorated = false; } +aspect production dispatchApplication +top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +{ + top.flowVertexInfo = top.decSiteVertexInfo; + es.appProd = + case e.typerep of + | dispatchType(fn) when getTypeDcl(fn, top.env) matches d :: _ -> just(d.dispatchSignature) + | _ -> nothing() + end; + e.decSiteVertexInfo = nothing(); + es.decSiteVertexInfo = top.decSiteVertexInfo; + es.alwaysDecorated = top.alwaysDecorated; +} + aspect production annoExpr top::AnnoExpr ::= qn::QName '=' e::AppExpr { diff --git a/grammars/silver/compiler/definition/flow/env/ProductionDcl.sv b/grammars/silver/compiler/definition/flow/env/ProductionDcl.sv index 724e4edff..8d0ca46dd 100644 --- a/grammars/silver/compiler/definition/flow/env/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/flow/env/ProductionDcl.sv @@ -9,16 +9,18 @@ import silver:compiler:definition:flow:driver; import silver:compiler:driver:util; -- only for productionFlowGraphs occurrence? attribute flowEnv occurs on - ProductionSignature, ProductionLHS, ProductionRHS, ProductionRHSElem, + DispatchSignature, DispatchRHS, DispatchRHSElem, + ProductionImplements, ProductionSignature, ProductionLHS, ProductionRHS, ProductionRHSElem, AspectProductionSignature, AspectProductionLHS, AspectFunctionSignature, AspectFunctionLHS, AspectRHS, AspectRHSElem; propagate flowEnv on - ProductionSignature, ProductionLHS, ProductionRHS, ProductionRHSElem, + DispatchSignature, DispatchRHS, DispatchRHSElem, + ProductionImplements, ProductionSignature, ProductionLHS, ProductionRHS, ProductionRHSElem, AspectProductionSignature, AspectProductionLHS, AspectFunctionSignature, AspectFunctionLHS, AspectRHS, AspectRHSElem; aspect production productionDcl -top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::ProductionBody +top::AGDcl ::= 'abstract' 'production' id::Name d::ProductionImplements ns::ProductionSignature body::ProductionBody { -- TODO: bit of a hack, isn't it? local myGraphs :: EnvTree = head(searchEnvTree(top.grammarName, top.compiledGrammars)).productionFlowGraphs; diff --git a/grammars/silver/compiler/definition/type/PrettyPrinting.sv b/grammars/silver/compiler/definition/type/PrettyPrinting.sv index 1a8525720..c66ad8a7b 100644 --- a/grammars/silver/compiler/definition/type/PrettyPrinting.sv +++ b/grammars/silver/compiler/definition/type/PrettyPrinting.sv @@ -235,6 +235,12 @@ top::Type ::= params::Integer namedParams::[String] top.typepp = s"(_ ::=${replicate(params, " _") }${if null(namedParams) then "" else "; " ++ implode("::_; ", namedParams) ++ "::_"})"; } +aspect production dispatchType +top::Type ::= fn::String +{ + top.typepp = fn; +} + aspect production starKind top::Kind ::= { diff --git a/grammars/silver/compiler/definition/type/Type.sv b/grammars/silver/compiler/definition/type/Type.sv index 0bbaa9f8e..b949a2f41 100644 --- a/grammars/silver/compiler/definition/type/Type.sv +++ b/grammars/silver/compiler/definition/type/Type.sv @@ -335,6 +335,13 @@ top::Type ::= params::Integer namedParams::[String] top.freeVariables = []; } +abstract production dispatchType +top::Type ::= fn::String +{ + top.kindrep = starKind(); + top.freeVariables = []; +} + -------------------------------------------------------------------------------- annotation varId :: Integer; diff --git a/grammars/silver/compiler/definition/type/Unification.sv b/grammars/silver/compiler/definition/type/Unification.sv index 8071d7e80..5323d3bae 100644 --- a/grammars/silver/compiler/definition/type/Unification.sv +++ b/grammars/silver/compiler/definition/type/Unification.sv @@ -206,6 +206,16 @@ top::Type ::= params::Integer namedParams::[String] end; } +aspect production dispatchType +top::Type ::= fn::String +{ + top.unify = + case top.unifyWith of + | dispatchType(ofn) when fn == ofn -> emptySubst() + | _ -> errorSubst("Tried to unify conflicting dispatch types " ++ fn ++ " and " ++ prettyType(top.unifyWith)) + end; +} + -------------------------------------------------------------------------------- function unify diff --git a/grammars/silver/compiler/definition/type/Util.sv b/grammars/silver/compiler/definition/type/Util.sv index 7c20a6b3d..d546487d8 100644 --- a/grammars/silver/compiler/definition/type/Util.sv +++ b/grammars/silver/compiler/definition/type/Util.sv @@ -276,6 +276,12 @@ top::Type ::= params::Integer namedParams::[String] top.isApplicable = true; } +aspect production dispatchType +top::Type ::= fn::String +{ + top.isApplicable = true; +} + -- Strict type equality, assuming all type vars are skolemized instance Eq Type { eq = \ t1::Type t2::Type -> !unifyDirectional(t1, t2).failure; diff --git a/grammars/silver/compiler/definition/type/syntax/ProductionDcl.sv b/grammars/silver/compiler/definition/type/syntax/ProductionDcl.sv index 30350a31f..8e9b3c867 100644 --- a/grammars/silver/compiler/definition/type/syntax/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/type/syntax/ProductionDcl.sv @@ -5,7 +5,7 @@ attribute lexicalTypeVariables, lexicalTyVarKinds occurs on ProductionSignature, flowtype lexicalTypeVariables {decorate} on ProductionSignature, ProductionLHS, ProductionRHS, ProductionRHSElem; aspect production productionDcl -top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::ProductionBody +top::AGDcl ::= 'abstract' 'production' id::Name d::ProductionImplements ns::ProductionSignature body::ProductionBody { production attribute allLexicalTyVars :: [String]; allLexicalTyVars = nub(ns.lexicalTypeVariables); diff --git a/grammars/silver/compiler/extension/autoattr/Inherited.sv b/grammars/silver/compiler/extension/autoattr/Inherited.sv index 6e1bddb48..fab9f717c 100644 --- a/grammars/silver/compiler/extension/autoattr/Inherited.sv +++ b/grammars/silver/compiler/extension/autoattr/Inherited.sv @@ -10,12 +10,15 @@ top::ProductionStmt ::= attr::Decorated! QName local inputsWithAttr::[NamedSignatureElement] = filter( \ input::NamedSignatureElement -> - isDecorable(input.typerep, top.env) && - -- Only propagate for unique decorated children that don't have the attribute - case getMaxRefSet(input.typerep, top.env) of - | just(inhs) -> !contains(attrFullName, inhs) - | nothing() -> false - end && + ((isDecorable(input.typerep, top.env) && + -- Only propagate for unique decorated children that don't have the attribute + case getMaxRefSet(input.typerep, top.env) of + | just(inhs) -> !contains(attrFullName, inhs) + | nothing() -> false + end) || + -- TODO: Check that the attribute is not already defined. + -- This may require consulting the flowEnv, but shouldn't require inferring flow types. + input.elementShared) && !null(getOccursDcl(attrFullName, input.typerep.typeName, top.env)), top.frame.signature.inputElements); forwards to diff --git a/grammars/silver/compiler/extension/autoattr/Propagate.sv b/grammars/silver/compiler/extension/autoattr/Propagate.sv index c21b1d9b7..5263ae4c5 100644 --- a/grammars/silver/compiler/extension/autoattr/Propagate.sv +++ b/grammars/silver/compiler/extension/autoattr/Propagate.sv @@ -173,7 +173,7 @@ top::ProdNameList ::= n::QName if n.lookupValue.found then case n.lookupValue.dcl of - | prodDcl(_, _) -> [] + | prodDcl(_, _, _) -> [] | _ -> [errFromOrigin(n, n.name ++ " is not a production")] end else []; @@ -189,7 +189,7 @@ top::ProdNameList ::= h::QName ',' t::ProdNameList if h.lookupValue.found then case h.lookupValue.dcl of - | prodDcl(_, _) -> [] + | prodDcl(_, _, _) -> [] | _ -> [errFromOrigin(h, h.name ++ " is not a production")] end else []; diff --git a/grammars/silver/compiler/extension/autoattr/Threaded.sv b/grammars/silver/compiler/extension/autoattr/Threaded.sv index c613f3434..834d9783e 100644 --- a/grammars/silver/compiler/extension/autoattr/Threaded.sv +++ b/grammars/silver/compiler/extension/autoattr/Threaded.sv @@ -110,6 +110,7 @@ top::ProductionStmt ::= isCol::Boolean rev::Boolean inh::Decorated! QName syn::S \ ie::NamedSignatureElement -> isDecorable(ie.typerep, top.env) && -- Only propagate for unique decorated children that don't have the inh attribute + -- TODO: Handle dispatch signatures case getMaxRefSet(ie.typerep, top.env) of | just(inhs) -> !contains(inh.lookupAttribute.fullName, inhs) | nothing() -> false @@ -146,6 +147,7 @@ top::ProductionStmt ::= isCol::Boolean rev::Boolean inh::String syn::Decorated! \ ie::NamedSignatureElement -> isDecorable(ie.typerep, top.env) && -- Only propagate for unique decorated children that don't have the inh attribute + -- TODO: Handle dispatch signatures case getMaxRefSet(ie.typerep, top.env) of | just(inhs) -> !contains(inh, inhs) | nothing() -> false diff --git a/grammars/silver/compiler/extension/convenience/Productions.sv b/grammars/silver/compiler/extension/convenience/Productions.sv index c4090fc18..684d0ffe4 100644 --- a/grammars/silver/compiler/extension/convenience/Productions.sv +++ b/grammars/silver/compiler/extension/convenience/Productions.sv @@ -4,9 +4,9 @@ import silver:compiler:modification:copper; -- "production" short for "abstract production" concrete production productionDclImplicitAbs -top::AGDcl ::= 'production' id::Name ns::ProductionSignature body::ProductionBody +top::AGDcl ::= 'production' id::Name d::ProductionImplements ns::ProductionSignature body::ProductionBody { - forwards to productionDcl('abstract', $1, id, ns, body); + forwards to productionDcl('abstract', $1, id, d, ns, body); } -- "concrete productions" syntax diff --git a/grammars/silver/compiler/extension/data/DataDcl.sv b/grammars/silver/compiler/extension/data/DataDcl.sv index d0b482c80..88064a79c 100644 --- a/grammars/silver/compiler/extension/data/DataDcl.sv +++ b/grammars/silver/compiler/extension/data/DataDcl.sv @@ -71,9 +71,15 @@ top::DataConstructor ::= id::Name rhs::ProductionRHS | botlNone() -> ntBaseType | botlSome(btl) -> appTypeExpr(ntBaseType, btl) end; - top.ctorDcls = Silver_AGDcl { + top.ctorDcls = + productionDcl('abstract', 'production', id, + productionImplementsNone(), + productionSignatureNoCL(productionLHS(name("top"), '::', ntType), '::=', rhs), + productionBody('{', productionStmtsNil(), '}')); +-- TODO: Restore after bootstrapping change to productionDcl +{-Silver_AGDcl { abstract production $Name{id} top::$TypeExpr{ntType} ::= $ProductionRHS{rhs} {} - }; + };-} } diff --git a/grammars/silver/compiler/extension/doc/core/AGDcl.sv b/grammars/silver/compiler/extension/doc/core/AGDcl.sv index 990813e74..020c0cdd6 100644 --- a/grammars/silver/compiler/extension/doc/core/AGDcl.sv +++ b/grammars/silver/compiler/extension/doc/core/AGDcl.sv @@ -42,8 +42,17 @@ top::AGDcl ::= 'aspect' 'function' id::QName ns::AspectFunctionSignature body::P top.docs := []; -- Not considered to need docs } +aspect production dispatchSigDcl +top::AGDcl ::= 'dispatch' id::Name '=' ns::DispatchSignature ';' +{ + top.docForName = id.name; + top.docUnparse = "`dispatch " ++ id.name ++ "`   (`" ++ ns.unparse ++ "`)"; + top.docDcls := [(id.name, docDclInfo(id.name, sourceLocation=id.nameLoc, sourceGrammar=top.grammarName))]; + top.docs := [mkUndocumentedItem(top.docForName, top)]; +} + aspect production productionDcl -top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::ProductionBody +top::AGDcl ::= 'abstract' 'production' id::Name d::ProductionImplements ns::ProductionSignature body::ProductionBody { top.docForName = id.name; top.docUnparse = "`abstract production " ++ id.name ++ "`   (`" ++ ns.unparse ++ "`)"; diff --git a/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv b/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv index 64844c66c..f487612e9 100644 --- a/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv +++ b/grammars/silver/compiler/extension/doc/core/DocumentedAGDcl.sv @@ -50,7 +50,7 @@ top::AGDcl ::= comment::DocComment_t dcl::AGDcl local paramNamesAndForWhat::Pair String> = case getFirstAGDcl(forward) of | functionDcl(_, _, ns, _) -> (just(ns.argNames), "function") | aspectFunctionDcl(_, _, _, ns, _) -> (just(ns.argNames), "function") - | productionDcl(_, _, _, ns, _) -> (just(ns.argNames), "production") + | productionDcl(_, _, _, _, ns, _) -> (just(ns.argNames), "production") | aspectProductionDcl(_, _, _, ns, _) -> (just(ns.argNames), "production") | nonterminalDcl(_, _, _, tl, _, _) -> (just(getFreeTypeNames(tl.freeVariables)), "nonterminal") | attributeDclInh(_, _, _, tl, _, _, _) -> (just(getFreeTypeNames(tl.freeVariables)), "attribute") diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index 8c6bd815b..bf7bea9bc 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -283,6 +283,20 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp top.monadicNames = t.monadicNames; } + +aspect production dispatchApplication +top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +{ + forward t = application(e, '(', es, ',', anns, ')'); + + top.merrors := t.merrors; + top.mUpSubst = t.mUpSubst; + top.mtyperep = t.mtyperep; + top.monadRewritten = t.monadRewritten; + + top.monadicNames = t.monadicNames; +} + --build the lambda to apply to all the original arguments plus the function function buildMonadApplicationLambda Expr ::= realtys::[Type] monadTysLocs::[Pair] monadAnns::[(Type, QName, Boolean)] diff --git a/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv b/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv index 866c6c741..537709756 100644 --- a/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv +++ b/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv @@ -147,7 +147,7 @@ top::Pattern ::= v::Name else []; top.errors <- case getValueDcl(v.name, top.env) of - | prodDcl(_,_) :: _ -> + | prodDcl(_,_,_) :: _ -> [errFromOrigin(v, "Pattern variables should not share the name of a production. (Potential confusion between '" ++ v.name ++ "' and '" ++ v.name ++ "()')")] | _ -> [] end; diff --git a/grammars/silver/compiler/extension/testing/EqualityTest.sv b/grammars/silver/compiler/extension/testing/EqualityTest.sv index 1cb0c070d..adb1fcfda 100644 --- a/grammars/silver/compiler/extension/testing/EqualityTest.sv +++ b/grammars/silver/compiler/extension/testing/EqualityTest.sv @@ -138,6 +138,7 @@ ag::AGDcl ::= kwd::'equalityTest' -- TODO: Rewrite as Silver_AGDcl { ... } local absProdCS :: AGDcl = productionDcl('abstract', 'production', testNameref, + productionImplementsNone(), productionSignature( nilConstraint(), '=>', productionLHS(tref, '::', diff --git a/grammars/silver/compiler/extension/testing/MainTestSuite.sv b/grammars/silver/compiler/extension/testing/MainTestSuite.sv index cd792308c..79528cf5d 100644 --- a/grammars/silver/compiler/extension/testing/MainTestSuite.sv +++ b/grammars/silver/compiler/extension/testing/MainTestSuite.sv @@ -34,7 +34,8 @@ top::AGDcl ::= 'makeTestSuite' nme::IdLower_t ';' ]; forwards to - productionDcl('abstract', 'production', nameIdLower(nme), sig, + productionDcl('abstract', 'production', nameIdLower(nme), + productionImplementsNone(), sig, productionBody('{', foldl(productionStmtsSnoc(_, _), productionStmtsNil(), bod), '}')); diff --git a/grammars/silver/compiler/modification/copper/ActionCode.sv b/grammars/silver/compiler/modification/copper/ActionCode.sv index 160d7537e..787f16065 100644 --- a/grammars/silver/compiler/modification/copper/ActionCode.sv +++ b/grammars/silver/compiler/modification/copper/ActionCode.sv @@ -25,6 +25,7 @@ top::AGDcl ::= 'concrete' 'production' id::Name ns::ProductionSignature pm::Prod constructAnonymousGraph(acode.flowDefs, top.env, myProds, myFlow); ns.signatureName = fName; + ns.implementedSig = nothing(); ns.env = newScopeEnv(ns.defs, top.env); pm.productionSig = ns.namedSignature; pm.env = newScopeEnv(ns.actionDefs, top.env); diff --git a/grammars/silver/compiler/modification/copper/ParserDcl.sv b/grammars/silver/compiler/modification/copper/ParserDcl.sv index 52cc7649b..f0fded6fa 100644 --- a/grammars/silver/compiler/modification/copper/ParserDcl.sv +++ b/grammars/silver/compiler/modification/copper/ParserDcl.sv @@ -32,9 +32,9 @@ top::AGDcl ::= 'parser' n::Name '::' t::TypeExpr '{' m::ParserComponents '}' production namedSig :: NamedSignature = namedSignature(fName, nilContext(), foldNamedSignatureElements([ - namedSignatureElement("stringToParse", stringType()), - namedSignatureElement("filenameToReport", stringType())]), - namedSignatureElement("__func__lhs", appType(nonterminalType("silver:core:ParseResult", [starKind()], true, false), t.typerep)), + namedSignatureElement("stringToParse", stringType(), false), + namedSignatureElement("filenameToReport", stringType(), false)]), + namedSignatureElement("__func__lhs", appType(nonterminalType("silver:core:ParseResult", [starKind()], true, false), t.typerep), false), nilNamedSignatureElement()); production spec :: ParserSpec = diff --git a/grammars/silver/compiler/modification/defaultattr/DefaultAttr.sv b/grammars/silver/compiler/modification/defaultattr/DefaultAttr.sv index 5fe4ea179..03c5ad9f0 100644 --- a/grammars/silver/compiler/modification/defaultattr/DefaultAttr.sv +++ b/grammars/silver/compiler/modification/defaultattr/DefaultAttr.sv @@ -57,7 +57,7 @@ top::AspectDefaultProductionSignature ::= lhs::Name '::' te::TypeExpr '::=' top.namedSignature = namedSignature(top.grammarName ++ ":default" ++ te.typerep.typeName, nilContext(), nilNamedSignatureElement(), - namedSignatureElement(lhs.name, te.typerep), + namedSignatureElement(lhs.name, te.typerep, false), foldNamedSignatureElements(annotationsForNonterminal(te.typerep, top.env))); propagate config, grammarName, env, compiledGrammars, errors, lexicalTypeVariables, lexicalTyVarKinds, flowEnv; diff --git a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv index c06c8b933..1a48045ae 100644 --- a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv +++ b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv @@ -129,7 +129,7 @@ top::LambdaRHSElem ::= id::Name '::' t::TypeExpr top.givenLambdaId, top.givenLambdaParamIndex)]; top.lambdaBoundVars := [id.name]; - top.inputElements = [namedSignatureElement(id.name, t.typerep)]; + top.inputElements = [namedSignatureElement(id.name, t.typerep, false)]; top.unparse = id.unparse ++ "::" ++ t.unparse; } diff --git a/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv b/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv index 7b3ca14ae..c4506d97f 100644 --- a/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv +++ b/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv @@ -209,7 +209,7 @@ top::PrimPattern ::= qn::Decorated QName ns::VarBinders e::Expr top.errors <- qn.lookupValue.errors; top.errors <- case qn.lookupValue.dcls of - | prodDcl (_, _) :: _ -> [] + | prodDcl (_, _, _) :: _ -> [] | [] -> [] | _ -> [errFromOrigin(qn, qn.name ++ " is not a production.")] end; @@ -292,7 +292,7 @@ top::PrimPattern ::= qn::Decorated QName ns::VarBinders e::Expr top.errors <- qn.lookupValue.errors; top.errors <- case qn.lookupValue.dcls of - | prodDcl (_, _) :: _ -> [] + | prodDcl (_, _, _) :: _ -> [] | [] -> [] | _ -> [errFromOrigin(qn, qn.name ++ " is not a production.")] end; diff --git a/grammars/silver/compiler/modification/primitivepattern/Types.sv b/grammars/silver/compiler/modification/primitivepattern/Types.sv index d86e139ab..b72a4f023 100644 --- a/grammars/silver/compiler/modification/primitivepattern/Types.sv +++ b/grammars/silver/compiler/modification/primitivepattern/Types.sv @@ -240,6 +240,19 @@ top::Type ::= params::Integer namedParams::[String] end; } +aspect production dispatchType +top::Type ::= fn::String +{ + top.refine = + case top.refineWith of + | dispatchType(ofn) -> + if fn == ofn + then emptySubst() + else errorSubst("Tried to refine conflicting dispatch types " ++ fn ++ " and " ++ ofn) + | _ -> errorSubst("Tried to refine dispatch type " ++ fn ++ " with " ++ prettyType(top.refineWith)) + end; +} + aspect production foreignType top::Type ::= fn::String transType::String params::[Type] { diff --git a/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv b/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv index 19b3c165c..30646db21 100644 --- a/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv +++ b/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv @@ -189,7 +189,7 @@ top::VarBinder ::= n::Name -- this would allow us to match 'left' and 'right' on a Pair, for example, but error on Either top.errors <- case getValueDcl(n.name, top.env) of - | prodDcl(_,_) :: _ -> [errFromOrigin(top, "Pattern variables cannot have the same name as productions (to avoid confusion)")] + | prodDcl(_,_,_) :: _ -> [errFromOrigin(top, "Pattern variables cannot have the same name as productions (to avoid confusion)")] | _ -> [] end; } diff --git a/grammars/silver/compiler/translation/java/core/Expr.sv b/grammars/silver/compiler/translation/java/core/Expr.sv index 9f6c5bdad..a451848d8 100644 --- a/grammars/silver/compiler/translation/java/core/Expr.sv +++ b/grammars/silver/compiler/translation/java/core/Expr.sv @@ -291,6 +291,22 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs annos::Decorated! AnnoA top.lazyTranslation = wrapThunk(top.translation, top.frame.lazyApplication); } +aspect production dispatchApplication +top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs annos::Decorated! AnnoAppExprs +{ + top.translation = e.invokeTranslation; + top.lazyTranslation = e.invokeLazyTranslation; + + e.invokeIsUnique = true; + e.invokeArgs = es; + e.invokeNamedArgs = annos; + e.sameProdAsProductionDefinedOn = + case e of + | baseExpr(qn) -> qn.name == last(explode(":", top.frame.fullName)) + | _ -> false + end; +} + aspect production errorAccessHandler top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur { diff --git a/grammars/silver/compiler/translation/java/core/NamedSignature.sv b/grammars/silver/compiler/translation/java/core/NamedSignature.sv index d7541dc96..ea46c4e40 100644 --- a/grammars/silver/compiler/translation/java/core/NamedSignature.sv +++ b/grammars/silver/compiler/translation/java/core/NamedSignature.sv @@ -240,14 +240,14 @@ top::NamedSignatureElements ::= -- TODO: It'd be nice to maybe split these into the ordered parameters and the annotations aspect production namedSignatureElement -top::NamedSignatureElement ::= n::String ty::Type +top::NamedSignatureElement ::= n::String ty::Type shared::Boolean { top.childSigElem = "final Object c_" ++ n; top.childRefElem = "c_" ++ n; top.childDeclElem = s"""private Object child_${n}; - public final ${ty.transType} getChild_${n}() { - final ${ty.transType} result = common.Util.<${ty.transType}>demand(child_${n}); + public final ${top.typerep.transType} getChild_${n}() { + final ${top.typerep.transType} result = common.Util.<${top.typerep.transType}>demand(child_${n}); child_${n} = result; return result; } @@ -319,7 +319,7 @@ String ::= n::NamedSignatureElement function makeChildDecorableCase String ::= env::Env n::NamedSignatureElement { - return s"\t\t\tcase i_${n.elementName}: return ${toString(isDecorable(n.typerep, env))};\n"; + return s"\t\t\tcase i_${n.elementName}: return ${toString(isDecorable(n.typerep, env) || n.elementShared)};\n"; } function makeChildDecSiteAccessCase String ::= env::Env flowEnv::FlowEnv lhsNtName::String prodName::String n::NamedSignatureElement diff --git a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv index 52dad2a1e..2f0f94649 100644 --- a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv +++ b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv @@ -3,7 +3,7 @@ grammar silver:compiler:translation:java:core; import silver:compiler:driver; aspect production productionDcl -top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::ProductionBody +top::AGDcl ::= 'abstract' 'production' id::Name d::ProductionImplements ns::ProductionSignature body::ProductionBody { local className :: String = "P" ++ id.name; diff --git a/grammars/silver/compiler/translation/java/type/Type.sv b/grammars/silver/compiler/translation/java/type/Type.sv index 80e79d566..9ed9bc183 100644 --- a/grammars/silver/compiler/translation/java/type/Type.sv +++ b/grammars/silver/compiler/translation/java/type/Type.sv @@ -196,3 +196,11 @@ top::Type ::= params::Integer namedParams::[String] s"new common.FunctionTypeRep(${toString(params)}, new String[] {${implode(", ", map(\ n::String -> s"\"${n}\"", namedParams))}})"; top.transTypeName = "Fn_" ++ toString(params) ++ "_" ++ implode("_", namedParams); } + +aspect production dispatchType +top::Type ::= fn::String +{ + top.transClassType = "common.NodeFactory"; + top.transTypeRep = s"new common.BaseTypeRep(\"${fn}\")"; + top.transTypeName = substitute(":", "_", fn); +} diff --git a/language-server/launcher/.settings/org.eclipse.jdt.core.prefs b/language-server/launcher/.settings/org.eclipse.jdt.core.prefs index cbcd33000..6bf842e11 100644 --- a/language-server/launcher/.settings/org.eclipse.jdt.core.prefs +++ b/language-server/launcher/.settings/org.eclipse.jdt.core.prefs @@ -33,7 +33,7 @@ org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore org.eclipse.jdt.core.compiler.annotation.nonnull=javax.annotation.Nonnull org.eclipse.jdt.core.compiler.annotation.nonnull.secondary= -org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=javax.annotation.ParametersAreNonnullByDefault org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary= org.eclipse.jdt.core.compiler.annotation.nullable=javax.annotation.Nullable org.eclipse.jdt.core.compiler.annotation.nullable.secondary= From d20c8df31cc58054689ca70661af881e4a53d145 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 6 Mar 2024 16:46:40 -0600 Subject: [PATCH 168/283] Bootstrapping --- grammars/silver/compiler/extension/data/DataDcl.sv | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/grammars/silver/compiler/extension/data/DataDcl.sv b/grammars/silver/compiler/extension/data/DataDcl.sv index 88064a79c..d0b482c80 100644 --- a/grammars/silver/compiler/extension/data/DataDcl.sv +++ b/grammars/silver/compiler/extension/data/DataDcl.sv @@ -71,15 +71,9 @@ top::DataConstructor ::= id::Name rhs::ProductionRHS | botlNone() -> ntBaseType | botlSome(btl) -> appTypeExpr(ntBaseType, btl) end; - top.ctorDcls = - productionDcl('abstract', 'production', id, - productionImplementsNone(), - productionSignatureNoCL(productionLHS(name("top"), '::', ntType), '::=', rhs), - productionBody('{', productionStmtsNil(), '}')); --- TODO: Restore after bootstrapping change to productionDcl -{-Silver_AGDcl { + top.ctorDcls = Silver_AGDcl { abstract production $Name{id} top::$TypeExpr{ntType} ::= $ProductionRHS{rhs} {} - };-} + }; } From c69f4677511fad8604dc69a036cba8ef41a9e24d Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 6 Mar 2024 17:14:17 -0600 Subject: [PATCH 169/283] Change signature of errorReference --- grammars/silver/compiler/definition/core/Expr.sv | 9 ++++----- .../silver/compiler/extension/implicit_monads/Expr.sv | 4 ++-- grammars/silver/compiler/translation/java/core/Expr.sv | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index 7db2765de..f7c0e5a0a 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -90,7 +90,7 @@ top::Expr ::= q::QName propagate env; forwards to if null(q.lookupValue.dcls) - then errorReference(q.lookupValue.errors, q) + then errorReference(q) else q.lookupValue.dcl.refDispatcher(q); } action { if (contains(q.name, sigNames)) { @@ -99,17 +99,16 @@ top::Expr ::= q::QName } abstract production errorReference -top::Expr ::= msg::[Message] q::Decorated! QName +top::Expr ::= q::Decorated! QName { - undecorates to errorExpr(msg); -- TODO: Should this be baseExpr? + undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); - top.errors <- msg; + top.errors <- q.lookupValue.errors; top.typerep = errorType(); } --- TODO: We should separate this out, even, to be "nonterminal/decorable" and "as-is" abstract production childReference top::Expr ::= q::Decorated! QName { diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index bf7bea9bc..3628826bb 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -43,9 +43,9 @@ top::Expr ::= e::[Message] } aspect production errorReference -top::Expr ::= msg::[Message] q::Decorated! QName +top::Expr ::= q::Decorated! QName { - top.merrors := msg; + top.merrors := q.lookupValue.errors; propagate mDownSubst, mUpSubst; top.mtyperep = errorType(); top.monadicNames = []; diff --git a/grammars/silver/compiler/translation/java/core/Expr.sv b/grammars/silver/compiler/translation/java/core/Expr.sv index a451848d8..162421ff2 100644 --- a/grammars/silver/compiler/translation/java/core/Expr.sv +++ b/grammars/silver/compiler/translation/java/core/Expr.sv @@ -58,7 +58,7 @@ top::Expr ::= msg::[Message] } aspect production errorReference -top::Expr ::= msg::[Message] q::Decorated! QName +top::Expr ::= q::Decorated! QName { top.translation = error("Internal compiler error: translation not defined in the presence of errors"); top.lazyTranslation = top.translation; From 86341f364ae9342f8e5798d3d210595cbaa02a93 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 6 Mar 2024 17:24:11 -0600 Subject: [PATCH 170/283] Add defs for dispatch decls --- grammars/silver/compiler/definition/core/DispatchDcl.sv | 2 ++ grammars/silver/compiler/definition/env/Defs.sv | 2 ++ 2 files changed, 4 insertions(+) diff --git a/grammars/silver/compiler/definition/core/DispatchDcl.sv b/grammars/silver/compiler/definition/core/DispatchDcl.sv index 77395b8b1..ea8207620 100644 --- a/grammars/silver/compiler/definition/core/DispatchDcl.sv +++ b/grammars/silver/compiler/definition/core/DispatchDcl.sv @@ -5,6 +5,8 @@ top::AGDcl ::= 'dispatch' id::Name '=' sig::DispatchSignature ';' { top.unparse = "dispatch " ++ id.unparse ++ " = " ++ sig.unparse ++ ";"; + top.defs := [dispatchDef(top.grammarName, id.nameLoc, sig.namedSignature)]; + production fName :: String = top.grammarName ++ ":" ++ id.name; sig.signatureName = fName; sig.env = newScopeEnv(sig.defs, top.env); diff --git a/grammars/silver/compiler/definition/env/Defs.sv b/grammars/silver/compiler/definition/env/Defs.sv index 8c94bc60a..9df719c78 100644 --- a/grammars/silver/compiler/definition/env/Defs.sv +++ b/grammars/silver/compiler/definition/env/Defs.sv @@ -151,6 +151,8 @@ fun aspectLexTyVarDef Def ::= sg::String sl::Location fn::String tv::TyVar = fun typeAliasDef Def ::= sg::String sl::Location fn::String mentionedAliases::[String] bound::[TyVar] ty::Type = typeDef(defaultEnvItem(typeAliasDcl(fn,mentionedAliases,bound,ty,sourceGrammar=sg,sourceLocation=sl))); +fun dispatchDef Def ::= sg::String sl::Location sig::NamedSignature = + typeDef(defaultEnvItem(dispatchDcl(sig,sourceGrammar=sg,sourceLocation=sl))); fun synDef Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type = attrDef(defaultEnvItem(synDcl(fn,bound,ty,sourceGrammar=sg,sourceLocation=sl))); fun inhDef Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type = From 878e695f3d8320223fd111b6f9afcb53f7ae388f Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 6 Mar 2024 18:49:15 -0600 Subject: [PATCH 171/283] Fix signature type checking bugs --- .../analysis/typechecking/core/AspectDcl.sv | 4 ++-- .../typechecking/core/ProductionDcl.sv | 4 ++-- .../compiler/definition/core/AspectDcl.sv | 4 ++-- .../compiler/definition/env/NamedSignature.sv | 21 +++++++++++++++---- .../compiler/extension/autoattr/Propagate.sv | 4 ++-- 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/grammars/silver/compiler/analysis/typechecking/core/AspectDcl.sv b/grammars/silver/compiler/analysis/typechecking/core/AspectDcl.sv index b938285c1..6b8177bd6 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/AspectDcl.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/AspectDcl.sv @@ -8,7 +8,7 @@ top::AGDcl ::= 'aspect' 'production' id::QName ns::AspectProductionSignature bod { local attribute errCheck1 :: TypeCheck; errCheck1.finalSubst = ns.finalSubst; - errCheck1 = check(realSig.typeScheme.typerep, namedSig.typeScheme.typerep); + errCheck1 = check(realSig.dclTypeScheme.typerep, namedSig.dclTypeScheme.typerep); top.errors <- if errCheck1.typeerror then [errFromOrigin(top, "Aspect for '" ++ id.name ++ "' does not have the right signature.\nExpected: " @@ -34,7 +34,7 @@ top::AGDcl ::= 'aspect' 'function' id::QName ns::AspectFunctionSignature body::P { local attribute errCheck1 :: TypeCheck; errCheck1.finalSubst = ns.finalSubst; - errCheck1 = check(realSig.typeScheme.typerep, namedSig.typeScheme.typerep); + errCheck1 = check(realSig.dclTypeScheme.typerep, namedSig.dclTypeScheme.typerep); top.errors <- if errCheck1.typeerror then [errFromOrigin(top, "Aspect for '" ++ id.name ++ "' does not have the right signature.\nExpected: " diff --git a/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv b/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv index b4d6a80a7..cb6897f4d 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv @@ -15,7 +15,7 @@ top::ProductionLHS ::= id::Name '::' t::TypeExpr checkNT.downSubst = emptySubst(); checkNT.finalSubst = emptySubst(); - local checkImplementedSig::TypeCheck = check(t.typerep, top.implementedSig.fromJust.typerep); + local checkImplementedSig::TypeCheck = check(t.typerep, top.implementedSig.fromJust.elementDclType); checkImplementedSig.downSubst = emptySubst(); checkImplementedSig.finalSubst = emptySubst(); @@ -35,7 +35,7 @@ top::ProductionRHSElem ::= id::Name '::' t::TypeExpr { top.errors <- t.errorsKindStar; - local checkImplementedSig::TypeCheck = check(t.typerep, top.implementedSig.fromJust.typerep); + local checkImplementedSig::TypeCheck = check(t.typerep, top.implementedSig.fromJust.elementDclType); checkImplementedSig.downSubst = emptySubst(); checkImplementedSig.finalSubst = emptySubst(); diff --git a/grammars/silver/compiler/definition/core/AspectDcl.sv b/grammars/silver/compiler/definition/core/AspectDcl.sv index 001031d5d..20dae9399 100644 --- a/grammars/silver/compiler/definition/core/AspectDcl.sv +++ b/grammars/silver/compiler/definition/core/AspectDcl.sv @@ -195,7 +195,7 @@ top::AspectProductionLHS ::= id::Name t::Type production attribute fName :: String; fName = if null(top.realSignature) then id.name else head(top.realSignature).elementName; production attribute rType :: Type; - rType = if null(top.realSignature) then errorType() else head(top.realSignature).typerep; + rType = if null(top.realSignature) then errorType() else head(top.realSignature).elementDclType; top.outputElement = namedSignatureElement(id.name, t, false); @@ -276,7 +276,7 @@ top::AspectRHSElem ::= id::Name t::Type production attribute fName :: String; fName = if null(top.realSignature) then id.name else head(top.realSignature).elementName; production attribute rType :: Type; - rType = if null(top.realSignature) then errorType() else head(top.realSignature).typerep; + rType = if null(top.realSignature) then errorType() else head(top.realSignature).elementDclType; production shared::Boolean = !null(top.realSignature) && head(top.realSignature).elementShared; top.inputElements = [namedSignatureElement(id.name, t, shared)]; diff --git a/grammars/silver/compiler/definition/env/NamedSignature.sv b/grammars/silver/compiler/definition/env/NamedSignature.sv index 607f068a8..eee6263dc 100644 --- a/grammars/silver/compiler/definition/env/NamedSignature.sv +++ b/grammars/silver/compiler/definition/env/NamedSignature.sv @@ -7,7 +7,13 @@ grammar silver:compiler:definition:env; - TODO: we might want to remove the full name of the production from this, and make it just `Signature`? - It's not clear if this information really belongs here, or not. -} -data nonterminal NamedSignature with fullName, contexts, inputElements, outputElement, namedInputElements, typeScheme, freeVariables, inputNames, inputTypes, typerep, freshenNamedSignature; +data nonterminal NamedSignature with + fullName, contexts, inputElements, outputElement, namedInputElements, freeVariables, + inputNames, inputTypes, typeScheme, dclTypeScheme, typerep, freshenNamedSignature; + +-- The type scheme for the signature as written, without sharing. +synthesized attribute dclTypeScheme :: PolyType; +-- typeScheme has all shared children changed to Decorated types. synthesized attribute inputElements :: [NamedSignatureElement]; synthesized attribute outputElement :: NamedSignatureElement; @@ -39,6 +45,8 @@ top::NamedSignature ::= fn::String ctxs::Contexts ie::NamedSignatureElements oe: top.inputTypes = ie.elementTypes; -- Does anything actually use this? TODO: eliminate? local typerep::Type = appTypes(functionType(length(ie.elements), np.elementShortNames), ie.elementTypes ++ np.elementTypes ++ [oe.typerep]); top.typeScheme = (if null(ctxs.contexts) then polyType else constraintType(_, ctxs.contexts, _))(top.freeVariables, typerep); + local dclType::Type = appTypes(functionType(length(ie.elements), np.elementShortNames), ie.elementDclTypes ++ np.elementDclTypes ++ [oe.elementDclType]); + top.dclTypeScheme = (if null(ctxs.contexts) then polyType else constraintType(_, ctxs.contexts, _))(top.freeVariables, dclType); top.freeVariables = setUnionTyVars(ctxs.freeVariables, typerep.freeVariables); top.typerep = typerep; -- TODO: Only used by unifyNamedSignature. Would be nice to eliminate, somehow. @@ -91,13 +99,14 @@ fun bogusNamedSignature NamedSignature ::= = {-- - Represents a collection of NamedSignatureElements -} -nonterminal NamedSignatureElements with elements, elementNames, elementShortNames, elementTypes, freeVariables, boundVariables; +nonterminal NamedSignatureElements with elements, elementNames, elementShortNames, elementTypes, elementDclTypes, freeVariables, boundVariables; propagate boundVariables on NamedSignatureElements; synthesized attribute elements::[NamedSignatureElement]; synthesized attribute elementNames::[String]; synthesized attribute elementShortNames::[String]; synthesized attribute elementTypes::[Type]; +synthesized attribute elementDclTypes::[Type]; abstract production consNamedSignatureElement top::NamedSignatureElements ::= h::NamedSignatureElement t::NamedSignatureElements @@ -106,6 +115,7 @@ top::NamedSignatureElements ::= h::NamedSignatureElement t::NamedSignatureElemen top.elementNames = h.elementName :: t.elementNames; top.elementShortNames = h.elementShortName :: t.elementShortNames; top.elementTypes = h.typerep :: t.elementTypes; + top.elementDclTypes = h.elementDclType :: t.elementDclTypes; top.freeVariables = setUnionTyVars(h.freeVariables, t.freeVariables); } @@ -116,6 +126,7 @@ top::NamedSignatureElements ::= top.elementNames = []; top.elementShortNames = []; top.elementTypes = []; + top.elementDclTypes = []; top.freeVariables = []; } @@ -125,10 +136,11 @@ global foldNamedSignatureElements::(NamedSignatureElements ::= [NamedSignatureEl {-- - Represents an elements of a signature, whether input, output, or annotation. -} -nonterminal NamedSignatureElement with elementName, elementShortName, elementShared, typerep, freeVariables, boundVariables; +nonterminal NamedSignatureElement with elementName, elementShortName, elementShared, elementDclType, typerep, freeVariables, boundVariables; propagate boundVariables on NamedSignatureElement; synthesized attribute elementName :: String; +synthesized attribute elementDclType :: Type; synthesized attribute elementShortName :: String; synthesized attribute elementShared :: Boolean; @@ -139,7 +151,8 @@ abstract production namedSignatureElement top::NamedSignatureElement ::= n::String ty::Type shared::Boolean { top.elementName = n; - top.typerep = if shared then decoratedType(inhSetType([]), ty) else ty; + top.elementDclType = ty; + top.typerep = if shared then decoratedType(ty, inhSetType([])) else ty; top.elementShared = shared; top.freeVariables = ty.freeVariables; diff --git a/grammars/silver/compiler/extension/autoattr/Propagate.sv b/grammars/silver/compiler/extension/autoattr/Propagate.sv index 5263ae4c5..b8128ec9c 100644 --- a/grammars/silver/compiler/extension/autoattr/Propagate.sv +++ b/grammars/silver/compiler/extension/autoattr/Propagate.sv @@ -83,7 +83,7 @@ top::AGDcl ::= d::ValueDclInfo attrs::NameList aspectProductionSignature( aspectProductionLHSFull( name(d.namedSignature.outputElement.elementName), - d.namedSignature.outputElement.typerep), + d.namedSignature.outputElement.elementDclType), '::=', foldr( aspectRHSElemCons(_, _), @@ -92,7 +92,7 @@ top::AGDcl ::= d::ValueDclInfo attrs::NameList \ ie::NamedSignatureElement -> aspectRHSElemFull( name(ie.elementName), - freshenType(ie.typerep, ie.typerep.freeVariables)), + freshenType(ie.elementDclType, ie.typerep.freeVariables)), d.namedSignature.inputElements))), productionBody( '{', From 8568aa59db4a3589605ce851c198e0333ad165e4 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 7 Mar 2024 11:01:29 -0600 Subject: [PATCH 172/283] Revert "Change signature of errorReference" This reverts commit c69f4677511fad8604dc69a036cba8ef41a9e24d. --- grammars/silver/compiler/definition/core/Expr.sv | 9 +++++---- .../silver/compiler/extension/implicit_monads/Expr.sv | 4 ++-- grammars/silver/compiler/translation/java/core/Expr.sv | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index f7c0e5a0a..7db2765de 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -90,7 +90,7 @@ top::Expr ::= q::QName propagate env; forwards to if null(q.lookupValue.dcls) - then errorReference(q) + then errorReference(q.lookupValue.errors, q) else q.lookupValue.dcl.refDispatcher(q); } action { if (contains(q.name, sigNames)) { @@ -99,16 +99,17 @@ top::Expr ::= q::QName } abstract production errorReference -top::Expr ::= q::Decorated! QName +top::Expr ::= msg::[Message] q::Decorated! QName { - undecorates to baseExpr(q); + undecorates to errorExpr(msg); -- TODO: Should this be baseExpr? top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); - top.errors <- q.lookupValue.errors; + top.errors <- msg; top.typerep = errorType(); } +-- TODO: We should separate this out, even, to be "nonterminal/decorable" and "as-is" abstract production childReference top::Expr ::= q::Decorated! QName { diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index 3628826bb..bf7bea9bc 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -43,9 +43,9 @@ top::Expr ::= e::[Message] } aspect production errorReference -top::Expr ::= q::Decorated! QName +top::Expr ::= msg::[Message] q::Decorated! QName { - top.merrors := q.lookupValue.errors; + top.merrors := msg; propagate mDownSubst, mUpSubst; top.mtyperep = errorType(); top.monadicNames = []; diff --git a/grammars/silver/compiler/translation/java/core/Expr.sv b/grammars/silver/compiler/translation/java/core/Expr.sv index 162421ff2..a451848d8 100644 --- a/grammars/silver/compiler/translation/java/core/Expr.sv +++ b/grammars/silver/compiler/translation/java/core/Expr.sv @@ -58,7 +58,7 @@ top::Expr ::= msg::[Message] } aspect production errorReference -top::Expr ::= q::Decorated! QName +top::Expr ::= msg::[Message] q::Decorated! QName { top.translation = error("Internal compiler error: translation not defined in the presence of errors"); top.lazyTranslation = top.translation; From 529a364fcbf9b67b2bfb75d8be0e5bdc2483db9f Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 7 Mar 2024 16:11:55 -0600 Subject: [PATCH 173/283] Changes to allow sharing in arbitrary production signatures --- .../analysis/typechecking/core/AspectDcl.sv | 7 +- .../typechecking/core/ProductionDcl.sv | 8 ++- .../concrete_syntax/ProductionDcl.sv | 5 +- .../compiler/definition/core/AspectDcl.sv | 42 ++++++++--- .../compiler/definition/core/DispatchDcl.sv | 69 +------------------ .../compiler/definition/core/FunctionDcl.sv | 5 ++ .../compiler/definition/core/ProductionDcl.sv | 35 +++++++--- .../compiler/definition/env/NamedSignature.sv | 1 + .../definition/flow/env/ProductionDcl.sv | 8 ++- .../definition/type/syntax/AspectDcl.sv | 6 ++ .../compiler/extension/autoattr/Propagate.sv | 1 + .../extension/constructparser/Construct.sv | 4 +- .../convenienceaspects/AbstractSyntax.sv | 24 +------ .../compiler/extension/doc/core/AGDcl.sv | 2 +- .../compiler/extension/doc/core/ArgNames.sv | 6 +- .../extension/easyterminal/TerminalDcl.sv | 10 +-- .../extension/testing/MainTestSuite.sv | 3 +- grammars/silver/compiler/host/Project.sv | 2 +- .../compiler/langserver/ReferenceLocations.sv | 7 +- .../concisefunctions/ConciseFunctions.sv | 4 +- .../modification/copper/ActionCode.sv | 2 +- 21 files changed, 116 insertions(+), 135 deletions(-) diff --git a/grammars/silver/compiler/analysis/typechecking/core/AspectDcl.sv b/grammars/silver/compiler/analysis/typechecking/core/AspectDcl.sv index 6b8177bd6..a74bbbb1d 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/AspectDcl.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/AspectDcl.sv @@ -88,7 +88,7 @@ top::AspectRHS ::= h::AspectRHSElem t::AspectRHS } aspect production aspectRHSElemFull -top::AspectRHSElem ::= id::Name t::Type +top::AspectRHSElem ::= shared::Boolean id::Name t::Type { local attribute errCheck1 :: TypeCheck; errCheck1.finalSubst = top.finalSubst; @@ -99,6 +99,11 @@ top::AspectRHSElem ::= id::Name t::Type if errCheck1.typeerror then [errFromOrigin(top, "Type incorrect in aspect signature. Expected: " ++ errCheck1.leftpp ++ " Got: " ++ errCheck1.rightpp)] else []; + + top.errors <- + if !null(top.realSignature) && head(top.realSignature).elementShared != shared + then [errFromOrigin(top, "Sharedness incorrect in aspect signature.")] + else []; } aspect production aspectFunctionSignature diff --git a/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv b/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv index cb6897f4d..9cdf27b27 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv @@ -31,7 +31,7 @@ top::ProductionLHS ::= id::Name '::' t::TypeExpr } aspect production productionRHSElem -top::ProductionRHSElem ::= id::Name '::' t::TypeExpr +top::ProductionRHSElem ::= ms::MaybeShared id::Name '::' t::TypeExpr { top.errors <- t.errorsKindStar; @@ -39,6 +39,12 @@ top::ProductionRHSElem ::= id::Name '::' t::TypeExpr checkImplementedSig.downSubst = emptySubst(); checkImplementedSig.finalSubst = emptySubst(); + top.errors <- + case top.implementedSig of + | just(e) when e.elementShared != ms.elementShared -> + [errFromOrigin(top, s"Child ${id.name} does not match the sharedness from the implemented dispatch signature.")] + | _ -> [] + end; top.errors <- if top.implementedSig.isJust && checkImplementedSig.typeerror then [errFromOrigin(top, "Child " ++ id.name ++ " does not match the type from the implemented dispatch signature " ++ checkImplementedSig.rightpp ++ ". Instead it is of type " ++ checkImplementedSig.leftpp)] diff --git a/grammars/silver/compiler/definition/concrete_syntax/ProductionDcl.sv b/grammars/silver/compiler/definition/concrete_syntax/ProductionDcl.sv index 605aef939..8d7b2ad81 100644 --- a/grammars/silver/compiler/definition/concrete_syntax/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/concrete_syntax/ProductionDcl.sv @@ -139,11 +139,14 @@ top::ProductionSignature ::= cl::ConstraintList '=>' lhs::ProductionLHS '::=' rh } aspect production productionRHSElem -top::ProductionRHSElem ::= id::Name '::' t::TypeExpr +top::ProductionRHSElem ::= ms::MaybeShared id::Name '::' t::TypeExpr { top.concreteSyntaxTypeErrors <- if t.typerep.permittedInConcreteSyntax then [] else [errFromOrigin(t, t.unparse ++ " is not permitted on concrete productions. Only terminals and nonterminals (without type variables) can appear here")]; + top.concreteSyntaxTypeErrors <- + if ms.elementShared then [errFromOrigin(ms, "Sharing is not permitted in concrete productions.")] + else []; } synthesized attribute permittedInConcreteSyntax :: Boolean occurs on Type; diff --git a/grammars/silver/compiler/definition/core/AspectDcl.sv b/grammars/silver/compiler/definition/core/AspectDcl.sv index 20dae9399..4f4cf4569 100644 --- a/grammars/silver/compiler/definition/core/AspectDcl.sv +++ b/grammars/silver/compiler/definition/core/AspectDcl.sv @@ -236,23 +236,31 @@ top::AspectRHSElem ::= '_' production attribute rType :: Type; rType = if null(top.realSignature) then errorType() else head(top.realSignature).typerep; + production shared :: Boolean = !null(top.realSignature) && head(top.realSignature).elementShared; - forwards to aspectRHSElemFull(name("p_" ++ toString(top.deterministicCount)), rType); + forwards to aspectRHSElemFull(shared, name("p_" ++ toString(top.deterministicCount)), rType); } -concrete production aspectRHSElemId +concrete production aspectRHSElemIdConcrete +top::AspectRHSElem ::= id::Name +{ + top.errors <- [wrnFromOrigin(top, "Giving just a name '" ++ id.name ++ "' is deprecated in aspect signature. Please explicitly use a name and type.")]; + + forwards to aspectRHSElemId(@id); +} action { + insert semantic token IdSigNameDcl_t at id.nameLoc; +} + +abstract production aspectRHSElemId top::AspectRHSElem ::= id::Name { top.unparse = id.unparse; production attribute rType :: Type; rType = if null(top.realSignature) then errorType() else head(top.realSignature).typerep; + production shared :: Boolean = !null(top.realSignature) && head(top.realSignature).elementShared; - top.errors <- [wrnFromOrigin(top, "Giving just a name '" ++ id.name ++ "' is deprecated in aspect signature. Please explicitly use a name and type.")]; - - forwards to aspectRHSElemFull(id, rType); -} action { - insert semantic token IdSigNameDcl_t at id.nameLoc; + forwards to aspectRHSElemFull(shared, id, rType); } concrete production aspectRHSElemTyped @@ -263,21 +271,33 @@ top::AspectRHSElem ::= id::Name '::' t::TypeExpr top.errors <- t.errors; - forwards to aspectRHSElemFull(id, t.typerep); + forwards to aspectRHSElemFull(false, @id, t.typerep); +} action { + insert semantic token IdSigNameDcl_t at id.nameLoc; +} + +concrete production aspectRHSElemSharedTyped +top::AspectRHSElem ::= '@' id::Name '::' t::TypeExpr +{ + top.unparse = "@" ++ id.unparse ++ "::" ++ t.unparse; + propagate env, grammarName, config; + + top.errors <- t.errors; + + forwards to aspectRHSElemFull(true, @id, t.typerep); } action { insert semantic token IdSigNameDcl_t at id.nameLoc; } abstract production aspectRHSElemFull -top::AspectRHSElem ::= id::Name t::Type +top::AspectRHSElem ::= shared::Boolean id::Name t::Type { - top.unparse = id.unparse ++ "::" ++ prettyType(t); + top.unparse = (if shared then "@" else "") ++ id.unparse ++ "::" ++ prettyType(t); production attribute fName :: String; fName = if null(top.realSignature) then id.name else head(top.realSignature).elementName; production attribute rType :: Type; rType = if null(top.realSignature) then errorType() else head(top.realSignature).elementDclType; - production shared::Boolean = !null(top.realSignature) && head(top.realSignature).elementShared; top.inputElements = [namedSignatureElement(id.name, t, shared)]; diff --git a/grammars/silver/compiler/definition/core/DispatchDcl.sv b/grammars/silver/compiler/definition/core/DispatchDcl.sv index ea8207620..d6b04d4b9 100644 --- a/grammars/silver/compiler/definition/core/DispatchDcl.sv +++ b/grammars/silver/compiler/definition/core/DispatchDcl.sv @@ -1,7 +1,7 @@ grammar silver:compiler:definition:core; concrete production dispatchSigDcl -top::AGDcl ::= 'dispatch' id::Name '=' sig::DispatchSignature ';' +top::AGDcl ::= 'dispatch' id::Name '=' sig::ProductionSignature ';' { top.unparse = "dispatch " ++ id.unparse ++ " = " ++ sig.unparse ++ ";"; @@ -9,6 +9,7 @@ top::AGDcl ::= 'dispatch' id::Name '=' sig::DispatchSignature ';' production fName :: String = top.grammarName ++ ":" ++ id.name; sig.signatureName = fName; + sig.implementedSig = nothing(); sig.env = newScopeEnv(sig.defs, top.env); top.errors <- @@ -21,69 +22,3 @@ top::AGDcl ::= 'dispatch' id::Name '=' sig::DispatchSignature ';' then [errFromOrigin(id, "Types must be capitalized. Invalid dispatch name " ++ id.name)] else []; } - -nonterminal DispatchSignature with config, grammarName, defs, env, unparse, errors, signatureName, namedSignature; -nonterminal DispatchRHS with config, grammarName, defs, env, unparse, errors, inputElements, elementCount; -nonterminal DispatchRHSElem with config, grammarName, defs, env, unparse, errors, inputElements, deterministicCount; -propagate config, grammarName, defs, env, errors on DispatchSignature, DispatchRHS, DispatchRHSElem; - -concrete production dispatchSignature -top::DispatchSignature ::= lhs::ProductionLHS '::=' rhs::DispatchRHS -{ - top.unparse = lhs.unparse ++ " ::= " ++ rhs.unparse; - top.namedSignature = - namedSignature( - top.signatureName, - nilContext(), - foldNamedSignatureElements(rhs.inputElements), - lhs.outputElement, - foldNamedSignatureElements(annotationsForNonterminal(lhs.outputElement.typerep, top.env))); - lhs.implementedSig = nothing(); -} - -concrete production dispatchRHSNil -top::DispatchRHS ::= -{ - top.unparse = ""; - - top.inputElements = []; - top.elementCount = 0; -} - -concrete production dispatchRHSCons -top::DispatchRHS ::= h::DispatchRHSElem t::DispatchRHS -{ - top.unparse = h.unparse ++ " " ++ t.unparse; - - top.inputElements = h.inputElements ++ t.inputElements; - top.elementCount = 1 + t.elementCount; - h.deterministicCount = t.elementCount; -} - -concrete production dispatchRHSElem -top::DispatchRHSElem ::= ms::MaybeShared id::Name '::' t::TypeExpr -{ - top.unparse = ms.unparse ++ id.unparse ++ "::" ++ t.unparse; - - top.inputElements = [namedSignatureElement(id.name, t.typerep, ms.elementShared)]; - - top.defs <- [childDef(top.grammarName, id.nameLoc, id.name, t.typerep)]; - - top.errors <- - if length(getValueDclInScope(id.name, top.env)) > 1 - then [errFromOrigin(id, "Value '" ++ id.name ++ "' is already bound.")] - else []; -} - -concrete production dispatchRHSElemType -top::DispatchRHSElem ::= ms::MaybeShared t::TypeExpr -{ - top.unparse = t.unparse; - - forwards to dispatchRHSElem(@ms, name("_G_" ++ toString(top.deterministicCount)), '::', @t); -} - -nonterminal MaybeShared with unparse, elementShared; -concrete productions top::MaybeShared -| '@' { top.unparse = "@"; top.elementShared = true; } -| { top.unparse = ""; top.elementShared = false; } diff --git a/grammars/silver/compiler/definition/core/FunctionDcl.sv b/grammars/silver/compiler/definition/core/FunctionDcl.sv index 48b35acb4..40d6b41c6 100644 --- a/grammars/silver/compiler/definition/core/FunctionDcl.sv +++ b/grammars/silver/compiler/definition/core/FunctionDcl.sv @@ -68,6 +68,11 @@ top::FunctionSignature ::= cl::ConstraintList '=>' lhs::FunctionLHS '::=' rhs::P lhs.outputElement, -- For the moment, functions do not have named parameters (hence, nilNamedSignatureElement) nilNamedSignatureElement()); + + top.errors <- + if any(map((.elementShared), rhs.inputElements)) + then [errFromOrigin(rhs, "Sharing in function parameters is not permitted.")] + else []; } action { sigNames = foldNamedSignatureElements(rhs.inputElements).elementNames; } diff --git a/grammars/silver/compiler/definition/core/ProductionDcl.sv b/grammars/silver/compiler/definition/core/ProductionDcl.sv index 27031e9c4..fea2f85eb 100644 --- a/grammars/silver/compiler/definition/core/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/core/ProductionDcl.sv @@ -180,6 +180,14 @@ top::ProductionLHS ::= id::Name '::' t::TypeExpr insert semantic token IdSigNameDcl_t at id.nameLoc; } +concrete production productionLHSType +top::ProductionLHS ::= t::TypeExpr +{ + top.unparse = t.unparse; + + forwards to productionLHS(name("_G_lhs"), '::', @t); +} + concrete production productionRHSNil top::ProductionRHS ::= { @@ -205,17 +213,12 @@ top::ProductionRHS ::= h::ProductionRHSElem t::ProductionRHS } concrete production productionRHSElem -top::ProductionRHSElem ::= id::Name '::' t::TypeExpr +top::ProductionRHSElem ::= ms::MaybeShared id::Name '::' t::TypeExpr { - top.unparse = id.unparse ++ "::" ++ t.unparse; + top.unparse = ms.unparse ++ id.unparse ++ "::" ++ t.unparse; propagate env; - local shared::Boolean = - case top.implementedSig of - | just(e) -> e.elementShared - | nothing() -> false - end; - top.inputElements = [namedSignatureElement(id.name, t.typerep, shared)]; + top.inputElements = [namedSignatureElement(id.name, t.typerep, ms.elementShared)]; top.defs := [childDef(top.grammarName, id.nameLoc, id.name, t.typerep)]; @@ -228,10 +231,20 @@ top::ProductionRHSElem ::= id::Name '::' t::TypeExpr } concrete production productionRHSElemType -top::ProductionRHSElem ::= t::TypeExpr +top::ProductionRHSElem ::= ms::MaybeShared t::TypeExpr { - top.unparse = t.unparse; + top.unparse = ms.unparse ++ t.unparse; - forwards to productionRHSElem(name("_G_" ++ toString(top.deterministicCount)), '::', t); + forwards to productionRHSElem(@ms, name("_G_" ++ toString(top.deterministicCount)), '::', @t); } +tracked nonterminal MaybeShared with unparse, elementShared; + +concrete production elemShared +top::MaybeShared ::= '@' +{ top.unparse = "@"; top.elementShared = true; } + +concrete production elemNotShared +top::MaybeShared ::= +{ top.unparse = ""; top.elementShared = false; } + diff --git a/grammars/silver/compiler/definition/env/NamedSignature.sv b/grammars/silver/compiler/definition/env/NamedSignature.sv index eee6263dc..5a31a891d 100644 --- a/grammars/silver/compiler/definition/env/NamedSignature.sv +++ b/grammars/silver/compiler/definition/env/NamedSignature.sv @@ -80,6 +80,7 @@ top::NamedSignature ::= fn::String ctxs::Contexts ty::Type top.inputNames = error("Not a production or function"); top.inputTypes = ty.inputTypes; -- Does anything actually use this? TODO: eliminate? top.typeScheme = (if null(ctxs.contexts) then polyType else constraintType(_, ctxs.contexts, _))(top.freeVariables, ty); + top.dclTypeScheme = top.typeScheme; top.freeVariables = setUnionTyVars(ctxs.freeVariables, ty.freeVariables); top.typerep = ty; diff --git a/grammars/silver/compiler/definition/flow/env/ProductionDcl.sv b/grammars/silver/compiler/definition/flow/env/ProductionDcl.sv index 8d0ca46dd..9befa2116 100644 --- a/grammars/silver/compiler/definition/flow/env/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/flow/env/ProductionDcl.sv @@ -9,12 +9,10 @@ import silver:compiler:definition:flow:driver; import silver:compiler:driver:util; -- only for productionFlowGraphs occurrence? attribute flowEnv occurs on - DispatchSignature, DispatchRHS, DispatchRHSElem, ProductionImplements, ProductionSignature, ProductionLHS, ProductionRHS, ProductionRHSElem, AspectProductionSignature, AspectProductionLHS, AspectFunctionSignature, AspectFunctionLHS, AspectRHS, AspectRHSElem; propagate flowEnv on - DispatchSignature, DispatchRHS, DispatchRHSElem, ProductionImplements, ProductionSignature, ProductionLHS, ProductionRHS, ProductionRHSElem, AspectProductionSignature, AspectProductionLHS, AspectFunctionSignature, AspectFunctionLHS, AspectRHS, AspectRHSElem; @@ -73,3 +71,9 @@ top::AspectRHSElem ::= id::Name '::' t::TypeExpr { propagate flowEnv; } + +aspect production aspectRHSElemSharedTyped +top::AspectRHSElem ::= '@' id::Name '::' t::TypeExpr +{ + propagate flowEnv; +} diff --git a/grammars/silver/compiler/definition/type/syntax/AspectDcl.sv b/grammars/silver/compiler/definition/type/syntax/AspectDcl.sv index 8df5d7e4d..d75e33866 100644 --- a/grammars/silver/compiler/definition/type/syntax/AspectDcl.sv +++ b/grammars/silver/compiler/definition/type/syntax/AspectDcl.sv @@ -59,6 +59,12 @@ top::AspectRHSElem ::= id::Name '::' t::TypeExpr propagate lexicalTypeVariables, lexicalTyVarKinds; } +aspect production aspectRHSElemSharedTyped +top::AspectRHSElem ::= '@' id::Name '::' t::TypeExpr +{ + propagate lexicalTypeVariables, lexicalTyVarKinds; +} + aspect production aspectFunctionSignature top::AspectFunctionSignature ::= lhs::AspectFunctionLHS '::=' rhs::AspectRHS { diff --git a/grammars/silver/compiler/extension/autoattr/Propagate.sv b/grammars/silver/compiler/extension/autoattr/Propagate.sv index b8128ec9c..af62f59ab 100644 --- a/grammars/silver/compiler/extension/autoattr/Propagate.sv +++ b/grammars/silver/compiler/extension/autoattr/Propagate.sv @@ -91,6 +91,7 @@ top::AGDcl ::= d::ValueDclInfo attrs::NameList map( \ ie::NamedSignatureElement -> aspectRHSElemFull( + ie.elementShared, name(ie.elementName), freshenType(ie.elementDclType, ie.typerep.freeVariables)), d.namedSignature.inputElements))), diff --git a/grammars/silver/compiler/extension/constructparser/Construct.sv b/grammars/silver/compiler/extension/constructparser/Construct.sv index 57a720683..003a321a7 100644 --- a/grammars/silver/compiler/extension/constructparser/Construct.sv +++ b/grammars/silver/compiler/extension/constructparser/Construct.sv @@ -42,10 +42,10 @@ top::Root ::= gdcl::GrammarDcl mStmts::ModuleStmts is::ImportStmts bTypeList('<', typeListSingle(integerTypeExpr('Integer')), '>'))), '::=', productionRHSCons( - productionRHSElem(name("args"), '::', + productionRHSElem(elemNotShared(), name("args"), '::', listTypeExpr('[', stringTypeExpr('String'), ']')), productionRHSCons( - productionRHSElem(name("ioIn"), '::', + productionRHSElem(elemNotShared(), name("ioIn"), '::', nominalTypeExpr(qNameTypeId(terminal(IdUpper_t, "IOToken")))), productionRHSNil()))), productionBody('{', diff --git a/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv b/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv index 6d9a8b2e4..794f21dfb 100644 --- a/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv +++ b/grammars/silver/compiler/extension/convenienceaspects/AbstractSyntax.sv @@ -200,20 +200,6 @@ Pair ::= rules::[MatchRule] aspectLHS::Decorated ConvAspectLHS { attachNote if null(rules) then logicalLocationFromOrigin(aspectLHS) else logicalLocationFromOrigin(head(rules)); - local lookupProdInputTypes::([Type] ::= String) = \prodName::String -> - case (getValueDcl(prodName,env)) of - -- Productions that aren't in scope, and names that - -- aren't productions will be caught later in the primitive match. - | [] -> [] - | dcl:: _ -> - if dcl.typeScheme.typerep.isApplicable - then dcl.typeScheme.typerep.inputTypes - else [] - end; - - local makeAspectRHSElemListFromNameAndTypeLists::([AspectRHSElem] ::= [Name] [Type]) = - zipWith(aspectRHSElemFull, _, _); - local makeAspectRHSFromParamsList::(AspectRHS ::= [AspectRHSElem] ) = foldr(aspectRHSElemCons, aspectRHSElemNil(), _); @@ -280,10 +266,7 @@ Pair ::= rules::[MatchRule] aspectLHS::Decorated ConvAspectLHS makeBaseExprFromQNames(makeQNamesFromNames(paramNames)), rules), name, - makeAspectRHSFromParamsList( - makeAspectRHSElemListFromNameAndTypeLists( - paramNames, - lookupProdInputTypes(name.name)))), + makeAspectRHSFromParamsList(map(aspectRHSElemId, paramNames))), []) end | matchRule_c(patternList_more(prodAppPattern(name,_,_,_),_,_),_,e) :: _ @@ -296,10 +279,7 @@ Pair ::= rules::[MatchRule] aspectLHS::Decorated ConvAspectLHS makeBaseExprFromQNames(makeQNamesFromNames(paramNames)), rules), name, - makeAspectRHSFromParamsList( - makeAspectRHSElemListFromNameAndTypeLists( - paramNames, - lookupProdInputTypes(name.name)))), + makeAspectRHSFromParamsList(map(aspectRHSElemId, paramNames))), []) end -- Handling for wildcard patterns diff --git a/grammars/silver/compiler/extension/doc/core/AGDcl.sv b/grammars/silver/compiler/extension/doc/core/AGDcl.sv index 020c0cdd6..980ea6df3 100644 --- a/grammars/silver/compiler/extension/doc/core/AGDcl.sv +++ b/grammars/silver/compiler/extension/doc/core/AGDcl.sv @@ -43,7 +43,7 @@ top::AGDcl ::= 'aspect' 'function' id::QName ns::AspectFunctionSignature body::P } aspect production dispatchSigDcl -top::AGDcl ::= 'dispatch' id::Name '=' ns::DispatchSignature ';' +top::AGDcl ::= 'dispatch' id::Name '=' ns::ProductionSignature ';' { top.docForName = id.name; top.docUnparse = "`dispatch " ++ id.name ++ "`   (`" ++ ns.unparse ++ "`)"; diff --git a/grammars/silver/compiler/extension/doc/core/ArgNames.sv b/grammars/silver/compiler/extension/doc/core/ArgNames.sv index c15ee41eb..c61c6ac9e 100644 --- a/grammars/silver/compiler/extension/doc/core/ArgNames.sv +++ b/grammars/silver/compiler/extension/doc/core/ArgNames.sv @@ -29,13 +29,13 @@ top::ProductionRHS ::= h::ProductionRHSElem t::ProductionRHS } aspect production productionRHSElem -top::ProductionRHSElem ::= id::Name '::' t::TypeExpr +top::ProductionRHSElem ::= ms::MaybeShared id::Name '::' t::TypeExpr { top.argNames = [id.name]; } aspect production productionRHSElemType -top::ProductionRHSElem ::= t::TypeExpr +top::ProductionRHSElem ::= ms::MaybeShared t::TypeExpr { top.argNames = []; -- Don't consider unnamed parameters against count } @@ -75,7 +75,7 @@ top::AspectRHSElem ::= '_' } aspect production aspectRHSElemFull -top::AspectRHSElem ::= id::Name t::Type +top::AspectRHSElem ::= shared::Boolean id::Name t::Type { top.argNames = [id.name]; } diff --git a/grammars/silver/compiler/extension/easyterminal/TerminalDcl.sv b/grammars/silver/compiler/extension/easyterminal/TerminalDcl.sv index 609867b0f..4b791fccc 100644 --- a/grammars/silver/compiler/extension/easyterminal/TerminalDcl.sv +++ b/grammars/silver/compiler/extension/easyterminal/TerminalDcl.sv @@ -61,15 +61,15 @@ top::EasyTerminalRef ::= t::Terminal_t top.typerep = if null(top.dcls) then errorType() else head(top.dcls).typeScheme.monoType; } - +-- sharing doesn't make sense here, but we need MaybeShared here to avoid shift/reduce: concrete production productionRhsElemEasyReg -top::ProductionRHSElem ::= id::Name '::' reg::EasyTerminalRef +top::ProductionRHSElem ::= ms::MaybeShared id::Name '::' reg::EasyTerminalRef { - top.unparse = id.unparse ++ "::" ++ reg.unparse; + top.unparse = ms.unparse ++ id.unparse ++ "::" ++ reg.unparse; propagate env; top.errors <- reg.errors; - forwards to productionRHSElem(id, $2, typerepTypeExpr(reg.typerep)); + forwards to productionRHSElem(@ms, id, $3, typerepTypeExpr(reg.typerep)); } concrete production productionRhsElemTypeEasyReg @@ -79,7 +79,7 @@ top::ProductionRHSElem ::= reg::EasyTerminalRef propagate env; top.errors <- reg.errors; - forwards to productionRHSElemType(typerepTypeExpr(reg.typerep)); + forwards to productionRHSElemType(elemNotShared(), typerepTypeExpr(reg.typerep)); } concrete production aspectRHSElemEasyReg diff --git a/grammars/silver/compiler/extension/testing/MainTestSuite.sv b/grammars/silver/compiler/extension/testing/MainTestSuite.sv index 79528cf5d..6148bb1a5 100644 --- a/grammars/silver/compiler/extension/testing/MainTestSuite.sv +++ b/grammars/silver/compiler/extension/testing/MainTestSuite.sv @@ -69,9 +69,10 @@ top::AGDcl ::= 'mainTestSuite' nme::IdLower_t ';' bTypeList('<', typeListSingle(integerTypeExpr('Integer')), '>'))), '::=', productionRHSCons( - productionRHSElemType(listTypeExpr('[', stringTypeExpr('String'), ']')), + productionRHSElemType(elemNotShared(), listTypeExpr('[', stringTypeExpr('String'), ']')), productionRHSCons( productionRHSElem( + elemNotShared(), name("mainIO"), '::', typerepTypeExpr(ioForeignType)), productionRHSNil()))), diff --git a/grammars/silver/compiler/host/Project.sv b/grammars/silver/compiler/host/Project.sv index 82adc01b4..85f20987f 100644 --- a/grammars/silver/compiler/host/Project.sv +++ b/grammars/silver/compiler/host/Project.sv @@ -36,7 +36,7 @@ exports silver:compiler:extension:testing; exports silver:compiler:extension:auto_ast; exports silver:compiler:extension:templating; exports silver:compiler:extension:patternmatching; -exports silver:compiler:extension:treegen; +--exports silver:compiler:extension:treegen; exports silver:compiler:extension:autoattr; exports silver:compiler:extension:strategyattr; exports silver:compiler:extension:do_notation; diff --git a/grammars/silver/compiler/langserver/ReferenceLocations.sv b/grammars/silver/compiler/langserver/ReferenceLocations.sv index d3ca6d2f0..2f7c2ccfb 100644 --- a/grammars/silver/compiler/langserver/ReferenceLocations.sv +++ b/grammars/silver/compiler/langserver/ReferenceLocations.sv @@ -209,19 +209,20 @@ end; --RHS aspect valueRefLocs on top::ProductionRHSElem using <- of -| productionRHSElem(n, _, _) -> map(\dcl :: ValueDclInfo -> (n.nameLoc, dcl), getValueDcl(n.name, top.env)) +| productionRHSElem(_, n, _, _) -> map(\dcl :: ValueDclInfo -> (n.nameLoc, dcl), getValueDcl(n.name, top.env)) end; aspect valueRefLocs on top::AspectRHSElem using <- of -| aspectRHSElemFull(n, _) -> map(\dcl :: ValueDclInfo -> (n.nameLoc, dcl), getValueDcl(n.name, top.env)) +| aspectRHSElemFull(_, n, _) -> map(\dcl :: ValueDclInfo -> (n.nameLoc, dcl), getValueDcl(n.name, top.env)) end; aspect typeRefLocs on ProductionRHSElem using <- of -| productionRHSElem(_, _, t) -> t.typeRefLocs +| productionRHSElem(_, _, _, t) -> t.typeRefLocs end; aspect typeRefLocs on AspectRHSElem using <- of | aspectRHSElemTyped(_, _, t) -> t.typeRefLocs +| aspectRHSElemSharedTyped(_, _, _, t) -> t.typeRefLocs end; synthesized attribute valueFileRefLocs::map:Map; diff --git a/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv b/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv index c946c1d0c..6c6020a99 100644 --- a/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv +++ b/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv @@ -72,8 +72,8 @@ top::FunctionSignature ::= cl::ConstraintList '=>' lhs::FunctionLHS '::=' rhs::P } aspect shortFunctionDefs on top::ProductionRHSElem using := of -| productionRHSElem(id, _, t) -> [shortFunParamDef(top.grammarName, id.nameLoc, id.name, t.typerep)] -| productionRHSElemType(_) -> [] +| productionRHSElem(_, id, _, t) -> [shortFunParamDef(top.grammarName, id.nameLoc, id.name, t.typerep)] +| productionRHSElemType(_, _) -> [] end; abstract production shortFunParamReference diff --git a/grammars/silver/compiler/modification/copper/ActionCode.sv b/grammars/silver/compiler/modification/copper/ActionCode.sv index 787f16065..e47a86d6a 100644 --- a/grammars/silver/compiler/modification/copper/ActionCode.sv +++ b/grammars/silver/compiler/modification/copper/ActionCode.sv @@ -149,7 +149,7 @@ top::ProductionRHS ::= h::ProductionRHSElem t::ProductionRHS } aspect production productionRHSElem -top::ProductionRHSElem ::= id::Name '::' t::TypeExpr +top::ProductionRHSElem ::= ms::MaybeShared id::Name '::' t::TypeExpr { top.actionDefs = [actionChildDef(top.grammarName, id.nameLoc, id.name, t.typerep)]; } From 45c7211af3b042ee2954f6a7e39cd74d50bfd561 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 7 Mar 2024 16:15:20 -0600 Subject: [PATCH 174/283] Re-bootstrapping treegen extension step --- grammars/silver/compiler/extension/treegen/Arbitrary.sv | 3 ++- grammars/silver/compiler/host/Project.sv | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/grammars/silver/compiler/extension/treegen/Arbitrary.sv b/grammars/silver/compiler/extension/treegen/Arbitrary.sv index 7909d2e51..e39f03fc6 100644 --- a/grammars/silver/compiler/extension/treegen/Arbitrary.sv +++ b/grammars/silver/compiler/extension/treegen/Arbitrary.sv @@ -17,7 +17,7 @@ imports silver:compiler:metatranslation; import silver:util:treemap as tm; terminal Generator_t 'generator' lexer classes {KEYWORD}; - +{- concrete production generatorDcl top::AGDcl ::= 'generator' n::Name '::' t::TypeExpr '{' grammars::GeneratorComponents '}' { @@ -318,3 +318,4 @@ Expr ::= env::Env specEnv::Env nt::String index::Integer lst::[ValueDclInfo] else $Expr{generateExprChain(env, specEnv, nt, index + 1, tail(lst))} }; } +-} \ No newline at end of file diff --git a/grammars/silver/compiler/host/Project.sv b/grammars/silver/compiler/host/Project.sv index 85f20987f..82adc01b4 100644 --- a/grammars/silver/compiler/host/Project.sv +++ b/grammars/silver/compiler/host/Project.sv @@ -36,7 +36,7 @@ exports silver:compiler:extension:testing; exports silver:compiler:extension:auto_ast; exports silver:compiler:extension:templating; exports silver:compiler:extension:patternmatching; ---exports silver:compiler:extension:treegen; +exports silver:compiler:extension:treegen; exports silver:compiler:extension:autoattr; exports silver:compiler:extension:strategyattr; exports silver:compiler:extension:do_notation; From 1ff5e56fbb256fd054ec307da6f9114394a1ffd0 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 7 Mar 2024 16:29:34 -0600 Subject: [PATCH 175/283] Finish bootstrap of treegen --- grammars/silver/compiler/extension/treegen/Arbitrary.sv | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/grammars/silver/compiler/extension/treegen/Arbitrary.sv b/grammars/silver/compiler/extension/treegen/Arbitrary.sv index e39f03fc6..7909d2e51 100644 --- a/grammars/silver/compiler/extension/treegen/Arbitrary.sv +++ b/grammars/silver/compiler/extension/treegen/Arbitrary.sv @@ -17,7 +17,7 @@ imports silver:compiler:metatranslation; import silver:util:treemap as tm; terminal Generator_t 'generator' lexer classes {KEYWORD}; -{- + concrete production generatorDcl top::AGDcl ::= 'generator' n::Name '::' t::TypeExpr '{' grammars::GeneratorComponents '}' { @@ -318,4 +318,3 @@ Expr ::= env::Env specEnv::Env nt::String index::Integer lst::[ValueDclInfo] else $Expr{generateExprChain(env, specEnv, nt, index + 1, tail(lst))} }; } --} \ No newline at end of file From 2bb16c4e791c9b5feb9bc359dad2203d435e78e5 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 7 Mar 2024 17:53:55 -0600 Subject: [PATCH 176/283] Handle dispatch implementation productions in pattern matching --- .../extension/patternmatching/PatternTypes.sv | 7 +++++-- .../primitivepattern/PrimitiveMatch.sv | 17 ++++++++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv b/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv index 537709756..04285b154 100644 --- a/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv +++ b/grammars/silver/compiler/extension/patternmatching/PatternTypes.sv @@ -73,7 +73,7 @@ top::Pattern ::= prod::QName '(' ps::PatternList ',' nps::NamedPatternList ')' { top.unparse = prod.unparse ++ "(" ++ ps.unparse ++ (if ps.count > 0 && nps.count > 0 then ", " else "") ++ nps.unparse ++ ")"; - local parms :: Integer = prod.lookupValue.typeScheme.arity; + local parms :: Integer = length(prod.lookupValue.dcl.namedSignature.inputElements); top.errors <- if null(prod.lookupValue.dcls) || length(ps.patternList) == parms then [] @@ -92,7 +92,10 @@ top::Pattern ::= prod::QName '(' ps::PatternList ',' nps::NamedPatternList ')' top.isPrimitivePattern = false; top.isBoolPattern = false; top.isListPattern = false; - top.patternTypeName = prod.lookupValue.typeScheme.typerep.outputType.baseType.typeName; + top.patternTypeName = + if prod.lookupValue.found + then prod.lookupValue.dcl.namedSignature.outputElement.typerep.typeName + else ""; } concrete production prodAppPattern diff --git a/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv b/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv index c4506d97f..cc5980254 100644 --- a/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv +++ b/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv @@ -175,8 +175,9 @@ top::PrimPattern ::= qn::QName '(' ns::VarBinders ')' '->' e::Expr top.freeVars := ts:removeAll(ns.boundNames, e.freeVars); - local t::Type = qn.lookupValue.typeScheme.typerep.outputType; + local t::Type = qn.lookupValue.dcl.namedSignature.outputElement.typerep; local isGadt :: Boolean = + qn.lookupValue.found && case t.baseType of -- If the lookup is successful, and it's a production type, and it -- constructs a nonterminal that either: @@ -213,9 +214,14 @@ top::PrimPattern ::= qn::Decorated QName ns::VarBinders e::Expr | [] -> [] | _ -> [errFromOrigin(qn, qn.name ++ " is not a production.")] end; + + local sig::NamedSignature = + if qn.lookupValue.found + then qn.lookupValue.dcl.namedSignature + else bogusNamedSignature(); -- Turns the existential variables existential - local prod_contexts_type :: Pair<[Context] Type> = skolemizeProductionType(qn.lookupValue.typeScheme); + local prod_contexts_type :: Pair<[Context] Type> = skolemizeProductionType(sig.typeScheme); production prod_contexts :: [Context] = prod_contexts_type.fst; production prod_type :: Type = prod_contexts_type.snd; -- Note that we're going to check prod_type against top.scrutineeType shortly. @@ -296,8 +302,13 @@ top::PrimPattern ::= qn::Decorated QName ns::VarBinders e::Expr | [] -> [] | _ -> [errFromOrigin(qn, qn.name ++ " is not a production.")] end; + + local sig::NamedSignature = + if qn.lookupValue.found + then qn.lookupValue.dcl.namedSignature + else bogusNamedSignature(); - local prod_contexts_type :: Pair<[Context] Type> = fullySkolemizeProductionType(qn.lookupValue.typeScheme); -- that says FULLY. See the comments on that function. + local prod_contexts_type :: Pair<[Context] Type> = fullySkolemizeProductionType(sig.typeScheme); -- that says FULLY. See the comments on that function. production prod_contexts :: [Context] = prod_contexts_type.fst; production prod_type :: Type = prod_contexts_type.snd; From 2e52f04d4278f6ff952342538a3b01f873a0895a Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 7 Mar 2024 19:30:56 -0600 Subject: [PATCH 177/283] Fix type checking bug with aspects when only a name is given --- grammars/silver/compiler/definition/core/AspectDcl.sv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/grammars/silver/compiler/definition/core/AspectDcl.sv b/grammars/silver/compiler/definition/core/AspectDcl.sv index 4f4cf4569..ee25dc836 100644 --- a/grammars/silver/compiler/definition/core/AspectDcl.sv +++ b/grammars/silver/compiler/definition/core/AspectDcl.sv @@ -244,6 +244,7 @@ top::AspectRHSElem ::= '_' concrete production aspectRHSElemIdConcrete top::AspectRHSElem ::= id::Name { + -- aspectRHSElemId is used by extensions, so avoid giving the warning there: top.errors <- [wrnFromOrigin(top, "Giving just a name '" ++ id.name ++ "' is deprecated in aspect signature. Please explicitly use a name and type.")]; forwards to aspectRHSElemId(@id); @@ -257,7 +258,7 @@ top::AspectRHSElem ::= id::Name top.unparse = id.unparse; production attribute rType :: Type; - rType = if null(top.realSignature) then errorType() else head(top.realSignature).typerep; + rType = if null(top.realSignature) then errorType() else head(top.realSignature).elementDclType; production shared :: Boolean = !null(top.realSignature) && head(top.realSignature).elementShared; forwards to aspectRHSElemFull(shared, id, rType); From 84ff8f251416f8f972d206ff51ea1ca16973167f Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 7 Mar 2024 22:11:37 -0600 Subject: [PATCH 178/283] Support extra children in dispatch signatures --- .../typechecking/core/ProductionDcl.sv | 7 ++++ .../compiler/definition/core/DclInfo.sv | 2 +- .../compiler/definition/core/ProductionDcl.sv | 2 +- .../silver/compiler/definition/env/DclInfo.sv | 11 ++++-- .../silver/compiler/definition/env/Defs.sv | 2 +- .../compiler/translation/java/core/Expr.sv | 25 ++++++++++---- .../java/src/common/DispatchNodeFactory.java | 34 +++++++++++++++++++ 7 files changed, 71 insertions(+), 12 deletions(-) create mode 100644 runtime/java/src/common/DispatchNodeFactory.java diff --git a/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv b/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv index 9cdf27b27..3376e0b96 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv @@ -4,6 +4,13 @@ aspect production productionDcl top::AGDcl ::= 'abstract' 'production' id::Name d::ProductionImplements ns::ProductionSignature body::ProductionBody { body.downSubst = emptySubst(); + + top.errors <- + case d.implementsSig of + | just(sig) when length(sig.inputElements) > length(ns.namedSignature.inputElements) -> + [errFromOrigin(top, "Production signature missing items from implemented dispatch signature.")] + | _ -> [] + end; } aspect production productionLHS diff --git a/grammars/silver/compiler/definition/core/DclInfo.sv b/grammars/silver/compiler/definition/core/DclInfo.sv index 73cf9409d..bc6b46036 100644 --- a/grammars/silver/compiler/definition/core/DclInfo.sv +++ b/grammars/silver/compiler/definition/core/DclInfo.sv @@ -72,7 +72,7 @@ top::ValueDclInfo ::= fn::String ty::Type _ -- -- interface values aspect production prodDcl -top::ValueDclInfo ::= ns::NamedSignature dispatch::Maybe hasForward::Boolean +top::ValueDclInfo ::= ns::NamedSignature dispatch::Maybe hasForward::Boolean { top.refDispatcher = productionReference; -- Note that we still need production references, even though bug #16 removes the production type. diff --git a/grammars/silver/compiler/definition/core/ProductionDcl.sv b/grammars/silver/compiler/definition/core/ProductionDcl.sv index fea2f85eb..4d8677349 100644 --- a/grammars/silver/compiler/definition/core/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/core/ProductionDcl.sv @@ -50,7 +50,7 @@ top::AGDcl ::= 'abstract' 'production' id::Name d::ProductionImplements ns::Prod production fName :: String = top.grammarName ++ ":" ++ id.name; production namedSig :: NamedSignature = ns.namedSignature; - top.defs := prodDef(top.grammarName, id.nameLoc, namedSig, map((.fullName), d.implementsSig), length(body.forwardExpr) > 0) :: + top.defs := prodDef(top.grammarName, id.nameLoc, namedSig, d.implementsSig, length(body.forwardExpr) > 0) :: if null(body.productionAttributes) then [] else [prodOccursDef(top.grammarName, id.nameLoc, namedSig, body.productionAttributes)]; diff --git a/grammars/silver/compiler/definition/env/DclInfo.sv b/grammars/silver/compiler/definition/env/DclInfo.sv index e63212826..9ba5f5222 100644 --- a/grammars/silver/compiler/definition/env/DclInfo.sv +++ b/grammars/silver/compiler/definition/env/DclInfo.sv @@ -103,7 +103,7 @@ top::ValueDclInfo ::= ty::Type -- ValueDclInfos that DO appear in interface files: abstract production prodDcl -top::ValueDclInfo ::= ns::NamedSignature dispatch::Maybe hasForward::Boolean +top::ValueDclInfo ::= ns::NamedSignature dispatch::Maybe hasForward::Boolean { top.fullName = ns.fullName; @@ -111,7 +111,14 @@ top::ValueDclInfo ::= ns::NamedSignature dispatch::Maybe hasForward::Boo top.typeScheme = case dispatch of | nothing() -> ns.typeScheme - | just(fn) -> monoType(dispatchType(fn)) + | just(dSig) -> + if length(ns.inputElements) == length(dSig.inputElements) + then monoType(dispatchType(dSig.fullName)) + else (if null(ns.contexts) then polyType else constraintType(_, ns.contexts, _))( + ns.freeVariables, + appTypes( + functionType(length(ns.inputElements) - length(dSig.inputElements), []), + drop(length(dSig.inputElements), ns.inputTypes) ++ [dispatchType(dSig.fullName)])) end; top.hasForward = hasForward; } diff --git a/grammars/silver/compiler/definition/env/Defs.sv b/grammars/silver/compiler/definition/env/Defs.sv index 9df719c78..d0a86b2c8 100644 --- a/grammars/silver/compiler/definition/env/Defs.sv +++ b/grammars/silver/compiler/definition/env/Defs.sv @@ -126,7 +126,7 @@ fun lhsDef Def ::= sg::String sl::Location fn::String ty::Type = valueDef(defaultEnvItem(lhsDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); fun localDef Def ::= sg::String sl::Location fn::String ty::Type isForward::Boolean = valueDef(defaultEnvItem(localDcl(fn,ty,isForward,sourceGrammar=sg,sourceLocation=sl))); -fun prodDef Def ::= sg::String sl::Location ns::NamedSignature dispatch::Maybe hasForward::Boolean = +fun prodDef Def ::= sg::String sl::Location ns::NamedSignature dispatch::Maybe hasForward::Boolean = prodDclDef(defaultEnvItem(prodDcl(ns,dispatch,hasForward,sourceGrammar=sg,sourceLocation=sl))); fun funDef Def ::= sg::String sl::Location ns::NamedSignature = valueDef(defaultEnvItem(funDcl(ns,sourceGrammar=sg,sourceLocation=sl))); diff --git a/grammars/silver/compiler/translation/java/core/Expr.sv b/grammars/silver/compiler/translation/java/core/Expr.sv index a451848d8..4fcf41820 100644 --- a/grammars/silver/compiler/translation/java/core/Expr.sv +++ b/grammars/silver/compiler/translation/java/core/Expr.sv @@ -153,18 +153,29 @@ top::Expr ::= q::Decorated! QName aspect production productionReference top::Expr ::= q::Decorated! QName { - top.translation = + local factory::String = if null(typeScheme.contexts) then makeProdName(q.lookupValue.fullName) ++ ".factory" else s"new ${makeProdName(q.lookupValue.fullName)}.Factory(${implode(", ", contexts.transContexts)})"; + local prodArity::Integer = length(q.lookupValue.dcl.namedSignature.inputElements); + top.translation = + case top.finalType.outputType of + | dispatchType(fn) when getTypeDcl(fn, top.env) matches dcl :: _ -> + s"new common.DispatchNodeFactory<${q.lookupValue.dcl.namedSignature.outputElement.typerep.transType}>(${factory}, ${toString(length(dcl.dispatchSignature.inputElements))})" + | _ -> factory + end; top.lazyTranslation = top.translation; top.invokeTranslation = - -- static constructor invocation - s"new ${makeProdName(q.lookupValue.fullName)}(${implode(", ", - makeNewConstructionOrigin(top, !top.sameProdAsProductionDefinedOn) ++ - toString(top.invokeIsUnique) :: - contexts.transContexts ++ - map((.lazyTranslation), top.invokeArgs.exprs ++ reorderedAnnoAppExprs(top.invokeNamedArgs)))})"; + case top.finalType.outputType of + | dispatchType(fn) -> s"${top.translation}.invoke(${makeOriginContextRef(top)}, new Object[]{${argsTranslation(top.invokeArgs)}}, ${namedargsTranslation(top.invokeNamedArgs)})" + | _ -> + -- static constructor invocation + s"new ${makeProdName(q.lookupValue.fullName)}(${implode(", ", + makeNewConstructionOrigin(top, !top.sameProdAsProductionDefinedOn) ++ + toString(top.invokeIsUnique) :: + contexts.transContexts ++ + map((.lazyTranslation), top.invokeArgs.exprs ++ reorderedAnnoAppExprs(top.invokeNamedArgs)))})" + end; -- Safe to be eager here, since the only work being done is constructing a term. -- This means that large nested terms will be built eagerly, but we rarely define a term without -- demanding it, so overall this is a performance win. diff --git a/runtime/java/src/common/DispatchNodeFactory.java b/runtime/java/src/common/DispatchNodeFactory.java new file mode 100644 index 000000000..30a5a78c5 --- /dev/null +++ b/runtime/java/src/common/DispatchNodeFactory.java @@ -0,0 +1,34 @@ +package common; + +/** + * Take a NodeFactory for a dispatch implementation production, + * and partially apply it to fill in the extra arguments. + * + * @author krame505 + */ + +public class DispatchNodeFactory extends NodeFactory> { + private final NodeFactory prod; + private int dispatchArity; + + public DispatchNodeFactory(final NodeFactory prod, final int dispatchArity) { + this.prod = prod; + this.dispatchArity = dispatchArity; + } + + @Override + public NodeFactory invoke(OriginContext originCtx, Object[] args, Object[] namedArgs) { + int[] indices = new int[args.length]; + for (int i = 0; i < args.length; i++) { + indices[i] = i + dispatchArity; + } + return new PartialNodeFactory<>(indices, args, prod); + } + + @Override + public TypeRep getType() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getType'"); + } + +} From 4348124bf5c557fd9fc78905b1de5abb62432dd9 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 11 Mar 2024 14:52:34 -0500 Subject: [PATCH 179/283] Use new dispatch signature mechanism for var reference expressions --- .../analysis/typechecking/core/Expr.sv | 8 ++-- .../compiler/analysis/uniqueness/Expr.sv | 20 ++++---- .../compiler/analysis/warnings/flow/Inh.sv | 8 ++-- .../compiler/definition/core/DclInfo.sv | 2 +- .../silver/compiler/definition/core/Expr.sv | 46 ++++++++----------- .../compiler/definition/flow/env/Expr.sv | 10 ++-- .../extension/implicit_monads/CopperExpr.sv | 10 ++-- .../extension/implicit_monads/Expr.sv | 20 ++++---- .../extension/implicit_monads/Lambda.sv | 4 +- .../compiler/extension/implicit_monads/Let.sv | 2 +- .../compiler/extension/rewriting/Expr.sv | 30 ++++++------ .../concisefunctions/ConciseFunctions.sv | 5 +- .../concisefunctions/java/ConciseFunctions.sv | 2 +- .../compiler/modification/copper/Expr.sv | 30 +++++------- .../compiler/modification/lambda_fn/Lambda.sv | 5 +- .../modification/lambda_fn/java/Lambda.sv | 2 +- .../compiler/modification/let_fix/DclInfo.sv | 2 +- .../compiler/modification/let_fix/Let.sv | 5 +- .../compiler/modification/let_fix/java/Let.sv | 2 +- .../silver/compiler/refactor/ExplicitNew.sv | 4 +- .../compiler/translation/java/core/Expr.sv | 18 ++++---- 21 files changed, 109 insertions(+), 126 deletions(-) diff --git a/grammars/silver/compiler/analysis/typechecking/core/Expr.sv b/grammars/silver/compiler/analysis/typechecking/core/Expr.sv index 0d2ab5545..5b7cf496c 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/Expr.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/Expr.sv @@ -22,7 +22,7 @@ top::Expr ::= } aspect production productionReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { contexts.contextLoc = q.nameLoc; contexts.contextSource = "the use of " ++ q.name; @@ -31,7 +31,7 @@ top::Expr ::= q::Decorated! QName } aspect production functionReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { contexts.contextLoc = q.nameLoc; contexts.contextSource = "the use of " ++ q.name; @@ -40,7 +40,7 @@ top::Expr ::= q::Decorated! QName } aspect production globalValueReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { contexts.contextLoc = q.nameLoc; contexts.contextSource = "the use of " ++ q.name; @@ -49,7 +49,7 @@ top::Expr ::= q::Decorated! QName } aspect production classMemberReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { instHead.contextLoc = q.nameLoc; instHead.contextSource = "the use of " ++ q.name; diff --git a/grammars/silver/compiler/analysis/uniqueness/Expr.sv b/grammars/silver/compiler/analysis/uniqueness/Expr.sv index b80e517e0..bff89b048 100644 --- a/grammars/silver/compiler/analysis/uniqueness/Expr.sv +++ b/grammars/silver/compiler/analysis/uniqueness/Expr.sv @@ -20,7 +20,7 @@ top::Expr ::= } aspect production childReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.uniqueRefs <- case top.finalType, refSet of @@ -51,7 +51,7 @@ top::Expr ::= q::Decorated! QName end; } aspect production localReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.uniqueRefs <- case top.finalType, refSet of @@ -82,7 +82,7 @@ top::Expr ::= q::Decorated! QName end; } aspect production lhsReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.errors <- case top.finalType of @@ -92,7 +92,7 @@ top::Expr ::= q::Decorated! QName end; } aspect production forwardReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.errors <- case top.finalType of @@ -102,7 +102,7 @@ top::Expr ::= q::Decorated! QName end; } aspect production productionReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.errors <- flatMap(\ tv::TyVar -> let substTy::Type = performSubstitution(varType(tv), top.finalSubst) @@ -113,7 +113,7 @@ top::Expr ::= q::Decorated! QName top.typerep.freeVariables); } aspect production functionReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.errors <- flatMap(\ tv::TyVar -> let substTy::Type = performSubstitution(varType(tv), top.finalSubst) @@ -124,7 +124,7 @@ top::Expr ::= q::Decorated! QName top.typerep.freeVariables); } aspect production classMemberReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.errors <- flatMap(\ tv::TyVar -> let substTy::Type = performSubstitution(varType(tv), top.finalSubst) @@ -135,7 +135,7 @@ top::Expr ::= q::Decorated! QName top.typerep.freeVariables); } aspect production globalValueReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.errors <- flatMap(\ tv::TyVar -> let substTy::Type = performSubstitution(varType(tv), top.finalSubst) @@ -316,7 +316,7 @@ top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'else' e3::Expr } aspect production lambdaParamReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.uniqueRefs <- if top.finalType.isUniqueDecorated @@ -345,7 +345,7 @@ top::Expr ::= params::LambdaRHS e::Expr } aspect production lexicalLocalReference -top::Expr ::= q::Decorated! QName fi::Maybe fd::[FlowVertex] rs::[(String, UniqueRefSite)] +top::Expr ::= @q::QName fi::Maybe fd::[FlowVertex] rs::[(String, UniqueRefSite)] { top.errors <- -- This check is needed due to how we handle let binding auto-undecoration in the type system: diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index a250aae5c..e01a1b487 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -634,7 +634,7 @@ Step 2: Let's go check on expressions. This has two purposes: -} aspect production childReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.errors <- if top.config.warnMissingInh @@ -644,7 +644,7 @@ top::Expr ::= q::Decorated! QName else []; } aspect production lhsReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.errors <- if top.config.warnMissingInh @@ -653,7 +653,7 @@ top::Expr ::= q::Decorated! QName else []; } aspect production localReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.errors <- if top.config.warnMissingInh @@ -663,7 +663,7 @@ top::Expr ::= q::Decorated! QName else []; } aspect production forwardReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.errors <- if top.config.warnMissingInh diff --git a/grammars/silver/compiler/definition/core/DclInfo.sv b/grammars/silver/compiler/definition/core/DclInfo.sv index bc6b46036..aa401173f 100644 --- a/grammars/silver/compiler/definition/core/DclInfo.sv +++ b/grammars/silver/compiler/definition/core/DclInfo.sv @@ -5,7 +5,7 @@ import silver:compiler:modification:copper only terminalIdReference; {-- - The production a variable reference should forward to for this type of value -} -synthesized attribute refDispatcher :: (Expr ::= Decorated! QName) occurs on ValueDclInfo; +synthesized attribute refDispatcher :: Reference occurs on ValueDclInfo; {-- - The production an "assignment" should forward to for this type of value -} diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index 7db2765de..f79f0942f 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -99,9 +99,8 @@ top::Expr ::= q::QName } abstract production errorReference -top::Expr ::= msg::[Message] q::Decorated! QName +top::Expr ::= msg::[Message] @q::QName { - undecorates to errorExpr(msg); -- TODO: Should this be baseExpr? top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); @@ -109,11 +108,11 @@ top::Expr ::= msg::[Message] q::Decorated! QName top.typerep = errorType(); } --- TODO: We should separate this out, even, to be "nonterminal/decorable" and "as-is" -abstract production childReference -top::Expr ::= q::Decorated! QName +dispatch Reference = Expr ::= @q::QName; + +abstract production childReference implements Reference +top::Expr ::= @q::QName { - undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); @@ -122,10 +121,9 @@ top::Expr ::= q::Decorated! QName else q.lookupValue.typeScheme.monoType; } -abstract production lhsReference -top::Expr ::= q::Decorated! QName +abstract production lhsReference implements Reference +top::Expr ::= @q::QName { - undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); @@ -133,10 +131,9 @@ top::Expr ::= q::Decorated! QName top.typerep = q.lookupValue.typeScheme.asNtOrDecType; } -abstract production localReference -top::Expr ::= q::Decorated! QName +abstract production localReference implements Reference +top::Expr ::= @q::QName { - undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); @@ -145,10 +142,9 @@ top::Expr ::= q::Decorated! QName else q.lookupValue.typeScheme.monoType; } -abstract production forwardReference -top::Expr ::= q::Decorated! QName +abstract production forwardReference implements Reference +top::Expr ::= @q::QName { - undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); @@ -159,10 +155,9 @@ top::Expr ::= q::Decorated! QName -- Note here that production and function *references* are distinguished. -- Later on, we do *not* distinguish for application. -abstract production productionReference -top::Expr ::= q::Decorated! QName +abstract production productionReference implements Reference +top::Expr ::= @q::QName { - undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); @@ -178,10 +173,9 @@ top::Expr ::= q::Decorated! QName contexts.compiledGrammars = top.compiledGrammars; } -abstract production functionReference -top::Expr ::= q::Decorated! QName +abstract production functionReference implements Reference +top::Expr ::= @q::QName { - undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); @@ -197,10 +191,9 @@ top::Expr ::= q::Decorated! QName contexts.compiledGrammars = top.compiledGrammars; } -abstract production classMemberReference -top::Expr ::= q::Decorated! QName +abstract production classMemberReference implements Reference +top::Expr ::= @q::QName { - undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); @@ -229,10 +222,9 @@ top::Expr ::= q::Decorated! QName contexts.compiledGrammars = top.compiledGrammars; } -abstract production globalValueReference -top::Expr ::= q::Decorated! QName +abstract production globalValueReference implements Reference +top::Expr ::= @q::QName { - undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index 7618e9681..2af028c0c 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -75,7 +75,7 @@ top::Expr ::= } aspect production childReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { -- Note that q should find the actual type written in the signature, and so -- isDecorable on that indeed tells us whether it's something autodecorated. @@ -106,7 +106,7 @@ top::Expr ::= q::Decorated! QName end; } aspect production lhsReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { -- Always a decorable type, so just check how it's being used: production refSet::Maybe<[String]> = getMaxRefSet(top.finalType, top.env); @@ -120,7 +120,7 @@ top::Expr ::= q::Decorated! QName else nothing(); } aspect production localReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { -- Again, q give the actual type written. production refSet::Maybe<[String]> = getMaxRefSet(top.finalType, top.env); @@ -154,7 +154,7 @@ top::Expr ::= q::Decorated! QName end; } aspect production forwardReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { -- Again, always a decorable type. production refSet::Maybe<[String]> = getMaxRefSet(top.finalType, top.env); @@ -516,7 +516,7 @@ top::AssignExpr ::= id::Name '::' t::TypeExpr '=' e::Expr } aspect production lexicalLocalReference -top::Expr ::= q::Decorated! QName fi::Maybe fd::[FlowVertex] _ +top::Expr ::= @q::QName fi::Maybe fd::[FlowVertex] _ { -- Because of the auto-undecorate behavior, we need to check for the case -- where `t` should be equivalent to `new(t)` and report accoringly. diff --git a/grammars/silver/compiler/extension/implicit_monads/CopperExpr.sv b/grammars/silver/compiler/extension/implicit_monads/CopperExpr.sv index 549b36de8..d0ce97ce9 100644 --- a/grammars/silver/compiler/extension/implicit_monads/CopperExpr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/CopperExpr.sv @@ -6,7 +6,7 @@ grammar silver:compiler:extension:implicit_monads; -} aspect production actionChildReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.merrors := []; top.mUpSubst = top.mDownSubst; @@ -18,7 +18,7 @@ top::Expr ::= q::Decorated! QName } aspect production pluckTerminalReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.merrors := []; top.mUpSubst = top.mDownSubst; @@ -30,7 +30,7 @@ top::Expr ::= q::Decorated! QName } aspect production terminalIdReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.merrors := []; top.mUpSubst = top.mDownSubst; @@ -42,7 +42,7 @@ top::Expr ::= q::Decorated! QName } aspect production parserAttributeReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.merrors := []; top.mUpSubst = top.mDownSubst; @@ -54,7 +54,7 @@ top::Expr ::= q::Decorated! QName } aspect production termAttrValueReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.merrors := []; top.mUpSubst = top.mDownSubst; diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index bf7bea9bc..5e45da097 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -43,7 +43,7 @@ top::Expr ::= e::[Message] } aspect production errorReference -top::Expr ::= msg::[Message] q::Decorated! QName +top::Expr ::= msg::[Message] @q::QName { top.merrors := msg; propagate mDownSubst, mUpSubst; @@ -53,7 +53,7 @@ top::Expr ::= msg::[Message] q::Decorated! QName } aspect production childReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.merrors := []; propagate mDownSubst, mUpSubst; @@ -67,7 +67,7 @@ top::Expr ::= q::Decorated! QName } aspect production lhsReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.merrors := []; propagate mDownSubst, mUpSubst; @@ -79,7 +79,7 @@ top::Expr ::= q::Decorated! QName } aspect production localReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.merrors := []; propagate mDownSubst, mUpSubst; @@ -93,7 +93,7 @@ top::Expr ::= q::Decorated! QName } aspect production forwardReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.merrors := []; propagate mDownSubst, mUpSubst; @@ -106,7 +106,7 @@ top::Expr ::= q::Decorated! QName } aspect production productionReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.merrors := []; propagate mDownSubst, mUpSubst; @@ -118,7 +118,7 @@ top::Expr ::= q::Decorated! QName } aspect production functionReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.merrors := []; propagate mDownSubst, mUpSubst; @@ -130,7 +130,7 @@ top::Expr ::= q::Decorated! QName } aspect production classMemberReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.merrors := []; propagate mDownSubst, mUpSubst; @@ -142,7 +142,7 @@ top::Expr ::= q::Decorated! QName } aspect production globalValueReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.merrors := []; propagate mDownSubst, mUpSubst; @@ -1899,7 +1899,7 @@ top::Expr ::= 'disambiguationFailure' aspect production lexerClassReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.mUpSubst = top.mDownSubst; top.mtyperep = q.lookupValue.typeScheme.typerep; diff --git a/grammars/silver/compiler/extension/implicit_monads/Lambda.sv b/grammars/silver/compiler/extension/implicit_monads/Lambda.sv index f9b3db9e4..5ab41b871 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Lambda.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Lambda.sv @@ -17,7 +17,7 @@ top::Expr ::= params::LambdaRHS e::Expr aspect production lambdaParamReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.merrors := []; propagate mDownSubst, mUpSubst; @@ -29,7 +29,7 @@ top::Expr ::= q::Decorated! QName } aspect production shortFunParamReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.merrors := []; propagate mDownSubst, mUpSubst; diff --git a/grammars/silver/compiler/extension/implicit_monads/Let.sv b/grammars/silver/compiler/extension/implicit_monads/Let.sv index 34e193a78..6d64e1237 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Let.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Let.sv @@ -133,7 +133,7 @@ top::AssignExpr ::= id::Name '::' t::TypeExpr '=' e::Expr aspect production lexicalLocalReference -top::Expr ::= q::Decorated! QName _ _ _ +top::Expr ::= @q::QName _ _ _ { top.merrors := []; propagate mDownSubst, mUpSubst; diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index ce5f0dbb9..1bfa9081b 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -26,7 +26,7 @@ top::Expr ::= } aspect production lexicalLocalReference -top::Expr ::= q::Decorated! QName _ _ _ +top::Expr ::= @q::QName _ _ _ { -- In regular pattern matching nonterminal values are always effectively decorated, but we are -- using the same typing behavior while matching on *undecorated* trees. So when a variable is @@ -67,49 +67,49 @@ top::Expr ::= q::Decorated! QName _ _ _ -- The variable is bound in an enclosing let/match -- Explicitly undecorate the variable, if appropriate for the final expected type if isDecorable(q.lookupValue.typeScheme.typerep, top.env) && !top.finalType.isDecorated - then antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr(silver:core:new($Expr{top})) }) - else antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr($Expr{top}) }) + then antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr(silver:core:new($QName{q})) }) + else antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr($QName{q}) }) end; } aspect production childReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.transform = -- Explicitly undecorate the variable, if appropriate for the final expected type if isDecorable(q.lookupValue.typeScheme.typerep, top.env) && !top.finalType.isDecorated - then antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr(silver:core:new($Expr{top})) }) - else antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr($Expr{top}) }); + then antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr(silver:core:new($QName{q})) }) + else antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr($QName{q}) }); } aspect production lhsReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.transform = -- Explicitly undecorate the variable, if appropriate for the final expected type if isDecorable(q.lookupValue.typeScheme.typerep, top.env) && !top.finalType.isDecorated - then antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr(silver:core:new($Expr{top})) }) - else antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr($Expr{top}) }); + then antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr(silver:core:new($QName{q})) }) + else antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr($QName{q}) }); } aspect production localReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.transform = -- Explicitly undecorate the variable, if appropriate for the final expected type if isDecorable(q.lookupValue.typeScheme.typerep, top.env) && !top.finalType.isDecorated - then antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr(silver:core:new($Expr{top})) }) - else antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr($Expr{top}) }); + then antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr(silver:core:new($QName{q})) }) + else antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr($QName{q}) }); } aspect production forwardReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.transform = -- Explicitly undecorate the variable, if appropriate for the final expected type if isDecorable(q.lookupValue.typeScheme.typerep, top.env) && !top.finalType.isDecorated - then antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr(silver:core:new($Expr{top})) }) - else antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr($Expr{top}) }); + then antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr(silver:core:new($QName{q})) }) + else antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr($QName{q}) }); } aspect production errorApplication diff --git a/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv b/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv index 6c6020a99..3101b0946 100644 --- a/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv +++ b/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv @@ -76,10 +76,9 @@ aspect shortFunctionDefs on top::ProductionRHSElem using := of | productionRHSElemType(_, _) -> [] end; -abstract production shortFunParamReference -top::Expr ::= q::Decorated! QName +abstract production shortFunParamReference implements Reference +top::Expr ::= @q::QName { - undecorates to baseExpr(q); top.unparse = q.unparse; propagate errors; diff --git a/grammars/silver/compiler/modification/concisefunctions/java/ConciseFunctions.sv b/grammars/silver/compiler/modification/concisefunctions/java/ConciseFunctions.sv index a7294c3d1..d3390a91b 100644 --- a/grammars/silver/compiler/modification/concisefunctions/java/ConciseFunctions.sv +++ b/grammars/silver/compiler/modification/concisefunctions/java/ConciseFunctions.sv @@ -69,7 +69,7 @@ ${makeTyVarDecls(3, namedSig.typerep.freeVariables)} } aspect production shortFunParamReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.translation = s"common.Util.<${top.finalType.transType}>demand(${top.lazyTranslation})"; top.lazyTranslation = "c_" ++ q.lookupValue.fullName; diff --git a/grammars/silver/compiler/modification/copper/Expr.sv b/grammars/silver/compiler/modification/copper/Expr.sv index 2110ac6d6..48e420776 100644 --- a/grammars/silver/compiler/modification/copper/Expr.sv +++ b/grammars/silver/compiler/modification/copper/Expr.sv @@ -18,10 +18,9 @@ top::Expr ::= 'disambiguationFailure' top.upSubst = top.downSubst; } -abstract production actionChildReference -top::Expr ::= q::Decorated! QName +abstract production actionChildReference implements Reference +top::Expr ::= @q::QName { - undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars := ts:fromList([q.name]); @@ -35,10 +34,9 @@ top::Expr ::= q::Decorated! QName top.upSubst = top.downSubst; } -abstract production pluckTerminalReference -top::Expr ::= q::Decorated! QName +abstract production pluckTerminalReference implements Reference +top::Expr ::= @q::QName { - undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars := ts:fromList([q.name]); @@ -57,10 +55,9 @@ top::Expr ::= q::Decorated! QName -- reference any terminal), but maybe it shouldn't be? These productions do almost the same -- thing. Also having type classes would let us use a more specific type than generic TerminalId, -- and pluckTerminalReference wouldn't need to cheat with a fresh type. -abstract production terminalIdReference -top::Expr ::= q::Decorated! QName +abstract production terminalIdReference implements Reference +top::Expr ::= @q::QName { - undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars := ts:fromList([q.name]); @@ -76,10 +73,9 @@ top::Expr ::= q::Decorated! QName top.upSubst = top.downSubst; } -abstract production lexerClassReference -top::Expr ::= q::Decorated! QName +abstract production lexerClassReference implements Reference +top::Expr ::= @q::QName { - undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars := ts:fromList([q.name]); @@ -96,10 +92,9 @@ top::Expr ::= q::Decorated! QName top.upSubst = top.downSubst; } -abstract production parserAttributeReference -top::Expr ::= q::Decorated! QName +abstract production parserAttributeReference implements Reference +top::Expr ::= @q::QName { - undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars := ts:fromList([q.name]); @@ -116,10 +111,9 @@ top::Expr ::= q::Decorated! QName top.upSubst = top.downSubst; } -abstract production termAttrValueReference -top::Expr ::= q::Decorated! QName +abstract production termAttrValueReference implements Reference +top::Expr ::= @q::QName { - undecorates to baseExpr(q); top.unparse = q.unparse; top.freeVars := ts:fromList([q.name]); diff --git a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv index 1a48045ae..61f6b0f14 100644 --- a/grammars/silver/compiler/modification/lambda_fn/Lambda.sv +++ b/grammars/silver/compiler/modification/lambda_fn/Lambda.sv @@ -179,10 +179,9 @@ top::LambdaRHSElem ::= '_' } -abstract production lambdaParamReference -top::Expr ::= q::Decorated! QName +abstract production lambdaParamReference implements Reference +top::Expr ::= @q::QName { - undecorates to baseExpr(q); top.unparse = q.unparse; propagate errors; top.freeVars := ts:fromList([q.name]); diff --git a/grammars/silver/compiler/modification/lambda_fn/java/Lambda.sv b/grammars/silver/compiler/modification/lambda_fn/java/Lambda.sv index 459e87d0e..105f4177d 100644 --- a/grammars/silver/compiler/modification/lambda_fn/java/Lambda.sv +++ b/grammars/silver/compiler/modification/lambda_fn/java/Lambda.sv @@ -52,7 +52,7 @@ ${makeTyVarDecls(5, top.finalType.freeVariables)} } aspect production lambdaParamReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.translation = s"common.Util.<${top.finalType.transType}>demandIndex(lambda_${toString(q.lookupValue.dcl.lambdaId)}_args, ${toString(q.lookupValue.dcl.lambdaParamIndex)})"; top.lazyTranslation = wrapThunk(top.translation, top.frame.lazyApplication); diff --git a/grammars/silver/compiler/modification/let_fix/DclInfo.sv b/grammars/silver/compiler/modification/let_fix/DclInfo.sv index ed334d9ff..33425701b 100644 --- a/grammars/silver/compiler/modification/let_fix/DclInfo.sv +++ b/grammars/silver/compiler/modification/let_fix/DclInfo.sv @@ -15,7 +15,7 @@ top::ValueDclInfo ::= fn::String ty::Type fi::Maybe fd::[FlowVertex] top.typeScheme = monoType(ty); - top.refDispatcher = lexicalLocalReference(_, fi, fd, rs); + top.refDispatcher = lexicalLocalReference(fi, fd, rs); top.defDispatcher = errorValueDef; -- should be impossible (never in scope at production level?) top.defLHSDispatcher = errorDefLHS; -- ditto top.transDefLHSDispatcher = errorTransAttrDefLHS; diff --git a/grammars/silver/compiler/modification/let_fix/Let.sv b/grammars/silver/compiler/modification/let_fix/Let.sv index dc2175bb5..79e5062fa 100644 --- a/grammars/silver/compiler/modification/let_fix/Let.sv +++ b/grammars/silver/compiler/modification/let_fix/Let.sv @@ -119,10 +119,9 @@ top::AssignExpr ::= id::Name '::' t::TypeExpr '=' e::Expr e.isRoot = false; } -abstract production lexicalLocalReference -top::Expr ::= q::Decorated! QName fi::Maybe fd::[FlowVertex] rs::[(String, UniqueRefSite)] +abstract production lexicalLocalReference implements Reference +top::Expr ::= @q::QName fi::Maybe fd::[FlowVertex] rs::[(String, UniqueRefSite)] { - undecorates to baseExpr(q); top.unparse = q.unparse; top.errors := []; top.freeVars := ts:fromList([q.name]); diff --git a/grammars/silver/compiler/modification/let_fix/java/Let.sv b/grammars/silver/compiler/modification/let_fix/java/Let.sv index f33298f27..00d008974 100644 --- a/grammars/silver/compiler/modification/let_fix/java/Let.sv +++ b/grammars/silver/compiler/modification/let_fix/java/Let.sv @@ -57,7 +57,7 @@ fun makeSpecialLocalBinding String ::= fn::String et::String ty::String = s"final common.Thunk<${ty}> ${makeLocalValueName(fn)} = ${wrapThunkText(et, ty)};\n"; aspect production lexicalLocalReference -top::Expr ::= q::Decorated! QName _ _ _ +top::Expr ::= @q::QName _ _ _ { -- To account for a magic case where we generate a let expression with a type -- that is, for example, a ntOrDecType or something, diff --git a/grammars/silver/compiler/refactor/ExplicitNew.sv b/grammars/silver/compiler/refactor/ExplicitNew.sv index 593818f34..0007392ec 100644 --- a/grammars/silver/compiler/refactor/ExplicitNew.sv +++ b/grammars/silver/compiler/refactor/ExplicitNew.sv @@ -24,7 +24,7 @@ Either ::= args::[String] } aspect production childReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.transforms <- if top.config.refactorExplicitNew @@ -38,7 +38,7 @@ top::Expr ::= q::Decorated! QName } aspect production localReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.transforms <- if top.config.refactorExplicitNew diff --git a/grammars/silver/compiler/translation/java/core/Expr.sv b/grammars/silver/compiler/translation/java/core/Expr.sv index 4fcf41820..14f5f265a 100644 --- a/grammars/silver/compiler/translation/java/core/Expr.sv +++ b/grammars/silver/compiler/translation/java/core/Expr.sv @@ -58,14 +58,14 @@ top::Expr ::= msg::[Message] } aspect production errorReference -top::Expr ::= msg::[Message] q::Decorated! QName +top::Expr ::= msg::[Message] @q::QName { top.translation = error("Internal compiler error: translation not defined in the presence of errors"); top.lazyTranslation = top.translation; } aspect production childReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { local childIDref :: String = top.frame.className ++ ".i_" ++ q.lookupValue.fullName; @@ -102,7 +102,7 @@ top::Expr ::= q::Decorated! QName } aspect production localReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.translation = if !isDecorable(q.lookupValue.typeScheme.typerep, top.env) @@ -128,7 +128,7 @@ top::Expr ::= q::Decorated! QName } aspect production lhsReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.translation = if top.finalType.isDecorated @@ -139,7 +139,7 @@ top::Expr ::= q::Decorated! QName } aspect production forwardReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { top.translation = if top.finalType.isDecorated @@ -151,7 +151,7 @@ top::Expr ::= q::Decorated! QName } aspect production productionReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { local factory::String = if null(typeScheme.contexts) @@ -185,7 +185,7 @@ top::Expr ::= q::Decorated! QName } aspect production functionReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { -- functions, unlike productions, can return a type variable. -- as such, we have to cast it to the real inferred final type. @@ -211,7 +211,7 @@ top::Expr ::= q::Decorated! QName } aspect production classMemberReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { local transContextMember::String = s"${instHead.transContext}.${makeInstanceMemberAccessorName(q.lookupValue.fullName)}(${implode(", ", contexts.transContexts)})"; @@ -227,7 +227,7 @@ top::Expr ::= q::Decorated! QName } aspect production globalValueReference -top::Expr ::= q::Decorated! QName +top::Expr ::= @q::QName { local directThunk :: String = s"${makeName(q.lookupValue.dcl.sourceGrammar)}.Init.global_${fullNameToShort(q.lookupValue.fullName)}" ++ From 7ca974a7966185dae33f19fd8e3ca342d570e897 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 11 Mar 2024 15:49:20 -0500 Subject: [PATCH 180/283] Translate dispatch types as NodeFactory instead of just NodeFactory --- grammars/silver/compiler/translation/java/type/Type.sv | 3 +++ 1 file changed, 3 insertions(+) diff --git a/grammars/silver/compiler/translation/java/type/Type.sv b/grammars/silver/compiler/translation/java/type/Type.sv index 9ed9bc183..5866697b2 100644 --- a/grammars/silver/compiler/translation/java/type/Type.sv +++ b/grammars/silver/compiler/translation/java/type/Type.sv @@ -200,6 +200,9 @@ top::Type ::= params::Integer namedParams::[String] aspect production dispatchType top::Type ::= fn::String { + -- TODO: This should ideally be specialized to the nonterminal, + -- but that requires an env lookup. + top.transType = "common.NodeFactory"; top.transClassType = "common.NodeFactory"; top.transTypeRep = s"new common.BaseTypeRep(\"${fn}\")"; top.transTypeName = substitute(":", "_", fn); From 3bfd64acb3abc37cc68f4593d9ebaf4c771a4c90 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 11 Mar 2024 15:55:10 -0500 Subject: [PATCH 181/283] Include shared signature items in propagated monoid equations --- grammars/silver/compiler/extension/autoattr/Monoid.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grammars/silver/compiler/extension/autoattr/Monoid.sv b/grammars/silver/compiler/extension/autoattr/Monoid.sv index 346ea49ad..7e46555bb 100644 --- a/grammars/silver/compiler/extension/autoattr/Monoid.sv +++ b/grammars/silver/compiler/extension/autoattr/Monoid.sv @@ -128,8 +128,8 @@ top::ProductionStmt ::= attr::Decorated! QName local inputsWithAttr::[NamedSignatureElement] = filter( \ input::NamedSignatureElement -> - (isDecorable(input.typerep, top.env) || input.typerep.isNonterminal) && - !null(getOccursDcl(attrFullName, input.typerep.typeName, top.env)), + (isDecorable(input.elementDclType, top.env) || input.elementDclType.isNonterminal) && + !null(getOccursDcl(attrFullName, input.elementDclType.typeName, top.env)), top.frame.signature.inputElements); local res :: Expr = if null(inputsWithAttr) From 9d9232f366f2db76ef5412aec1b8d996eaa468c4 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 11 Mar 2024 16:44:39 -0500 Subject: [PATCH 182/283] Make dispatchType include the NamedSignature --- grammars/silver/compiler/definition/core/Expr.sv | 4 ++-- grammars/silver/compiler/definition/env/DclInfo.sv | 7 ++++--- grammars/silver/compiler/definition/env/Env.sv | 10 ---------- grammars/silver/compiler/definition/env/Type.sv | 6 ++++++ grammars/silver/compiler/definition/flow/env/Expr.sv | 2 +- .../silver/compiler/definition/type/PrettyPrinting.sv | 4 ++-- grammars/silver/compiler/definition/type/Type.sv | 4 +++- .../silver/compiler/definition/type/Unification.sv | 6 +++--- grammars/silver/compiler/definition/type/Util.sv | 4 +++- .../compiler/modification/primitivepattern/Types.sv | 10 +++++----- .../silver/compiler/translation/java/core/Expr.sv | 4 ++-- .../silver/compiler/translation/java/type/Context.sv | 1 - .../silver/compiler/translation/java/type/Type.sv | 11 +++++------ 13 files changed, 36 insertions(+), 37 deletions(-) diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index 7db2765de..3c2af48bf 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -277,7 +277,7 @@ top::Expr ::= e::Expr '(' es::AppExprs ',' anns::AnnoAppExprs ')' -- NOTE: REVERSED ORDER -- We may need to resolve e's type to get at the actual 'function type' - local t :: Type = asFunctionType(performSubstitution(e.typerep, e.upSubst), top.env); + local t :: Type = performSubstitution(e.typerep, e.upSubst); -- TODO: These should maybe be supplied after forwarding? es.appExprTypereps = reverse(correctNumTypes); es.appExprApplied = e.unparse; @@ -377,7 +377,7 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp undecorates to application(e, '(', es, ',', anns, ')'); top.unparse = e.unparse ++ "(" ++ es.unparse ++ "," ++ anns.unparse ++ ")"; - top.typerep = asFunctionType(performSubstitution(e.typerep, e.upSubst), top.env).outputType; + top.typerep = performSubstitution(e.typerep, e.upSubst).outputType; } concrete production noteAttachment diff --git a/grammars/silver/compiler/definition/env/DclInfo.sv b/grammars/silver/compiler/definition/env/DclInfo.sv index 9ba5f5222..4fa9aa34c 100644 --- a/grammars/silver/compiler/definition/env/DclInfo.sv +++ b/grammars/silver/compiler/definition/env/DclInfo.sv @@ -113,12 +113,13 @@ top::ValueDclInfo ::= ns::NamedSignature dispatch::Maybe hasForw | nothing() -> ns.typeScheme | just(dSig) -> if length(ns.inputElements) == length(dSig.inputElements) - then monoType(dispatchType(dSig.fullName)) + then monoType(dispatchType(dSig)) else (if null(ns.contexts) then polyType else constraintType(_, ns.contexts, _))( ns.freeVariables, appTypes( functionType(length(ns.inputElements) - length(dSig.inputElements), []), - drop(length(dSig.inputElements), ns.inputTypes) ++ [dispatchType(dSig.fullName)])) + drop(length(dSig.inputElements), ns.inputTypes) ++ + [dispatchType(dSig)])) end; top.hasForward = hasForward; } @@ -256,7 +257,7 @@ top::TypeDclInfo ::= ns::NamedSignature { top.fullName = ns.fullName; - top.typeScheme = monoType(dispatchType(ns.fullName)); + top.typeScheme = monoType(dispatchType(ns)); top.dispatchSignature = ns; top.isType = true; } diff --git a/grammars/silver/compiler/definition/env/Env.sv b/grammars/silver/compiler/definition/env/Env.sv index e9a5b6f2c..e243134a0 100644 --- a/grammars/silver/compiler/definition/env/Env.sv +++ b/grammars/silver/compiler/definition/env/Env.sv @@ -345,13 +345,3 @@ Maybe<[String]> ::= t::Type e::Env | _ -> just([]) end; } - -function asFunctionType -Type ::= t::Type e::Env -{ - return - case t.baseType of - | dispatchType(fn) when getTypeDcl(fn, e) matches dispatchDcl(ns) :: _ -> ns.typerep - | _ -> t - end; -} diff --git a/grammars/silver/compiler/definition/env/Type.sv b/grammars/silver/compiler/definition/env/Type.sv index a4e1589ac..c5a81b6ff 100644 --- a/grammars/silver/compiler/definition/env/Type.sv +++ b/grammars/silver/compiler/definition/env/Type.sv @@ -75,6 +75,12 @@ top::Type ::= tv::TyVar top.typeName = tv.typeName; } +aspect production dispatchType +top::Type ::= ns::NamedSignature +{ + top.typeName = ns.fullName; +} + attribute typeName occurs on TyVar; aspect production tyVar diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index 7618e9681..f29c125f2 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -222,7 +222,7 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp top.flowVertexInfo = top.decSiteVertexInfo; es.appProd = case e.typerep of - | dispatchType(fn) when getTypeDcl(fn, top.env) matches d :: _ -> just(d.dispatchSignature) + | dispatchType(ns) -> just(ns) | _ -> nothing() end; e.decSiteVertexInfo = nothing(); diff --git a/grammars/silver/compiler/definition/type/PrettyPrinting.sv b/grammars/silver/compiler/definition/type/PrettyPrinting.sv index c66ad8a7b..c08ad402f 100644 --- a/grammars/silver/compiler/definition/type/PrettyPrinting.sv +++ b/grammars/silver/compiler/definition/type/PrettyPrinting.sv @@ -236,9 +236,9 @@ top::Type ::= params::Integer namedParams::[String] } aspect production dispatchType -top::Type ::= fn::String +top::Type ::= ns::NamedSignature { - top.typepp = fn; + top.typepp = ns.fullName; } aspect production starKind diff --git a/grammars/silver/compiler/definition/type/Type.sv b/grammars/silver/compiler/definition/type/Type.sv index b949a2f41..285178725 100644 --- a/grammars/silver/compiler/definition/type/Type.sv +++ b/grammars/silver/compiler/definition/type/Type.sv @@ -3,6 +3,8 @@ grammar silver:compiler:definition:type; option silver:compiler:modification:ffi; -- foreign types option silver:compiler:modification:list; -- list type +imports silver:compiler:definition:env only NamedSignature, fullName, outputElement; + synthesized attribute kindrep :: Kind; synthesized attribute freeVariables :: [TyVar]; synthesized attribute boundVars :: [TyVar]; @@ -336,7 +338,7 @@ top::Type ::= params::Integer namedParams::[String] } abstract production dispatchType -top::Type ::= fn::String +top::Type ::= ns::NamedSignature { top.kindrep = starKind(); top.freeVariables = []; diff --git a/grammars/silver/compiler/definition/type/Unification.sv b/grammars/silver/compiler/definition/type/Unification.sv index 5323d3bae..fcf3f8285 100644 --- a/grammars/silver/compiler/definition/type/Unification.sv +++ b/grammars/silver/compiler/definition/type/Unification.sv @@ -207,12 +207,12 @@ top::Type ::= params::Integer namedParams::[String] } aspect production dispatchType -top::Type ::= fn::String +top::Type ::= ns::NamedSignature { top.unify = case top.unifyWith of - | dispatchType(ofn) when fn == ofn -> emptySubst() - | _ -> errorSubst("Tried to unify conflicting dispatch types " ++ fn ++ " and " ++ prettyType(top.unifyWith)) + | dispatchType(ons) when ns.fullName == ons.fullName -> emptySubst() + | _ -> errorSubst("Tried to unify conflicting dispatch types " ++ ns.fullName ++ " and " ++ prettyType(top.unifyWith)) end; } diff --git a/grammars/silver/compiler/definition/type/Util.sv b/grammars/silver/compiler/definition/type/Util.sv index d546487d8..1bacb01ad 100644 --- a/grammars/silver/compiler/definition/type/Util.sv +++ b/grammars/silver/compiler/definition/type/Util.sv @@ -277,9 +277,11 @@ top::Type ::= params::Integer namedParams::[String] } aspect production dispatchType -top::Type ::= fn::String +top::Type ::= ns::NamedSignature { top.isApplicable = true; + top.inputTypes = ns.inputTypes; + top.outputType = ns.outputElement.typerep; } -- Strict type equality, assuming all type vars are skolemized diff --git a/grammars/silver/compiler/modification/primitivepattern/Types.sv b/grammars/silver/compiler/modification/primitivepattern/Types.sv index b72a4f023..4222838a0 100644 --- a/grammars/silver/compiler/modification/primitivepattern/Types.sv +++ b/grammars/silver/compiler/modification/primitivepattern/Types.sv @@ -241,15 +241,15 @@ top::Type ::= params::Integer namedParams::[String] } aspect production dispatchType -top::Type ::= fn::String +top::Type ::= ns::NamedSignature { top.refine = case top.refineWith of - | dispatchType(ofn) -> - if fn == ofn + | dispatchType(ons) -> + if ns.fullName == ons.fullName then emptySubst() - else errorSubst("Tried to refine conflicting dispatch types " ++ fn ++ " and " ++ ofn) - | _ -> errorSubst("Tried to refine dispatch type " ++ fn ++ " with " ++ prettyType(top.refineWith)) + else errorSubst("Tried to refine conflicting dispatch types " ++ ns.fullName ++ " and " ++ ons.fullName) + | _ -> errorSubst("Tried to refine dispatch type " ++ ns.fullName ++ " with " ++ prettyType(top.refineWith)) end; } diff --git a/grammars/silver/compiler/translation/java/core/Expr.sv b/grammars/silver/compiler/translation/java/core/Expr.sv index 4fcf41820..9d4481b4b 100644 --- a/grammars/silver/compiler/translation/java/core/Expr.sv +++ b/grammars/silver/compiler/translation/java/core/Expr.sv @@ -160,8 +160,8 @@ top::Expr ::= q::Decorated! QName local prodArity::Integer = length(q.lookupValue.dcl.namedSignature.inputElements); top.translation = case top.finalType.outputType of - | dispatchType(fn) when getTypeDcl(fn, top.env) matches dcl :: _ -> - s"new common.DispatchNodeFactory<${q.lookupValue.dcl.namedSignature.outputElement.typerep.transType}>(${factory}, ${toString(length(dcl.dispatchSignature.inputElements))})" + | dispatchType(ns) -> + s"new common.DispatchNodeFactory<${q.lookupValue.dcl.namedSignature.outputElement.typerep.transType}>(${factory}, ${toString(length(ns.inputElements))})" | _ -> factory end; top.lazyTranslation = top.translation; diff --git a/grammars/silver/compiler/translation/java/type/Context.sv b/grammars/silver/compiler/translation/java/type/Context.sv index 0cebbcaba..f9e002c0a 100644 --- a/grammars/silver/compiler/translation/java/type/Context.sv +++ b/grammars/silver/compiler/translation/java/type/Context.sv @@ -1,6 +1,5 @@ grammar silver:compiler:translation:java:type; -import silver:compiler:definition:env; import silver:compiler:definition:core only QNameAttrOccur, QName, qNameAttrOccur; -- Translation of *solved* contexts, not *constraint* contexts diff --git a/grammars/silver/compiler/translation/java/type/Type.sv b/grammars/silver/compiler/translation/java/type/Type.sv index 5866697b2..9a057f362 100644 --- a/grammars/silver/compiler/translation/java/type/Type.sv +++ b/grammars/silver/compiler/translation/java/type/Type.sv @@ -1,6 +1,7 @@ grammar silver:compiler:translation:java:type; imports silver:compiler:definition:type; +imports silver:compiler:definition:env; imports silver:compiler:translation:java:core; -- The Java type corresponding to the Silver Type @@ -198,12 +199,10 @@ top::Type ::= params::Integer namedParams::[String] } aspect production dispatchType -top::Type ::= fn::String +top::Type ::= ns::NamedSignature { - -- TODO: This should ideally be specialized to the nonterminal, - -- but that requires an env lookup. - top.transType = "common.NodeFactory"; + top.transType = s"common.NodeFactory<${ns.outputElement.typerep.transType}>"; top.transClassType = "common.NodeFactory"; - top.transTypeRep = s"new common.BaseTypeRep(\"${fn}\")"; - top.transTypeName = substitute(":", "_", fn); + top.transTypeRep = s"new common.BaseTypeRep(\"${ns.fullName}\")"; + top.transTypeName = substitute(":", "_", ns.fullName); } From 5c6d2db8ef92e040801e8e68641b97b4d051f41c Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 11 Mar 2024 16:55:40 -0500 Subject: [PATCH 183/283] Use dispatch signature for application --- .../compiler/analysis/uniqueness/Expr.sv | 6 ++--- .../silver/compiler/definition/core/Expr.sv | 22 ++++++++++--------- .../silver/compiler/definition/core/Type.sv | 2 +- .../compiler/definition/flow/env/Expr.sv | 8 +++---- .../extension/implicit_monads/Expr.sv | 8 +++---- .../compiler/extension/rewriting/Expr.sv | 6 ++--- .../compiler/translation/java/core/Expr.sv | 8 +++---- 7 files changed, 31 insertions(+), 29 deletions(-) diff --git a/grammars/silver/compiler/analysis/uniqueness/Expr.sv b/grammars/silver/compiler/analysis/uniqueness/Expr.sv index bff89b048..b520cf6fd 100644 --- a/grammars/silver/compiler/analysis/uniqueness/Expr.sv +++ b/grammars/silver/compiler/analysis/uniqueness/Expr.sv @@ -156,7 +156,7 @@ monoid attribute appExprUniquenessErrors::[Message] occurs on AppExprs, AppExpr, propagate appExprUniquenessErrors on AppExprs, AppExpr, AnnoAppExprs, AnnoExpr; aspect production functionInvocation -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { top.errors <- es.appExprUniquenessErrors ++ anns.appExprUniquenessErrors; es.isNtUniquenessPreserving = @@ -168,7 +168,7 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp } aspect production partialApplication -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { top.errors <- es.appExprUniquenessErrors ++ anns.appExprUniquenessErrors; es.isNtUniquenessPreserving = @@ -180,7 +180,7 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp } aspect production dispatchApplication -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { top.errors <- es.appExprUniquenessErrors ++ anns.appExprUniquenessErrors; es.isNtUniquenessPreserving = true; diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index 788c88741..afc421972 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -307,8 +307,10 @@ top::Expr ::= e::Expr '(' ')' forwards to application(@e, $2, emptyAppExprs(), ',', emptyAnnoAppExprs(), $3); } -abstract production errorApplication -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +dispatch Application = Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs; + +abstract production errorApplication implements Application +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { undecorates to application(e, '(', es, ',', anns, ')'); top.unparse = e.unparse ++ "(" ++ es.unparse ++ "," ++ anns.unparse ++ ")"; @@ -325,8 +327,8 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp -- Note that this applies to both function and productions. -- We don't distinguish anymore at this point. A production reference -- becomes a function, effectively. -abstract production functionApplication -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +abstract production functionApplication implements Application +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { undecorates to application(e, '(', es, ',', anns, ')'); top.unparse = e.unparse ++ "(" ++ es.unparse ++ "," ++ anns.unparse ++ ")"; @@ -338,8 +340,8 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp else functionInvocation)(e, es, anns); } -abstract production functionInvocation -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +abstract production functionInvocation implements Application +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { undecorates to application(e, '(', es, ',', anns, ')'); top.unparse = e.unparse ++ "(" ++ es.unparse ++ "," ++ anns.unparse ++ ")"; @@ -349,8 +351,8 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp top.typerep = ety.outputType; } -abstract production partialApplication -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +abstract production partialApplication implements Application +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { undecorates to application(e, '(', es, ',', anns, ')'); top.unparse = e.unparse ++ "(" ++ es.unparse ++ "," ++ anns.unparse ++ ")"; @@ -363,8 +365,8 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp es.missingTypereps ++ anns.partialAnnoTypereps ++ map(snd, anns.missingAnnotations) ++ [ety.outputType]); } -abstract production dispatchApplication -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +abstract production dispatchApplication implements Application +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { undecorates to application(e, '(', es, ',', anns, ')'); top.unparse = e.unparse ++ "(" ++ es.unparse ++ "," ++ anns.unparse ++ ")"; diff --git a/grammars/silver/compiler/definition/core/Type.sv b/grammars/silver/compiler/definition/core/Type.sv index 8c4821550..eea642f17 100644 --- a/grammars/silver/compiler/definition/core/Type.sv +++ b/grammars/silver/compiler/definition/core/Type.sv @@ -1,7 +1,7 @@ grammar silver:compiler:definition:core; -- LHS type gives this to 'application' for "foo(...)" calls. -synthesized attribute applicationDispatcher :: (Expr ::= Decorated! Expr Decorated! AppExprs Decorated! AnnoAppExprs); +synthesized attribute applicationDispatcher :: Application; -- LHS type gives this to 'access' for "foo.some" accesses. -- (See DclInfo for the next step) synthesized attribute accessHandler :: (Expr ::= Decorated! Expr Decorated! QNameAttrOccur); diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index d0ed7b170..93276574c 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -181,7 +181,7 @@ top::Expr ::= e::Expr '(' es::AppExprs ',' anns::AnnoAppExprs ')' } aspect production errorApplication -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { e.decSiteVertexInfo = nothing(); es.decSiteVertexInfo = nothing(); @@ -190,7 +190,7 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp } aspect production functionInvocation -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { top.flowVertexInfo = top.decSiteVertexInfo; es.appProd = @@ -204,7 +204,7 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp } aspect production partialApplication -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { es.appProd = case e of @@ -217,7 +217,7 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp } aspect production dispatchApplication -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { top.flowVertexInfo = top.decSiteVertexInfo; es.appProd = diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index 5e45da097..233000c6c 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -272,7 +272,7 @@ top::Expr ::= e::Expr '(' es::AppExprs ',' anns::AnnoAppExprs ')' aspect production functionInvocation -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { forward t = application(e, '(', es, ',', anns, ')'); @@ -285,7 +285,7 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp } aspect production dispatchApplication -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { forward t = application(e, '(', es, ',', anns, ')'); @@ -397,7 +397,7 @@ Expr ::= monadTysLocs::[Pair] funargs::AppExprs annargs::AnnoAppEx aspect production partialApplication -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { top.merrors := error("merrors not defined on partial applications"); top.mUpSubst = error("mUpSubst not defined on partial applications"); @@ -409,7 +409,7 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp } aspect production errorApplication -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { top.merrors := []; diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index 1bfa9081b..90fe27eb1 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -113,13 +113,13 @@ top::Expr ::= @q::QName } aspect production errorApplication -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { top.transform = applyASTExpr(e.transform, es.transform, anns.transform); } aspect production functionInvocation -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { top.transform = case e, es of @@ -178,7 +178,7 @@ aspect isPrimitive on Type of end; aspect production partialApplication -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAppExprs +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { top.transform = applyASTExpr(e.transform, es.transform, anns.transform); } diff --git a/grammars/silver/compiler/translation/java/core/Expr.sv b/grammars/silver/compiler/translation/java/core/Expr.sv index ad56835bb..bb24ec78a 100644 --- a/grammars/silver/compiler/translation/java/core/Expr.sv +++ b/grammars/silver/compiler/translation/java/core/Expr.sv @@ -241,14 +241,14 @@ top::Expr ::= @q::QName else s"${directThunk}.eval()"; } aspect production errorApplication -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs annos::Decorated! AnnoAppExprs +top::Expr ::= @e::Expr @es::AppExprs @annos::AnnoAppExprs { top.translation = error("Internal compiler error: translation not defined in the presence of errors"); top.lazyTranslation = top.translation; } aspect production functionInvocation -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs annos::Decorated! AnnoAppExprs +top::Expr ::= @e::Expr @es::AppExprs @annos::AnnoAppExprs { top.translation = e.invokeTranslation; top.lazyTranslation = e.invokeLazyTranslation; @@ -274,7 +274,7 @@ fun namedargsTranslationNOReorder String ::= e::Decorated AnnoAppExprs = else s"new Object[]{${implode(", ", map((.lazyTranslation), e.exprs))}}"; aspect production partialApplication -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs annos::Decorated! AnnoAppExprs +top::Expr ::= @e::Expr @es::AppExprs @annos::AnnoAppExprs { local step1 :: String = e.translation; -- Note: we check for nullity of the index lists instead of use @@ -303,7 +303,7 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs annos::Decorated! AnnoA } aspect production dispatchApplication -top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs annos::Decorated! AnnoAppExprs +top::Expr ::= @e::Expr @es::AppExprs @annos::AnnoAppExprs { top.translation = e.invokeTranslation; top.lazyTranslation = e.invokeLazyTranslation; From 45f3a5992939a8852ffa58aa4b819d5a709eefc3 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 11 Mar 2024 18:46:20 -0500 Subject: [PATCH 184/283] Use dispatch for attribute access --- .../analysis/typechecking/core/Expr.sv | 6 +- .../compiler/analysis/uniqueness/Expr.sv | 20 +++--- .../compiler/analysis/warnings/flow/Inh.sv | 6 +- .../compiler/definition/core/DclInfo.sv | 10 +-- .../silver/compiler/definition/core/Expr.sv | 71 ++++++++++--------- .../silver/compiler/definition/core/Type.sv | 7 +- .../compiler/definition/flow/env/Expr.sv | 22 +++--- .../compiler/extension/autoattr/DclInfo.sv | 16 ++--- .../extension/implicit_monads/DclInfo.sv | 4 +- .../extension/implicit_monads/Expr.sv | 20 +++--- .../compiler/extension/rewriting/Expr.sv | 18 ++--- .../extension/strategyattr/DclInfo.sv | 2 +- .../modification/collection/DclInfo.sv | 2 +- .../compiler/translation/java/core/Expr.sv | 20 +++--- 14 files changed, 112 insertions(+), 112 deletions(-) diff --git a/grammars/silver/compiler/analysis/typechecking/core/Expr.sv b/grammars/silver/compiler/analysis/typechecking/core/Expr.sv index 5b7cf496c..414bf6bc8 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/Expr.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/Expr.sv @@ -83,7 +83,7 @@ top::Expr ::= e::Expr '.' q::QNameAttrOccur } aspect production undecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { -- We might have gotten here via a 'ntOrDec' type. So let's make certain we're UNdecorated, -- ensuring that type's specialization, otherwise we could end up in trouble! @@ -101,7 +101,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production accessBouncer -top::Expr ::= target::(Expr ::= Decorated! Expr Decorated! QNameAttrOccur) e::Expr q::Decorated! QNameAttrOccur +top::Expr ::= e::Expr @q::QNameAttrOccur target::Access { propagate upSubst, downSubst, finalSubst; } @@ -121,7 +121,7 @@ top::Expr ::= e::Expr '.' 'forward' } aspect production decoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { -- We might have gotten here via a 'ntOrDec' type. So let's make certain we're decorated, -- ensuring that type's specialization, otherwise we could end up in trouble! diff --git a/grammars/silver/compiler/analysis/uniqueness/Expr.sv b/grammars/silver/compiler/analysis/uniqueness/Expr.sv index b520cf6fd..a1b68b1fa 100644 --- a/grammars/silver/compiler/analysis/uniqueness/Expr.sv +++ b/grammars/silver/compiler/analysis/uniqueness/Expr.sv @@ -205,27 +205,27 @@ top::AppExpr ::= e::Expr } aspect production errorAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.uniqueRefs := e.accessUniqueRefs; } aspect production terminalAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.uniqueRefs := e.accessUniqueRefs; } aspect production synDecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.uniqueRefs := e.accessUniqueRefs; } aspect production inhDecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.uniqueRefs := e.accessUniqueRefs; } aspect production transDecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.uniqueRefs := case top.finalType, refSet of @@ -282,27 +282,27 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur end; } aspect production annoAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.uniqueRefs := e.accessUniqueRefs; } aspect production synDataAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.uniqueRefs := e.accessUniqueRefs; } aspect production inhUndecoratedAccessErrorHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.uniqueRefs := e.accessUniqueRefs; } aspect production transUndecoratedAccessErrorHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.uniqueRefs := e.accessUniqueRefs; } aspect production unknownDclAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.uniqueRefs := e.accessUniqueRefs; } diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index e01a1b487..a1e0277ee 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -679,7 +679,7 @@ top::Expr ::= e::Expr '.' 'forward' } aspect production synDecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { -- oh no again local myFlow :: EnvTree = head(searchEnvTree(top.grammarName, top.compiledGrammars)).grammarFlowTypes; @@ -783,7 +783,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production inhDecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { -- In this case, ONLY check for references. -- The transitive deps error will be less difficult to figure out when there's @@ -803,7 +803,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production transDecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { -- oh no again local myFlow :: EnvTree = head(searchEnvTree(top.grammarName, top.compiledGrammars)).grammarFlowTypes; diff --git a/grammars/silver/compiler/definition/core/DclInfo.sv b/grammars/silver/compiler/definition/core/DclInfo.sv index aa401173f..af44ebcc7 100644 --- a/grammars/silver/compiler/definition/core/DclInfo.sv +++ b/grammars/silver/compiler/definition/core/DclInfo.sv @@ -23,17 +23,17 @@ synthesized attribute transDefLHSDispatcher :: (DefLHS ::= Decorated! QName Dec - The handler for 'x.a' for 'a', given that 'x' is DECORATED. - @see decoratedAccessHandler production for where this is used -} -synthesized attribute decoratedAccessHandler :: (Expr ::= Decorated! Expr Decorated! QNameAttrOccur) occurs on AttributeDclInfo; +synthesized attribute decoratedAccessHandler :: Access occurs on AttributeDclInfo; {-- - The handler for 'x.a' for 'a', given that 'x' is UNdecorated. - @see undecoratedAccessHandler production for where this is used -} -synthesized attribute undecoratedAccessHandler :: (Expr ::= Decorated! Expr Decorated! QNameAttrOccur) occurs on AttributeDclInfo; +synthesized attribute undecoratedAccessHandler :: Access occurs on AttributeDclInfo; {-- - The handler for 'x.a' for 'a', given that 'x' is data. - @see dataAccessHandler production for where this is used -} -synthesized attribute dataAccessHandler :: (Expr ::= Decorated! Expr Decorated! QNameAttrOccur) occurs on AttributeDclInfo; +synthesized attribute dataAccessHandler :: Access occurs on AttributeDclInfo; {-- - The production an "equation" should forward to for this type of attribute (i.e. the 'a' in 'x.a = e') -} @@ -129,7 +129,7 @@ aspect production synDcl top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type { top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = synthesizedAttributeDef; top.attributionDispatcher = defaultAttributionDcl; @@ -155,7 +155,7 @@ top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type aspect production annoDcl top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type { - top.decoratedAccessHandler = accessBounceUndecorate(annoAccessHandler, _, _); + top.decoratedAccessHandler = accessBounceUndecorate(annoAccessHandler); top.undecoratedAccessHandler = annoAccessHandler; top.dataAccessHandler = annoAccessHandler; top.attrDefDispatcher = diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index afc421972..719599c96 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -418,8 +418,10 @@ top::Expr ::= e::Expr '.' q::QNameAttrOccur -- terminalAccessHandler } -abstract production errorAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +dispatch Access = Expr ::= @e::Expr @q::QNameAttrOccur; + +abstract production errorAccessHandler implements Access +top::Expr ::= @e::Expr @q::QNameAttrOccur { undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; @@ -434,8 +436,8 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur end; } -abstract production terminalAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +abstract production terminalAccessHandler implements Access +top::Expr ::= @e::Expr @q::QNameAttrOccur { undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; @@ -459,8 +461,8 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur else errorType(); } -abstract production undecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +abstract production undecoratedAccessHandler implements Access +top::Expr ::= @e::Expr @q::QNameAttrOccur { undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; @@ -474,8 +476,8 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur -- unknownDclAccessHandler -- unknown attribute error raised already. } -abstract production dataAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +abstract production dataAccessHandler implements Access +top::Expr ::= @e::Expr @q::QNameAttrOccur { undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; @@ -493,7 +495,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur - This production is intended to permit that. -} abstract production accessBouncer -top::Expr ::= target::(Expr ::= Decorated! Expr Decorated! QNameAttrOccur) e::Expr q::Decorated! QNameAttrOccur +top::Expr ::= e::Expr @q::QNameAttrOccur target::Access { undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; @@ -503,26 +505,27 @@ top::Expr ::= target::(Expr ::= Decorated! Expr Decorated! QNameAttrOccur) e::E -- Basically the only purpose here is to decorate 'e'. forwards to target(e, q); } -function accessBounceDecorate -Expr ::= target::(Expr ::= Decorated! Expr Decorated! QNameAttrOccur) e::Decorated! Expr q::Decorated! QNameAttrOccur +production accessBounceDecorate implements Access +Expr ::= @e::Expr @q::QNameAttrOccur target::Access { - return accessBouncer(target, decorateExprWithEmpty('decorate', @e, 'with', '{', '}'), q); + forwards to + accessBouncer(decorateExprWithEmpty('decorate', @e, 'with', '{', '}'), q, target); } -- Note that this performs the access on the term that was originally decorated, rather than properly undecorating. -function accessBounceUndecorate -Expr ::= target::(Expr ::= Decorated! Expr Decorated! QNameAttrOccur) e::Decorated! Expr q::Decorated! QNameAttrOccur +production accessBounceUndecorate implements Access +Expr ::= @e::Expr @q::QNameAttrOccur target::Access { - return accessBouncer(target, + forwards to accessBouncer( application( baseExpr(qName("silver:core:getTermThatWasDecorated")), '(', oneAppExprs( presentAppExpr(@e)), ',', emptyAnnoAppExprs(), ')'), - q); + q, target); } -abstract production decoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +abstract production decoratedAccessHandler implements Access +top::Expr ::= @e::Expr @q::QNameAttrOccur { undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; @@ -536,8 +539,8 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur -- unknownDclAccessHandler -- unknown attribute error raised already. } -abstract production synDecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +abstract production synDecoratedAccessHandler implements Access +top::Expr ::= @e::Expr @q::QNameAttrOccur { undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; @@ -545,8 +548,8 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur top.typerep = q.typerep; } -abstract production inhDecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +abstract production inhDecoratedAccessHandler implements Access +top::Expr ::= @e::Expr @q::QNameAttrOccur { undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; @@ -554,8 +557,8 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur top.typerep = q.typerep; } -abstract production transDecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +abstract production transDecoratedAccessHandler implements Access +top::Expr ::= @e::Expr @q::QNameAttrOccur { undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; @@ -563,8 +566,8 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur top.typerep = q.typerep.asNtOrDecType; } -abstract production annoAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +abstract production annoAccessHandler implements Access +top::Expr ::= @e::Expr @q::QNameAttrOccur { undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; @@ -575,8 +578,8 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur top.typerep = q.typerep; } -abstract production synDataAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +abstract production synDataAccessHandler implements Access +top::Expr ::= @e::Expr @q::QNameAttrOccur { undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; @@ -584,8 +587,8 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur top.typerep = q.typerep; } -abstract production inhUndecoratedAccessErrorHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +abstract production inhUndecoratedAccessErrorHandler implements Access +top::Expr ::= @e::Expr @q::QNameAttrOccur { undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; @@ -595,8 +598,8 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur top.errors <- [errFromOrigin(top, s"Cannot access inherited attribute ${q.attrDcl.fullName} from an undecorated type")]; } -abstract production transUndecoratedAccessErrorHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +abstract production transUndecoratedAccessErrorHandler implements Access +top::Expr ::= @e::Expr @q::QNameAttrOccur { undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; @@ -606,8 +609,8 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur top.errors <- [errFromOrigin(top, s"Cannot access translation attribute ${q.attrDcl.fullName} from an undecorated type")]; } -abstract production unknownDclAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +abstract production unknownDclAccessHandler implements Access +top::Expr ::= @e::Expr @q::QNameAttrOccur { undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; diff --git a/grammars/silver/compiler/definition/core/Type.sv b/grammars/silver/compiler/definition/core/Type.sv index eea642f17..83bd2799e 100644 --- a/grammars/silver/compiler/definition/core/Type.sv +++ b/grammars/silver/compiler/definition/core/Type.sv @@ -4,7 +4,7 @@ grammar silver:compiler:definition:core; synthesized attribute applicationDispatcher :: Application; -- LHS type gives this to 'access' for "foo.some" accesses. -- (See DclInfo for the next step) -synthesized attribute accessHandler :: (Expr ::= Decorated! Expr Decorated! QNameAttrOccur); +synthesized attribute accessHandler :: Access; attribute applicationDispatcher, accessHandler occurs on Type; @@ -31,10 +31,7 @@ top::Type ::= _ aspect production nonterminalType top::Type ::= fn::String _ data::Boolean _ { - top.accessHandler = - if data - then dataAccessHandler(_, _) - else undecoratedAccessHandler(_, _); + top.accessHandler = if data then dataAccessHandler else undecoratedAccessHandler; } aspect production terminalType diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index 93276574c..1bac134d0 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -278,7 +278,7 @@ top::Expr ::= e::Expr '.' q::QNameAttrOccur } aspect production accessBouncer -top::Expr ::= target::(Expr ::= Decorated! Expr Decorated! QNameAttrOccur) e::Expr q::Decorated! QNameAttrOccur +top::Expr ::= e::Expr @q::QNameAttrOccur target::Access { propagate flowEnv; e.alwaysDecorated = false; @@ -298,19 +298,19 @@ top::Expr ::= e::Expr '.' 'forward' aspect production errorAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { e.decSiteVertexInfo = nothing(); } aspect production terminalAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { e.decSiteVertexInfo = nothing(); } -- Note that below we IGNORE the flow deps of the lhs if we know what it is -- this is because by default the lhs will have 'taking ref' flow deps (see above) aspect production synDecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.flowDeps := case e.flowVertexInfo of @@ -320,7 +320,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur e.decSiteVertexInfo = nothing(); } aspect production inhDecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.flowDeps := case e.flowVertexInfo of @@ -330,7 +330,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur e.decSiteVertexInfo = nothing(); } aspect production transDecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { production refSet::Maybe<[String]> = getMaxRefSet(top.finalType, top.env); top.flowVertexInfo = map(transAttrVertexType(_, q.attrDcl.fullName), e.flowVertexInfo); @@ -365,29 +365,29 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur e.decSiteVertexInfo = nothing(); } aspect production annoAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { e.decSiteVertexInfo = nothing(); } aspect production synDataAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { -- No flow vertex, since there are never any inh deps e.decSiteVertexInfo = nothing(); } aspect production inhUndecoratedAccessErrorHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { e.decSiteVertexInfo = nothing(); } aspect production transUndecoratedAccessErrorHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { e.decSiteVertexInfo = nothing(); } aspect production unknownDclAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { e.decSiteVertexInfo = nothing(); } diff --git a/grammars/silver/compiler/extension/autoattr/DclInfo.sv b/grammars/silver/compiler/extension/autoattr/DclInfo.sv index 670423549..6ad44e6ba 100644 --- a/grammars/silver/compiler/extension/autoattr/DclInfo.sv +++ b/grammars/silver/compiler/extension/autoattr/DclInfo.sv @@ -28,7 +28,7 @@ top::AttributeDclInfo ::= fn::String top.isSynthesized = true; top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations top.attributionDispatcher = functorAttributionDcl; @@ -53,7 +53,7 @@ top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type empty::Expr append: top.operation = append; top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr -> @@ -93,7 +93,7 @@ top::AttributeDclInfo ::= inh::String syn::String top.isSynthesized = true; top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations top.attributionDispatcher = defaultAttributionDcl; @@ -110,7 +110,7 @@ top::AttributeDclInfo ::= syn::String top.isSynthesized = true; top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations top.attributionDispatcher = defaultAttributionDcl; @@ -127,7 +127,7 @@ top::AttributeDclInfo ::= inh::String keySyn::String syn::String top.isSynthesized = true; top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations top.attributionDispatcher = defaultAttributionDcl; @@ -144,7 +144,7 @@ top::AttributeDclInfo ::= inh::String synPartial::String syn::String top.isSynthesized = true; top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations top.attributionDispatcher = defaultAttributionDcl; @@ -161,7 +161,7 @@ top::AttributeDclInfo ::= inh::String synPartial::String syn::String top.isSynthesized = true; top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations top.attributionDispatcher = defaultAttributionDcl; @@ -222,7 +222,7 @@ top::AttributeDclInfo ::= inh::String syn::String bound::[TyVar] ty::Type o::May top.operation = o.fromJust; top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = if o.isJust diff --git a/grammars/silver/compiler/extension/implicit_monads/DclInfo.sv b/grammars/silver/compiler/extension/implicit_monads/DclInfo.sv index 0cebceb49..82ad511e4 100644 --- a/grammars/silver/compiler/extension/implicit_monads/DclInfo.sv +++ b/grammars/silver/compiler/extension/implicit_monads/DclInfo.sv @@ -8,7 +8,7 @@ top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type --copied from synDcl top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler); top.dataAccessHandler = synDataAccessHandler; top.attributionDispatcher = defaultAttributionDcl; @@ -52,7 +52,7 @@ top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type --copied from synDcl top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler); top.dataAccessHandler = synDataAccessHandler; top.attributionDispatcher = defaultAttributionDcl; diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index 233000c6c..0d576c30f 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -479,7 +479,7 @@ top::Expr ::= e::Expr '.' 'forward' } aspect production errorAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { e.monadicallyUsed = false; --this needs to change when we decorate monadic trees top.monadicNames = if top.monadicallyUsed @@ -554,7 +554,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production annoAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { e.mDownSubst = top.mDownSubst; e.monadicallyUsed = false; --this needs to change when we decorate monadic trees @@ -613,7 +613,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production synDataAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { e.mDownSubst = top.mDownSubst; e.monadicallyUsed = false; --this needs to change when we decorate monadic trees @@ -686,7 +686,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production terminalAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { e.mDownSubst = top.mDownSubst; @@ -734,7 +734,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production synDecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { e.mDownSubst = top.mDownSubst; e.monadicallyUsed = false; --this needs to change when we decorate monadic trees @@ -807,7 +807,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production inhDecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { e.mDownSubst = top.mDownSubst; e.monadicallyUsed = false; --this needs to change when we decorate monadic trees @@ -881,7 +881,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur -- TODO: restricted translation attributes? aspect production transDecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { e.monadicallyUsed = false; --this needs to change when we decorate monadic trees top.monadicNames = if top.monadicallyUsed @@ -936,7 +936,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production unknownDclAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { e.mDownSubst = top.mDownSubst; @@ -1010,7 +1010,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production inhUndecoratedAccessErrorHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { e.monadicallyUsed = false; --this needs to change when we decorate monadic trees top.monadicNames = if top.monadicallyUsed @@ -1064,7 +1064,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur -- TODO: restricted translation attributes? aspect production transUndecoratedAccessErrorHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { e.monadicallyUsed = false; --this needs to change when we decorate monadic trees top.monadicNames = if top.monadicallyUsed diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index 90fe27eb1..659788fe5 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -206,7 +206,7 @@ top::Expr ::= e::Expr '.' 'forward' } aspect production errorAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.transform = applyASTExpr( @@ -220,7 +220,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production annoAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.transform = applyASTExpr( @@ -234,7 +234,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production synDataAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.transform = applyASTExpr( @@ -248,7 +248,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production terminalAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.transform = applyASTExpr( @@ -263,7 +263,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur aspect production synDecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { -- Flow analysis has no way to track what e is decorated with across reflect/reify, -- so if the inh set is unspecialized, assume that it has the reference set. @@ -323,7 +323,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production inhDecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { -- Flow analysis has no way to track what e is decorated with across reflect/reify, -- so if the inh set is unspecialized, assume that it has the reference set. @@ -345,7 +345,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production inhUndecoratedAccessErrorHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { -- Flow analysis has no way to track what e is decorated with across reflect/reify, -- so if the inh set is unspecialized, assume that it has the reference set. @@ -367,7 +367,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production transUndecoratedAccessErrorHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { -- Flow analysis has no way to track what e is decorated with across reflect/reify, -- so if the inh set is unspecialized, assume that it has the reference set. @@ -389,7 +389,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production unknownDclAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { -- Flow analysis has no way to track what e is decorated with across reflect/reify, -- so if the inh set is unspecialized, assume that it has the reference set. diff --git a/grammars/silver/compiler/extension/strategyattr/DclInfo.sv b/grammars/silver/compiler/extension/strategyattr/DclInfo.sv index d8a422a01..86b5b3b90 100644 --- a/grammars/silver/compiler/extension/strategyattr/DclInfo.sv +++ b/grammars/silver/compiler/extension/strategyattr/DclInfo.sv @@ -44,7 +44,7 @@ top::AttributeDclInfo ::= top.isStrategy = true; top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations top.attributionDispatcher = strategyAttributionDcl; diff --git a/grammars/silver/compiler/modification/collection/DclInfo.sv b/grammars/silver/compiler/modification/collection/DclInfo.sv index c50a793ab..c84dfaab0 100644 --- a/grammars/silver/compiler/modification/collection/DclInfo.sv +++ b/grammars/silver/compiler/modification/collection/DclInfo.sv @@ -47,7 +47,7 @@ top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type o::Operation top.operation = o; top.decoratedAccessHandler = synDecoratedAccessHandler; - top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler, _, _); + top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler); top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = collectionAttrDefError; top.attributionDispatcher = defaultAttributionDcl; diff --git a/grammars/silver/compiler/translation/java/core/Expr.sv b/grammars/silver/compiler/translation/java/core/Expr.sv index bb24ec78a..4257ef306 100644 --- a/grammars/silver/compiler/translation/java/core/Expr.sv +++ b/grammars/silver/compiler/translation/java/core/Expr.sv @@ -319,28 +319,28 @@ top::Expr ::= @e::Expr @es::AppExprs @annos::AnnoAppExprs } aspect production errorAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.translation = error("Internal compiler error: translation not defined in the presence of errors"); top.lazyTranslation = top.translation; } aspect production inhUndecoratedAccessErrorHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.translation = error("Internal compiler error: translation not defined in the presence of errors"); top.lazyTranslation = top.translation; } aspect production transUndecoratedAccessErrorHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.translation = error("Internal compiler error: translation not defined in the presence of errors"); top.lazyTranslation = top.translation; } aspect production unknownDclAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.translation = error("Internal compiler error: translation not defined in the presence of errors"); top.lazyTranslation = top.translation; @@ -354,7 +354,7 @@ top::Expr ::= e::Expr '.' 'forward' } aspect production synDecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.translation = wrapAccessWithOT(top, s"${e.translation}.<${top.finalType.transType}>synthesized(${q.attrOccursIndex})"); @@ -373,7 +373,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production inhDecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.translation = wrapAccessWithOT(top, s"${e.translation}.<${top.finalType.transType}>inherited(${q.attrOccursIndex})"); @@ -385,7 +385,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production transDecoratedAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { -- TODO: Origin tracking? top.translation = @@ -427,7 +427,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production terminalAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { local accessor :: String = if q.name == "lexeme" || q.name == "location" @@ -446,7 +446,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production annoAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { local accessTrans::String = s"((${makeAnnoName(q.attrDcl.fullName)})${e.translation}).getAnno_${makeIdName(q.attrDcl.fullName)}()"; -- Note that the transType is specific to the nonterminal we're accessing from. @@ -459,7 +459,7 @@ top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur } aspect production synDataAccessHandler -top::Expr ::= e::Decorated! Expr q::Decorated! QNameAttrOccur +top::Expr ::= @e::Expr @q::QNameAttrOccur { top.translation = wrapAccessWithOT(top, s"${e.translation}.<${top.finalType.transType}>synthesized(${q.attrOccursIndex})"); From 460cb8308c1355eec2f8d0c5863bd331e08c41ef Mon Sep 17 00:00:00 2001 From: unironically Date: Mon, 11 Mar 2024 18:50:34 -0500 Subject: [PATCH 185/283] Defining equations allowing concise main functions, rewriting select tutorial main functions concisely --- .../translation/java/core/FunctionDcl.sv | 32 +++++++++++++++++++ tutorials/hello/Hello.sv | 9 ++---- tutorials/hello/silver-compile | 3 +- tutorials/lambda/Main.sv | 8 ++--- tutorials/simple/src/simple/arb/Main.sv | 8 ++--- tutorials/simple/src/simple/host/Main.sv | 9 ++---- 6 files changed, 45 insertions(+), 24 deletions(-) diff --git a/grammars/silver/compiler/translation/java/core/FunctionDcl.sv b/grammars/silver/compiler/translation/java/core/FunctionDcl.sv index 38bef5900..316effe51 100644 --- a/grammars/silver/compiler/translation/java/core/FunctionDcl.sv +++ b/grammars/silver/compiler/translation/java/core/FunctionDcl.sv @@ -3,6 +3,38 @@ grammar silver:compiler:translation:java:core; import silver:compiler:modification:ffi only ioForeignType; -- for main type check only import silver:compiler:modification:list only listCtrType; +import silver:compiler:modification:concisefunctions; + +aspect production shortFunctionDcl +top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' +{ + -- For main functions which return IOVal + local attribute typeIOValFailed::Boolean = unify(namedSig.typerep, + appTypes( + functionType(2, []), + [appType(listCtrType(), stringType()), + ioForeignType, + appType(nonterminalType("silver:core:IOVal", [starKind()], true, false), intType())])).failure; + + -- For main functions which return IO + local attribute typeIOMonadFailed::Boolean = unify(namedSig.typerep, + appTypes( + functionType(1, []), + [appType(listCtrType(), stringType()), + appType(nonterminalType("silver:core:IO", [starKind()], false, false), intType())])).failure; + + top.genFiles <- + if id.name == "main" + then [("Main.java", generateMainClassString(top.grammarName, !typeIOValFailed))] + else []; + + top.errors <- + if id.name == "main" && typeIOValFailed && typeIOMonadFailed -- Neither legal main function type used + then [errFromOrigin(top, "main function must have type signature (IOVal ::= [String] IOToken) " ++ + "or (IO ::= [String]). Instead it has type " ++ prettyType(namedSig.typerep))] + else []; +} + aspect production functionDcl top::AGDcl ::= 'function' id::Name ns::FunctionSignature body::ProductionBody { diff --git a/tutorials/hello/Hello.sv b/tutorials/hello/Hello.sv index dc29080da..8fdba2bd5 100644 --- a/tutorials/hello/Hello.sv +++ b/tutorials/hello/Hello.sv @@ -1,10 +1,7 @@ grammar hello; -function main -IO ::= largs::[String] -{ - return do { +fun main IO ::= largs::[String] = + do { print("Hello, world!\n"); return 0; - }; -} + }; \ No newline at end of file diff --git a/tutorials/hello/silver-compile b/tutorials/hello/silver-compile index 515cc0846..183865ece 100755 --- a/tutorials/hello/silver-compile +++ b/tutorials/hello/silver-compile @@ -6,5 +6,4 @@ silver() { "../../support/bin/silver" "$@"; } SRC=.. # cheating a bit. Current directory should be 'hello' GRAMMAR=hello -silver -I $SRC $@ $GRAMMAR - +silver -I $SRC $@ $GRAMMAR \ No newline at end of file diff --git a/tutorials/lambda/Main.sv b/tutorials/lambda/Main.sv index 66644f506..285d0f9b8 100644 --- a/tutorials/lambda/Main.sv +++ b/tutorials/lambda/Main.sv @@ -23,8 +23,6 @@ parser hostParse :: Root_c { lambda; } -function main -IOVal ::= largs::[String] io_in::IOToken -{ - return driver(largs, hostParse, io_in) ; -} +fun main +IOVal ::= largs::[String] io_in::IOToken = + driver(largs, hostParse, io_in); diff --git a/tutorials/simple/src/simple/arb/Main.sv b/tutorials/simple/src/simple/arb/Main.sv index 1541e8253..e27758087 100644 --- a/tutorials/simple/src/simple/arb/Main.sv +++ b/tutorials/simple/src/simple/arb/Main.sv @@ -7,8 +7,6 @@ generator generate :: simple:concretesyntax:Root { simple:host; } -function main -IOVal ::= args::[String] io_in::IOToken -{ - return ioval(arbDriver(args, io_in, generate), 0); -} +fun main +IOVal ::= args::[String] io_in::IOToken = + ioval(arbDriver(args, io_in, generate), 0); diff --git a/tutorials/simple/src/simple/host/Main.sv b/tutorials/simple/src/simple/host/Main.sv index 07e51d08f..02788f799 100644 --- a/tutorials/simple/src/simple/host/Main.sv +++ b/tutorials/simple/src/simple/host/Main.sv @@ -23,9 +23,6 @@ parser parse :: simple:concretesyntax:Root { simple:terminals; } -function main -IOVal ::= args::[String] io_in::IOToken -{ - return ioval(driver(args, io_in, parse), 0); -} - +fun main +IOVal ::= args::[String] io_in::IOToken = + ioval(driver(args, io_in, parse), 0); \ No newline at end of file From 9c2f6e98e984cb0018fc7d570d8164be2597fe9d Mon Sep 17 00:00:00 2001 From: unironically Date: Mon, 11 Mar 2024 18:54:52 -0500 Subject: [PATCH 186/283] Fixing indentation --- .../translation/java/core/FunctionDcl.sv | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/grammars/silver/compiler/translation/java/core/FunctionDcl.sv b/grammars/silver/compiler/translation/java/core/FunctionDcl.sv index 316effe51..876e8675a 100644 --- a/grammars/silver/compiler/translation/java/core/FunctionDcl.sv +++ b/grammars/silver/compiler/translation/java/core/FunctionDcl.sv @@ -8,7 +8,7 @@ import silver:compiler:modification:concisefunctions; aspect production shortFunctionDcl top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' { - -- For main functions which return IOVal + -- For main functions which return IOVal local attribute typeIOValFailed::Boolean = unify(namedSig.typerep, appTypes( functionType(2, []), @@ -23,16 +23,16 @@ top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' [appType(listCtrType(), stringType()), appType(nonterminalType("silver:core:IO", [starKind()], false, false), intType())])).failure; - top.genFiles <- - if id.name == "main" - then [("Main.java", generateMainClassString(top.grammarName, !typeIOValFailed))] - else []; + top.genFiles <- + if id.name == "main" + then [("Main.java", generateMainClassString(top.grammarName, !typeIOValFailed))] + else []; - top.errors <- + top.errors <- if id.name == "main" && typeIOValFailed && typeIOMonadFailed -- Neither legal main function type used - then [errFromOrigin(top, "main function must have type signature (IOVal ::= [String] IOToken) " ++ - "or (IO ::= [String]). Instead it has type " ++ prettyType(namedSig.typerep))] - else []; + then [errFromOrigin(top, "main function must have type signature (IOVal ::= [String] IOToken) " ++ + "or (IO ::= [String]). Instead it has type " ++ prettyType(namedSig.typerep))] + else []; } aspect production functionDcl From 6e867dfa60f45028eded8e86e3fe1956c267ab86 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 12 Mar 2024 11:22:59 -0500 Subject: [PATCH 187/283] Use dispatch for attribute defs --- .../typechecking/core/ProductionBody.sv | 6 +- .../analysis/uniqueness/ProductionBody.sv | 12 +-- .../compiler/analysis/warnings/flow/Inh.sv | 12 +-- .../warnings/flow/OrphanedEquation.sv | 8 +- .../compiler/definition/core/DclInfo.sv | 8 +- .../definition/core/ProductionBody.sv | 26 +++-- .../definition/flow/env/ProductionBody.sv | 14 +-- .../compiler/extension/autoattr/DclInfo.sv | 28 +++-- .../compiler/extension/autoattr/Monoid.sv | 8 ++ .../implicit_monads/ProductionBody.sv | 102 +++++++++--------- .../modification/collection/Collection.sv | 45 +++++--- .../modification/collection/DclInfo.sv | 25 ++--- .../collection/java/Collection.sv | 8 +- .../translation/java/core/ProductionBody.sv | 6 +- 14 files changed, 161 insertions(+), 147 deletions(-) diff --git a/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv b/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv index 929d32f63..b77746d9b 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv @@ -117,7 +117,7 @@ top::ProductionStmt ::= 'return' e::Expr ';' } aspect production synthesizedAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { local attribute errCheck1 :: TypeCheck; errCheck1.finalSubst = top.finalSubst; @@ -131,7 +131,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur } aspect production inheritedAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { local attribute errCheck1 :: TypeCheck; errCheck1.finalSubst = top.finalSubst; @@ -145,7 +145,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur } aspect production errorAttributeDef -top::ProductionStmt ::= msg::[Message] dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= msg::[Message] @dl::DefLHS @attr::QNameAttrOccur e::Expr { propagate downSubst, upSubst, finalSubst; } diff --git a/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv b/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv index 72e23bfa7..a061fbd5a 100644 --- a/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv +++ b/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv @@ -38,36 +38,36 @@ top::ProductionStmt ::= 'undecorates' 'to' e::Expr ';' top.errors <- uniqueContextErrors(e.uniqueRefs); } aspect production synthesizedAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { top.errors <- if !attr.found || attr.attrDcl.isTranslation then [] else uniqueContextErrors(e.uniqueRefs); } aspect production inheritedAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { top.errors <- uniqueContextErrors(e.uniqueRefs); } -- Modifications aspect production synAppendColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur {- <- -} e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur {- <- -} e::Expr { top.errors <- uniqueContextErrors(e.uniqueRefs); } aspect production inhAppendColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur {- <- -} e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur {- <- -} e::Expr { top.errors <- uniqueContextErrors(e.uniqueRefs); } aspect production synBaseColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { top.errors <- uniqueContextErrors(e.uniqueRefs); } aspect production inhBaseColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { top.errors <- uniqueContextErrors(e.uniqueRefs); } diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index a1e0277ee..734b1dc60 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -238,7 +238,7 @@ top::InstanceBodyItem ::= id::QName '=' e::Expr ';' } aspect production synthesizedAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { -- oh no again! local myFlow :: EnvTree = head(searchEnvTree(top.grammarName, top.compiledGrammars)).grammarFlowTypes; @@ -258,7 +258,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur } aspect production inheritedAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { -- oh no again! local myFlow :: EnvTree = head(searchEnvTree(top.grammarName, top.compiledGrammars)).grammarFlowTypes; @@ -398,7 +398,7 @@ top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur ----- WARNING TODO BEGIN MASSIVE COPY & PASTE SESSION aspect production synBaseColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { -- oh no again! local myFlow :: EnvTree = head(searchEnvTree(top.grammarName, top.compiledGrammars)).grammarFlowTypes; @@ -417,7 +417,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur else []; } aspect production synAppendColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { -- oh no again! local myFlow :: EnvTree = head(searchEnvTree(top.grammarName, top.compiledGrammars)).grammarFlowTypes; @@ -436,7 +436,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur else []; } aspect production inhBaseColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { -- oh no again! local myFlow :: EnvTree = head(searchEnvTree(top.grammarName, top.compiledGrammars)).grammarFlowTypes; @@ -462,7 +462,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur else []; } aspect production inhAppendColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { -- oh no again! local myFlow :: EnvTree = head(searchEnvTree(top.grammarName, top.compiledGrammars)).grammarFlowTypes; diff --git a/grammars/silver/compiler/analysis/warnings/flow/OrphanedEquation.sv b/grammars/silver/compiler/analysis/warnings/flow/OrphanedEquation.sv index d30a0b134..76b6f8453 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/OrphanedEquation.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/OrphanedEquation.sv @@ -26,7 +26,7 @@ Either ::= args::[String] } aspect production synthesizedAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { local exportedBy :: [String] = if top.frame.hasPartialSignature @@ -49,7 +49,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e } aspect production inheritedAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { local exportedBy :: [String] = case dl of @@ -84,7 +84,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur --- FROM COLLECTIONS aspect production synBaseColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { local exportedBy :: [String] = if top.frame.hasPartialSignature @@ -106,7 +106,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur else []; } aspect production inhBaseColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { local exportedBy :: [String] = case dl of diff --git a/grammars/silver/compiler/definition/core/DclInfo.sv b/grammars/silver/compiler/definition/core/DclInfo.sv index af44ebcc7..070e8c382 100644 --- a/grammars/silver/compiler/definition/core/DclInfo.sv +++ b/grammars/silver/compiler/definition/core/DclInfo.sv @@ -37,7 +37,7 @@ synthesized attribute dataAccessHandler :: Access occurs on AttributeDclInfo; {-- - The production an "equation" should forward to for this type of attribute (i.e. the 'a' in 'x.a = e') -} -synthesized attribute attrDefDispatcher :: (ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr) occurs on AttributeDclInfo; +synthesized attribute attrDefDispatcher :: AttributeDef occurs on AttributeDclInfo; {-- - The production an "occurs on" decl should forward to for this type of attribute (for extension use, defaultAttributionDcl for all syn/inh attrs.) -} @@ -158,8 +158,6 @@ top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type top.decoratedAccessHandler = accessBounceUndecorate(annoAccessHandler); top.undecoratedAccessHandler = annoAccessHandler; top.dataAccessHandler = annoAccessHandler; - top.attrDefDispatcher = - \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr -> - errorAttributeDef([errFromOrigin(ambientOrigin(), "Annotations are not defined as equations within productions")], dl, attr, e); + top.attrDefDispatcher = annoErrorAttributeDef; top.attributionDispatcher = defaultAttributionDcl; -} \ No newline at end of file +} diff --git a/grammars/silver/compiler/definition/core/ProductionBody.sv b/grammars/silver/compiler/definition/core/ProductionBody.sv index cf81be33b..383e9ac98 100644 --- a/grammars/silver/compiler/definition/core/ProductionBody.sv +++ b/grammars/silver/compiler/definition/core/ProductionBody.sv @@ -305,10 +305,7 @@ top::ProductionStmt ::= dl::DefLHS '.' attr::QNameAttrOccur '=' e::Expr ';' dl.defLHSattr = attr; attr.attrFor = dl.typerep; - local problems :: [Message] = - if attr.found && attr.attrDcl.isAnnotation - then [errFromOrigin(attr, attr.name ++ " is an annotation, which are supplied to productions as arguments, not defined as equations.")] - else dl.errors ++ attr.errors; + local problems :: [Message] = dl.errors ++ attr.errors; forwards to -- oddly enough we may have no errors and need to forward to error production: @@ -323,9 +320,8 @@ top::ProductionStmt ::= dl::DefLHS '.' attr::QNameAttrOccur '=' e::Expr ';' {- This is a helper that exist primarily to decorate 'e' and add its error messages to the list. Invariant: msg should not be null! -} abstract production errorAttributeDef -top::ProductionStmt ::= msg::[Message] dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= msg::[Message] @dl::DefLHS @attr::QNameAttrOccur e::Expr { - undecorates to errorProductionStmt(msg); top.unparse = "\t" ++ dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; propagate grammarName, config, env, frame, compiledGrammars, originRules; e.isRoot = true; @@ -333,8 +329,18 @@ top::ProductionStmt ::= msg::[Message] dl::Decorated! DefLHS attr::Decorated! Q forwards to errorProductionStmt(msg ++ e.errors); } -abstract production synthesizedAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +dispatch AttributeDef = ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr; + +abstract production annoErrorAttributeDef implements AttributeDef +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr +{ + forwards to errorAttributeDef( + [errFromOrigin(attr, attr.name ++ " is an annotation, which are supplied to productions as arguments, not defined as equations.")], + dl, attr, e); +} + +abstract production synthesizedAttributeDef implements AttributeDef +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { undecorates to attributeDef(dl, '.', attr, '=', e, ';'); top.unparse = "\t" ++ dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; @@ -349,8 +355,8 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur end; } -abstract production inheritedAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +abstract production inheritedAttributeDef implements AttributeDef +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { undecorates to attributeDef(dl, '.', attr, '=', e, ';'); top.unparse = "\t" ++ dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; diff --git a/grammars/silver/compiler/definition/flow/env/ProductionBody.sv b/grammars/silver/compiler/definition/flow/env/ProductionBody.sv index bca5555ac..3c3e828bb 100644 --- a/grammars/silver/compiler/definition/flow/env/ProductionBody.sv +++ b/grammars/silver/compiler/definition/flow/env/ProductionBody.sv @@ -91,12 +91,12 @@ top::ProductionStmt ::= dl::DefLHS '.' attr::QNameAttrOccur '=' e::Expr ';' propagate flowEnv; } aspect production errorAttributeDef -top::ProductionStmt ::= msg::[Message] dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= msg::[Message] @dl::DefLHS @attr::QNameAttrOccur e::Expr { propagate flowEnv; } aspect production synthesizedAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { local ntDefGram :: String = hackGramFromFName(top.frame.lhsNtName); @@ -117,7 +117,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e.alwaysDecorated = attr.found && attr.attrDcl.isTranslation; } aspect production inheritedAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { top.flowDefs <- flap(dl.defLHSInhEq, e.flowDeps); e.decSiteVertexInfo = nothing(); @@ -214,7 +214,7 @@ top::ProductionStmt ::= val::Decorated! QName e::Expr -- FROM COLLECTIONS TODO aspect production synAppendColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur {- <- -} e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur {- <- -} e::Expr { local ntDefGram :: String = hackGramFromFName(top.frame.lhsNtName); @@ -228,14 +228,14 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur } aspect production inhAppendColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur {- <- -} e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur {- <- -} e::Expr { top.flowDefs <- [extraEq(top.frame.fullName, dl.defLHSVertex.inhVertex(attr.attrDcl.fullName), e.flowDeps, true)]; e.decSiteVertexInfo = nothing(); e.alwaysDecorated = false; } aspect production synBaseColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { local ntDefGram :: String = hackGramFromFName(top.frame.lhsNtName); @@ -253,7 +253,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e.alwaysDecorated = false; } aspect production inhBaseColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { top.flowDefs <- flap(dl.defLHSInhEq, e.flowDeps); e.decSiteVertexInfo = nothing(); diff --git a/grammars/silver/compiler/extension/autoattr/DclInfo.sv b/grammars/silver/compiler/extension/autoattr/DclInfo.sv index 6ad44e6ba..677f95b09 100644 --- a/grammars/silver/compiler/extension/autoattr/DclInfo.sv +++ b/grammars/silver/compiler/extension/autoattr/DclInfo.sv @@ -55,9 +55,7 @@ top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type empty::Expr append: top.decoratedAccessHandler = synDecoratedAccessHandler; top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler); top.dataAccessHandler = synDataAccessHandler; - top.attrDefDispatcher = - \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr -> - errorAttributeDef([errFromOrigin(ambientOrigin(), attr.name ++ " is a monoid collection attribute, and you must use ':=' or '<-', not '='.")], dl, attr, e); + top.attrDefDispatcher = monoidErrorRegularAttributeDef; top.attrBaseDefDispatcher = synBaseColAttributeDef; top.attrAppendDefDispatcher = synAppendColAttributeDef; top.attributionDispatcher = defaultAttributionDcl; @@ -190,16 +188,16 @@ top::AttributeDclInfo ::= inh::String syn::String bound::[TyVar] ty::Type o::May top.dataAccessHandler = inhUndecoratedAccessErrorHandler; top.attrDefDispatcher = if o.isJust - then collectionAttrDefError - else inheritedAttributeDef(_, _, _); -- Allow normal inh equations + then collectionErrorRegularAttributeDef + else inheritedAttributeDef; -- Allow normal inh equations top.attrBaseDefDispatcher = if o.isJust - then inhBaseColAttributeDef(_, _, _) -- Allow normal inh base equations - else nonCollectionAttrBaseDefError; + then inhBaseColAttributeDef -- Allow normal inh base equations + else nonCollectionErrorBaseAttributeDef; top.attrAppendDefDispatcher = if o.isJust - then inhAppendColAttributeDef(_, _, _) -- Allow normal inh append equations - else nonCollectionAttrAppendDefError; + then inhAppendColAttributeDef -- Allow normal inh append equations + else nonCollectionErrorAppendAttributeDef; top.attributionDispatcher = defaultAttributionDcl; top.propagateDispatcher = propagateThreadedInh(o.isJust, rev, _, syn); } @@ -226,16 +224,16 @@ top::AttributeDclInfo ::= inh::String syn::String bound::[TyVar] ty::Type o::May top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = if o.isJust - then collectionAttrDefError - else synthesizedAttributeDef(_, _, _); -- Allow normal syn equations + then collectionErrorRegularAttributeDef + else synthesizedAttributeDef; -- Allow normal syn equations top.attrBaseDefDispatcher = if o.isJust - then synBaseColAttributeDef(_, _, _) -- Allow normal syn base equations - else nonCollectionAttrBaseDefError; + then synBaseColAttributeDef -- Allow normal syn base equations + else nonCollectionErrorBaseAttributeDef; top.attrAppendDefDispatcher = if o.isJust - then synAppendColAttributeDef(_, _, _) -- Allow normal syn append equations - else nonCollectionAttrAppendDefError; + then synAppendColAttributeDef -- Allow normal syn append equations + else nonCollectionErrorAppendAttributeDef; top.attributionDispatcher = defaultAttributionDcl; top.propagateDispatcher = propagateThreadedSyn(o.isJust, rev, inh, _); } diff --git a/grammars/silver/compiler/extension/autoattr/Monoid.sv b/grammars/silver/compiler/extension/autoattr/Monoid.sv index 7e46555bb..4028ededb 100644 --- a/grammars/silver/compiler/extension/autoattr/Monoid.sv +++ b/grammars/silver/compiler/extension/autoattr/Monoid.sv @@ -153,3 +153,11 @@ top::ProductionStmt ::= attr::Decorated! QName qNameAttrOccur(new(attr)), ':=', res, ';'); } + +abstract production monoidErrorRegularAttributeDef implements AttributeDef +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr +{ + forwards to errorAttributeDef( + [errFromOrigin(top, dl.unparse ++ "." ++ attr.unparse ++ " is a monoid collection attribute, and you must use ':=' or '<-', not '='.")], + dl, attr, @e); +} diff --git a/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv b/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv index 7abe0675c..d0c58b87d 100644 --- a/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv +++ b/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv @@ -49,10 +49,6 @@ top::ProductionStmt ::= 'implicit' dl::DefLHS '.' attr::QNameAttrOccur '=' ';' } -global partialDefaultAttributeDef::(ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr) = - \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr -> - attributeDef(newUnique(dl), '.', newUnique(attr), '=', e, ';'); - concrete production implicitAttributeDef top::ProductionStmt ::= 'implicit' dl::DefLHS '.' attr::QNameAttrOccur '=' e::Expr ';' { @@ -82,12 +78,12 @@ top::ProductionStmt ::= 'implicit' dl::DefLHS '.' attr::QNameAttrOccur '=' e::Ex attr.attrFor = dl.typerep; forwards to - (if null(merrors) - then if attr.found - then attr.attrDcl.attrDefDispatcher - --if not found, let the normal dispatcher handle it - else partialDefaultAttributeDef - else errorAttributeDef(merrors, _, _, _))(dl, attr, e); + if null(merrors) + then if attr.found + then attr.attrDcl.attrDefDispatcher(dl, attr, @e) + --if not found, let the normal dispatcher handle it + else attributeDef(new(dl), '.', new(attr), '=', @e, ';') + else errorAttributeDef(merrors, dl, attr, @e); } @@ -123,12 +119,12 @@ top::ProductionStmt ::= 'restricted' dl::DefLHS '.' attr::QNameAttrOccur '=' e:: attr.attrFor = dl.typerep; forwards to - (if null(merrors) - then if attr.found - then attr.attrDcl.attrDefDispatcher - --if not found, let the normal dispatcher handle it - else partialDefaultAttributeDef - else errorAttributeDef(merrors, _, _, _))(dl, attr, e); + if null(merrors) + then if attr.found + then attr.attrDcl.attrDefDispatcher(dl, attr, @e) + --if not found, let the normal dispatcher handle it + else attributeDef(new(dl), '.', new(attr), '=', @e, ';') + else errorAttributeDef(merrors, dl, attr, @e); } @@ -160,16 +156,16 @@ top::ProductionStmt ::= 'unrestricted' dl::DefLHS '.' attr::QNameAttrOccur '=' e "Unrestricted equations can only be used for attributes " ++ "not declared to be restricted or implicit; " ++ attr.unparse ++ " is implicit")]; forwards to - (if attr.found - then case attr.attrDcl of - | restrictedSynDcl(_, _, _) -> errorAttributeDef(restrictedErr, _, _, _) - | restrictedInhDcl(_, _, _) -> errorAttributeDef(restrictedErr, _, _, _) - | implicitSynDcl(_, _, _) -> errorAttributeDef(implicitErr, _, _, _) - | implicitInhDcl(_, _, _) -> errorAttributeDef(implicitErr, _, _, _) - | _ -> partialDefaultAttributeDef - end - --if not found, let the normal dispatcher handle it - else partialDefaultAttributeDef)(dl, attr, e); + if attr.found + then case attr.attrDcl of + | restrictedSynDcl(_, _, _) -> errorAttributeDef(restrictedErr, dl, attr, @e) + | restrictedInhDcl(_, _, _) -> errorAttributeDef(restrictedErr, dl, attr, @e) + | implicitSynDcl(_, _, _) -> errorAttributeDef(implicitErr, dl, attr, @e) + | implicitInhDcl(_, _, _) -> errorAttributeDef(implicitErr, dl, attr, @e) + | _ -> attributeDef(new(dl), '.', new(attr), '=', @e, ';') + end + --if not found, let the normal dispatcher handle it + else attributeDef(new(dl), '.', new(attr), '=', @e, ';'); } @@ -189,8 +185,8 @@ fun buildExplicitAttrErrors [Message] ::= l::[Decorated QNameAttrOccur] = --productions for error checking on restricted attributes -abstract production restrictedSynAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +abstract production restrictedSynAttributeDef implements AttributeDef +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { undecorates to attributeDef(dl, '.', attr, '=', e, ';'); top.unparse = dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; @@ -210,14 +206,14 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e: buildExplicitAttrErrors(e.notExplicitAttributes); forwards to - (if null(merrors) - then synthesizedAttributeDef(_, _, _) - else errorAttributeDef(merrors, _, _, _))(dl, attr, e); + if null(merrors) + then synthesizedAttributeDef(dl, attr, @e) + else errorAttributeDef(merrors, dl, attr, @e); } -abstract production restrictedInhAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +abstract production restrictedInhAttributeDef implements AttributeDef +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { undecorates to attributeDef(dl, '.', attr, '=', e, ';'); top.unparse = dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; @@ -237,17 +233,17 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e: buildExplicitAttrErrors(e.notExplicitAttributes); forwards to - (if null(merrors) - then inheritedAttributeDef(_, _, _) - else errorAttributeDef(merrors, _, _, _))(dl, attr, e); + if null(merrors) + then inheritedAttributeDef(dl, attr, @e) + else errorAttributeDef(merrors, dl, attr, @e); } --productions for error checking on implicit attributes -abstract production implicitSynAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +abstract production implicitSynAttributeDef implements AttributeDef +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { undecorates to attributeDef(dl, '.', attr, '=', e, ';'); top.unparse = dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; @@ -267,19 +263,19 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e: top.undecorateExpr := []; forwards to - (if null(e.merrors) - then if fst(monadsMatch(attr.typerep, e.mtyperep, e.mUpSubst)) - then synthesizedAttributeDef(_, _, e.monadRewritten) - else synthesizedAttributeDef(_, _, Silver_Expr { + if null(e.merrors) + then if fst(monadsMatch(attr.typerep, e.mtyperep, e.mUpSubst)) + then synthesizedAttributeDef(dl, attr, e.monadRewritten) + else synthesizedAttributeDef(dl, attr, Silver_Expr { $Expr {monadReturn()} ($Expr {e.monadRewritten}) }) - else errorAttributeDef(e.merrors, _, _, e.monadRewritten))(dl, attr); + else errorAttributeDef(e.merrors, dl, attr, e.monadRewritten); } -abstract production implicitInhAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +abstract production implicitInhAttributeDef implements AttributeDef +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { undecorates to attributeDef(dl, '.', attr, '=', e, ';'); top.unparse = dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; @@ -299,13 +295,13 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e: top.undecorateExpr := []; forwards to - (if null(e.merrors) - then if fst(monadsMatch(attr.typerep, e.mtyperep, e.mUpSubst)) - then inheritedAttributeDef(_, _, e.monadRewritten) - else inheritedAttributeDef(_, _, Silver_Expr { - $Expr {monadReturn()} - ($Expr {e.monadRewritten}) - }) - else errorAttributeDef(e.merrors, _, _, e.monadRewritten))(dl, attr); + if null(e.merrors) + then if fst(monadsMatch(attr.typerep, e.mtyperep, e.mUpSubst)) + then synthesizedAttributeDef(dl, attr, e.monadRewritten) + else synthesizedAttributeDef(dl, attr, Silver_Expr { + $Expr {monadReturn()} + ($Expr {e.monadRewritten}) + }) + else errorAttributeDef(e.merrors, dl, attr, e.monadRewritten); } diff --git a/grammars/silver/compiler/modification/collection/Collection.sv b/grammars/silver/compiler/modification/collection/Collection.sv index 7fdb426ac..38e5dd2f3 100644 --- a/grammars/silver/compiler/modification/collection/Collection.sv +++ b/grammars/silver/compiler/modification/collection/Collection.sv @@ -268,12 +268,36 @@ top::ProductionStmt ::= val::Decorated! QName e::Expr forwards to localValueDef(val, @e); } +-- ERROR ON ATTR DEFS +abstract production nonCollectionErrorBaseAttributeDef implements AttributeDef +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr +{ + forwards to errorAttributeDef( + [errFromOrigin(top, "The ':=' operator can only be used for collections. " ++ dl.unparse ++ "." ++ attr.unparse ++ " is not a collection.")], + dl, attr, @e); +} + +abstract production nonCollectionErrorAppendAttributeDef implements AttributeDef +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr +{ + forwards to errorAttributeDef( + [errFromOrigin(top, "The '<-' operator can only be used for collections. " ++ dl.unparse ++ "." ++ attr.unparse ++ " is not a collection.")], + dl, attr, @e); +} + +abstract production collectionErrorRegularAttributeDef implements AttributeDef +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr +{ + forwards to errorAttributeDef( + [errFromOrigin(top, dl.unparse ++ "." ++ attr.unparse ++ " is a collection attribute, and you must use ':=' or '<-', not '='.")], + dl, attr, @e); +} + -- NON-ERRORS for SYN ATTRS -abstract production synBaseColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +abstract production synBaseColAttributeDef implements AttributeDef +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { - undecorates to attrContainsBase(dl, '.', attr, ':=', e, ';'); top.unparse = "\t" ++ dl.unparse ++ "." ++ attr.unparse ++ " := " ++ e.unparse ++ ";"; propagate config, grammarName, compiledGrammars, frame, env, finalSubst, originRules; @@ -291,10 +315,9 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur then [errFromOrigin(top, "Attribute " ++ attr.name ++ " has type " ++ errCheck1.leftpp ++ " but the expression being assigned to it has type " ++ errCheck1.rightpp)] else []; } -abstract production synAppendColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +abstract production synAppendColAttributeDef implements AttributeDef +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { - undecorates to attrContainsAppend(dl, '.', attr, '<-', e, ';'); top.unparse = "\t" ++ dl.unparse ++ "." ++ attr.unparse ++ " <- " ++ e.unparse ++ ";"; propagate config, grammarName, compiledGrammars, frame, env, finalSubst, originRules; @@ -315,10 +338,9 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur -- NON-ERRORS for INHERITED ATTRS -abstract production inhBaseColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +abstract production inhBaseColAttributeDef implements AttributeDef +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { - undecorates to attrContainsBase(dl, '.', attr, ':=', e, ';'); top.unparse = "\t" ++ dl.unparse ++ "." ++ attr.unparse ++ " := " ++ e.unparse ++ ";"; propagate config, grammarName, compiledGrammars, frame, env, finalSubst, originRules; @@ -336,10 +358,9 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur then [errFromOrigin(top, "Attribute " ++ attr.name ++ " has type " ++ errCheck1.leftpp ++ " but the expression being assigned to it has type " ++ errCheck1.rightpp)] else []; } -abstract production inhAppendColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +abstract production inhAppendColAttributeDef implements AttributeDef +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { - undecorates to attrContainsAppend(dl, '.', attr, '<-', e, ';'); top.unparse = "\t" ++ dl.unparse ++ "." ++ attr.unparse ++ " <- " ++ e.unparse ++ ";"; propagate config, grammarName, compiledGrammars, frame, env, finalSubst, originRules; diff --git a/grammars/silver/compiler/modification/collection/DclInfo.sv b/grammars/silver/compiler/modification/collection/DclInfo.sv index c84dfaab0..b3dd59600 100644 --- a/grammars/silver/compiler/modification/collection/DclInfo.sv +++ b/grammars/silver/compiler/modification/collection/DclInfo.sv @@ -5,8 +5,8 @@ attribute operation, baseDefDispatcher, appendDefDispatcher occurs on ValueDclIn synthesized attribute isCollection::Boolean; -synthesized attribute attrBaseDefDispatcher :: (ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr); -synthesized attribute attrAppendDefDispatcher :: (ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr); +synthesized attribute attrBaseDefDispatcher :: AttributeDef; +synthesized attribute attrAppendDefDispatcher :: AttributeDef; synthesized attribute baseDefDispatcher :: (ProductionStmt ::= Decorated! QName Expr); synthesized attribute appendDefDispatcher :: (ProductionStmt ::= Decorated! QName Expr); @@ -17,8 +17,8 @@ top::AttributeDclInfo ::= top.isCollection = false; top.operation = error("Internal compiler error: must be defined for all collection attribute declarations"); - top.attrBaseDefDispatcher = nonCollectionAttrBaseDefError; - top.attrAppendDefDispatcher = nonCollectionAttrAppendDefError; + top.attrBaseDefDispatcher = nonCollectionErrorBaseAttributeDef; + top.attrAppendDefDispatcher = nonCollectionErrorAppendAttributeDef; } aspect default production @@ -49,7 +49,7 @@ top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type o::Operation top.decoratedAccessHandler = synDecoratedAccessHandler; top.undecoratedAccessHandler = accessBounceDecorate(synDecoratedAccessHandler); top.dataAccessHandler = synDataAccessHandler; - top.attrDefDispatcher = collectionAttrDefError; + top.attrDefDispatcher = collectionErrorRegularAttributeDef; top.attributionDispatcher = defaultAttributionDcl; top.attrBaseDefDispatcher = synBaseColAttributeDef; @@ -74,7 +74,7 @@ top::AttributeDclInfo ::= fn::String bound::[TyVar] ty::Type o::Operation top.decoratedAccessHandler = inhDecoratedAccessHandler; top.undecoratedAccessHandler = inhUndecoratedAccessErrorHandler; top.dataAccessHandler = inhUndecoratedAccessErrorHandler; - top.attrDefDispatcher = collectionAttrDefError; + top.attrDefDispatcher = collectionErrorRegularAttributeDef; top.attributionDispatcher = defaultAttributionDcl; top.attrBaseDefDispatcher = inhBaseColAttributeDef; @@ -104,19 +104,6 @@ top::ValueDclInfo ::= fn::String ty::Type o::Operation forwards to localDcl(fn,ty,false,sourceGrammar=top.sourceGrammar,sourceLocation=top.sourceLocation); } -global nonCollectionAttrBaseDefError::(ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr) = - \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr -> - errorAttributeDef([errFromOrigin(ambientOrigin(), "The ':=' operator can only be used for collections. " ++ attr.name ++ " is not a collection.")], dl, attr, e); - -global nonCollectionAttrAppendDefError::(ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr) = - \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr -> - errorAttributeDef([errFromOrigin(ambientOrigin(), "The '<-' operator can only be used for collections. " ++ attr.name ++ " is not a collection.")], dl, attr, e); - -global collectionAttrDefError::(ProductionStmt ::= Decorated! DefLHS Decorated! QNameAttrOccur Expr) = - \ dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr -> - errorAttributeDef([errFromOrigin(ambientOrigin(), attr.name ++ " is a collection attribute, and you must use ':=' or '<-', not '='.")], dl, attr, e); - - -- Defs fun synColDef Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type o::Operation = attrDef(defaultEnvItem(synCollectionDcl(fn,bound,ty,o,sourceGrammar=sg,sourceLocation=sl))); diff --git a/grammars/silver/compiler/modification/collection/java/Collection.sv b/grammars/silver/compiler/modification/collection/java/Collection.sv index f1370025c..cdab2a75e 100644 --- a/grammars/silver/compiler/modification/collection/java/Collection.sv +++ b/grammars/silver/compiler/modification/collection/java/Collection.sv @@ -207,7 +207,7 @@ top::ProductionStmt ::= val::Decorated! QName e::Expr ---------- SYNTHESIZED ---- aspect production synBaseColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur {- := -} e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur {- := -} e::Expr { top.translation = s""" // ${dl.unparse}.${attr.unparse} := ${e.unparse} @@ -217,7 +217,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur """; } aspect production synAppendColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur {- <- -} e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur {- <- -} e::Expr { top.translation = s""" // ${dl.unparse}.${attr.unparse} <- ${e.unparse} @@ -229,7 +229,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur ---------- INHERITED ---- aspect production inhBaseColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur {- := -} e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur {- := -} e::Expr { top.translation = s""" // ${dl.unparse}.${attr.unparse} := ${e.unparse} @@ -239,7 +239,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur """; } aspect production inhAppendColAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur {- <- -} e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur {- <- -} e::Expr { top.translation = s""" // ${dl.unparse}.${attr.unparse} <- ${e.unparse} diff --git a/grammars/silver/compiler/translation/java/core/ProductionBody.sv b/grammars/silver/compiler/translation/java/core/ProductionBody.sv index ea1622038..e7e5cd7da 100644 --- a/grammars/silver/compiler/translation/java/core/ProductionBody.sv +++ b/grammars/silver/compiler/translation/java/core/ProductionBody.sv @@ -251,13 +251,13 @@ top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur } aspect production errorAttributeDef -top::ProductionStmt ::= msg::[Message] dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= msg::[Message] @dl::DefLHS @attr::QNameAttrOccur e::Expr { top.translation = error("Internal compiler error: translation not defined in the presence of errors"); } aspect production synthesizedAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { top.translation = s"\t\t// ${dl.unparse}.${attr.unparse} = ${e.unparse}\n" ++ @@ -266,7 +266,7 @@ top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur } aspect production inheritedAttributeDef -top::ProductionStmt ::= dl::Decorated! DefLHS attr::Decorated! QNameAttrOccur e::Expr +top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { top.translation = s"\t\t// ${dl.unparse}.${attr.unparse} = ${e.unparse}\n" ++ From 764f3f8d94179172dc378339ad0bd5a6ec02e446 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 12 Mar 2024 11:42:20 -0500 Subject: [PATCH 188/283] Use dispatch for DefLHS --- .../typechecking/core/ProductionBody.sv | 4 +- .../compiler/analysis/warnings/flow/Inh.sv | 8 ++-- .../compiler/definition/core/DclInfo.sv | 4 +- .../definition/core/ProductionBody.sv | 44 +++++++++---------- .../definition/flow/env/ProductionBody.sv | 12 ++--- .../compiler/modification/copper/DclInfo.sv | 9 ++-- .../modification/copper/ProductionStmt.sv | 11 +++-- .../modification/defaultattr/DefaultAttr.sv | 5 +-- .../translation/java/core/ProductionBody.sv | 16 +++---- 9 files changed, 55 insertions(+), 58 deletions(-) diff --git a/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv b/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv index b77746d9b..5bb7f3362 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv @@ -151,14 +151,14 @@ top::ProductionStmt ::= msg::[Message] @dl::DefLHS @attr::QNameAttrOccur e::Expr } aspect production childDefLHS -top::DefLHS ::= q::Decorated! QName +top::DefLHS ::= @q::QName { top.errors <- if isDecorable(top.typerep, top.env) then [] else [errFromOrigin(top, s"Inherited attributes can only be defined on (undecorated) nonterminal and unique decorated types, not ${prettyType(top.typerep)}.")]; } aspect production localDefLHS -top::DefLHS ::= q::Decorated! QName +top::DefLHS ::= @q::QName { top.errors <- if isDecorable(top.typerep, top.env) then [] else [errFromOrigin(top, s"Inherited attributes can only be defined on (undecorated) nonterminal and unique decorated types, not ${prettyType(top.typerep)}.")]; diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index 734b1dc60..e40926d58 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -322,7 +322,7 @@ top::DefLHS ::= top.refDecSiteInhDeps = nothing(); } aspect production childDefLHS -top::DefLHS ::= q::Decorated! QName +top::DefLHS ::= @q::QName { top.lhsUniqueRefs = lookupUniqueRefs(top.frame.fullName, q.lookupValue.fullName, top.flowEnv); top.refDecSiteInhDeps = @@ -336,7 +336,7 @@ top::DefLHS ::= q::Decorated! QName end; } aspect production localDefLHS -top::DefLHS ::= q::Decorated! QName +top::DefLHS ::= @q::QName { top.lhsUniqueRefs = lookupLocalUniqueRefs(q.lookupValue.fullName, top.flowEnv); top.refDecSiteInhDeps = @@ -350,7 +350,7 @@ top::DefLHS ::= q::Decorated! QName end; } aspect production childTransAttrDefLHS -top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur +top::DefLHS ::= @q::QName @attr::QNameAttrOccur { local childUniqueRefs::[UniqueRefSite] = lookupUniqueRefs(top.frame.fullName, q.lookupValue.fullName, top.flowEnv); @@ -373,7 +373,7 @@ top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur end; } aspect production localTransAttrDefLHS -top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur +top::DefLHS ::= @q::QName @attr::QNameAttrOccur { local localUniqueRefs::[UniqueRefSite] = lookupUniqueRefs(top.frame.fullName, q.lookupValue.fullName, top.flowEnv); diff --git a/grammars/silver/compiler/definition/core/DclInfo.sv b/grammars/silver/compiler/definition/core/DclInfo.sv index 070e8c382..3a9af408a 100644 --- a/grammars/silver/compiler/definition/core/DclInfo.sv +++ b/grammars/silver/compiler/definition/core/DclInfo.sv @@ -13,11 +13,11 @@ synthesized attribute defDispatcher :: (ProductionStmt ::= Decorated! QName Exp {-- - The production an "equation" left hand side should forward to for this type of value (i.e. the 'x' in 'x.a = e') -} -synthesized attribute defLHSDispatcher :: (DefLHS ::= Decorated! QName) occurs on ValueDclInfo; +synthesized attribute defLHSDispatcher :: BaseDefLHS occurs on ValueDclInfo; {-- - The production a translation attribute left hand side should forward to, for this type of value (i.e. the 'x.a' in 'x.a.b = e') -} -synthesized attribute transDefLHSDispatcher :: (DefLHS ::= Decorated! QName Decorated! QNameAttrOccur) occurs on ValueDclInfo; +synthesized attribute transDefLHSDispatcher :: TransAttrDefLHS occurs on ValueDclInfo; {-- - The handler for 'x.a' for 'a', given that 'x' is DECORATED. diff --git a/grammars/silver/compiler/definition/core/ProductionBody.sv b/grammars/silver/compiler/definition/core/ProductionBody.sv index 383e9ac98..cd768b86a 100644 --- a/grammars/silver/compiler/definition/core/ProductionBody.sv +++ b/grammars/silver/compiler/definition/core/ProductionBody.sv @@ -398,10 +398,11 @@ top::DefLHS ::= q::QName } } -abstract production errorDefLHS -top::DefLHS ::= q::Decorated! QName +dispatch BaseDefLHS = DefLHS ::= @q::QName; + +abstract production errorDefLHS implements BaseDefLHS +top::DefLHS ::= @q::QName { - undecorates to concreteDefLHS(q); top.name = q.name; top.unparse = q.unparse; top.found = false; @@ -418,10 +419,9 @@ top::DefLHS ::= 'forward' forwards to concreteDefLHS(qName("forward")); } -abstract production childDefLHS -top::DefLHS ::= q::Decorated! QName +abstract production childDefLHS implements BaseDefLHS +top::DefLHS ::= @q::QName { - undecorates to concreteDefLHS(q); top.name = q.name; top.unparse = q.unparse; top.found = !existingProblems && top.defLHSattr.attrDcl.isInherited; @@ -435,10 +435,9 @@ top::DefLHS ::= q::Decorated! QName top.typerep = q.lookupValue.typeScheme.monoType; } -abstract production lhsDefLHS -top::DefLHS ::= q::Decorated! QName +abstract production lhsDefLHS implements BaseDefLHS +top::DefLHS ::= @q::QName { - undecorates to concreteDefLHS(q); top.name = q.name; top.unparse = q.unparse; top.found = !existingProblems && top.defLHSattr.attrDcl.isSynthesized; @@ -452,10 +451,9 @@ top::DefLHS ::= q::Decorated! QName top.typerep = q.lookupValue.typeScheme.monoType; } -abstract production localDefLHS -top::DefLHS ::= q::Decorated! QName +abstract production localDefLHS implements BaseDefLHS +top::DefLHS ::= @q::QName { - undecorates to concreteDefLHS(q); top.name = q.name; top.unparse = q.unparse; top.found = !existingProblems && top.defLHSattr.attrDcl.isInherited; @@ -469,10 +467,9 @@ top::DefLHS ::= q::Decorated! QName top.typerep = q.lookupValue.typeScheme.monoType; } -abstract production forwardDefLHS -top::DefLHS ::= q::Decorated! QName +abstract production forwardDefLHS implements BaseDefLHS +top::DefLHS ::= @q::QName { - undecorates to concreteDefLHS(q); top.name = q.name; top.unparse = q.unparse; top.found = !existingProblems && top.defLHSattr.attrDcl.isInherited; @@ -502,10 +499,11 @@ top::DefLHS ::= q::QName attr::QNameAttrOccur else q.lookupValue.dcl.transDefLHSDispatcher(q, attr); } -abstract production errorTransAttrDefLHS -top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur +dispatch TransAttrDefLHS = DefLHS ::= @q::QName @attr::QNameAttrOccur; + +abstract production errorTransAttrDefLHS implements TransAttrDefLHS +top::DefLHS ::= @q::QName @attr::QNameAttrOccur { - undecorates to transAttrDefLHS(q, attr); top.name = q.name; top.unparse = s"${q.unparse}.${attr.unparse}"; top.found = false; @@ -516,10 +514,9 @@ top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur top.typerep = attr.typerep; } -abstract production childTransAttrDefLHS -top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur +abstract production childTransAttrDefLHS implements TransAttrDefLHS +top::DefLHS ::= @q::QName @attr::QNameAttrOccur { - undecorates to transAttrDefLHS(q, attr); top.name = q.name; top.unparse = s"${q.unparse}.${attr.unparse}"; top.found = !existingProblems && attr.attrDcl.isSynthesized && top.defLHSattr.attrDcl.isInherited; @@ -541,10 +538,9 @@ top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur top.typerep = attr.typerep; } -abstract production localTransAttrDefLHS -top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur +abstract production localTransAttrDefLHS implements TransAttrDefLHS +top::DefLHS ::= @q::QName @attr::QNameAttrOccur { - undecorates to transAttrDefLHS(q, attr); top.name = q.name; top.unparse = s"${q.unparse}.${attr.unparse}"; top.found = !existingProblems && attr.attrDcl.isSynthesized && top.defLHSattr.attrDcl.isInherited; diff --git a/grammars/silver/compiler/definition/flow/env/ProductionBody.sv b/grammars/silver/compiler/definition/flow/env/ProductionBody.sv index 3c3e828bb..bc97813f1 100644 --- a/grammars/silver/compiler/definition/flow/env/ProductionBody.sv +++ b/grammars/silver/compiler/definition/flow/env/ProductionBody.sv @@ -141,42 +141,42 @@ top::DefLHS ::= top.inhAttrName = ""; } aspect production childDefLHS -top::DefLHS ::= q::Decorated! QName +top::DefLHS ::= @q::QName { top.defLHSVertex = rhsVertexType(q.lookupValue.fullName); top.defLHSInhEq = [inhEq(top.frame.fullName, q.lookupValue.fullName, top.defLHSattr.attrDcl.fullName, _)]; top.inhAttrName = top.defLHSattr.attrDcl.fullName; } aspect production lhsDefLHS -top::DefLHS ::= q::Decorated! QName +top::DefLHS ::= @q::QName { top.defLHSVertex = lhsVertexType; top.defLHSInhEq = []; top.inhAttrName = ""; } aspect production localDefLHS -top::DefLHS ::= q::Decorated! QName +top::DefLHS ::= @q::QName { top.defLHSVertex = localVertexType(q.lookupValue.fullName); top.defLHSInhEq = [localInhEq(top.frame.fullName, q.lookupValue.fullName, top.defLHSattr.attrDcl.fullName, _)]; top.inhAttrName = top.defLHSattr.attrDcl.fullName; } aspect production forwardDefLHS -top::DefLHS ::= q::Decorated! QName +top::DefLHS ::= @q::QName { top.defLHSVertex = forwardVertexType; top.defLHSInhEq = [fwdInhEq(top.frame.fullName, top.defLHSattr.attrDcl.fullName, _)]; top.inhAttrName = top.defLHSattr.attrDcl.fullName; } aspect production childTransAttrDefLHS -top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur +top::DefLHS ::= @q::QName @attr::QNameAttrOccur { top.defLHSVertex = transAttrVertexType(rhsVertexType(q.lookupValue.fullName), attr.attrDcl.fullName); top.defLHSInhEq = [transInhEq(top.frame.fullName, q.lookupValue.fullName, attr.attrDcl.fullName, top.defLHSattr.attrDcl.fullName, _)]; top.inhAttrName = s"${attr.attrDcl.fullName}.${top.defLHSattr.attrDcl.fullName}"; } aspect production localTransAttrDefLHS -top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur +top::DefLHS ::= @q::QName @attr::QNameAttrOccur { top.defLHSVertex = transAttrVertexType(localVertexType(q.lookupValue.fullName), attr.attrDcl.fullName); top.defLHSInhEq = [localTransInhEq(top.frame.fullName, q.lookupValue.fullName, attr.attrDcl.fullName, top.defLHSattr.attrDcl.fullName, _)]; diff --git a/grammars/silver/compiler/modification/copper/DclInfo.sv b/grammars/silver/compiler/modification/copper/DclInfo.sv index 2a36574ab..33a90b610 100644 --- a/grammars/silver/compiler/modification/copper/DclInfo.sv +++ b/grammars/silver/compiler/modification/copper/DclInfo.sv @@ -22,8 +22,7 @@ top::ValueDclInfo ::= fn::String ty::Type top.refDispatcher = parserAttributeReference; top.defDispatcher = parserAttributeValueDef; top.defLHSDispatcher = parserAttributeDefLHS; - top.transDefLHSDispatcher = \ q::Decorated! QName _ -> - parserAttributeDefLHS(q); + top.transDefLHSDispatcher = parserAttributeTransAttrDefLHS; } {-- @@ -96,8 +95,7 @@ top::ValueDclInfo ::= fn::String ty::Type top.refDispatcher = actionChildReference; top.defDispatcher = errorValueDef; top.defLHSDispatcher = parserAttributeDefLHS; -- TODO: specialize this - top.transDefLHSDispatcher = \ q::Decorated! QName _ -> - parserAttributeDefLHS(q); + top.transDefLHSDispatcher = parserAttributeTransAttrDefLHS; } {-- @@ -115,6 +113,5 @@ top::ValueDclInfo ::= fn::String ty::Type top.refDispatcher = parserAttributeReference; top.defDispatcher = parserAttributeValueDef; top.defLHSDispatcher = parserAttributeDefLHS; - top.transDefLHSDispatcher = \ q::Decorated! QName _ -> - parserAttributeDefLHS(q); + top.transDefLHSDispatcher = parserAttributeTransAttrDefLHS; } diff --git a/grammars/silver/compiler/modification/copper/ProductionStmt.sv b/grammars/silver/compiler/modification/copper/ProductionStmt.sv index ac2afdd76..b3a6a3ef7 100644 --- a/grammars/silver/compiler/modification/copper/ProductionStmt.sv +++ b/grammars/silver/compiler/modification/copper/ProductionStmt.sv @@ -234,10 +234,9 @@ top::ProductionStmt ::= 'if' '(' condition::Expr ')' th::ProductionStmt } -abstract production parserAttributeDefLHS -top::DefLHS ::= q::Decorated! QName +abstract production parserAttributeDefLHS implements BaseDefLHS +top::DefLHS ::= @q::QName { - undecorates to concreteDefLHS(q); top.name = q.name; top.unparse = q.unparse; top.found = false; @@ -254,6 +253,12 @@ top::DefLHS ::= q::Decorated! QName top.typerep = q.lookupValue.typeScheme.monoType; } +abstract production parserAttributeTransAttrDefLHS implements TransAttrDefLHS +top::DefLHS ::= @q::QName @attr::QNameAttrOccur +{ + forwards to parserAttributeDefLHS(q); +} + abstract production termAttrValueValueDef top::ProductionStmt ::= val::Decorated! QName e::Expr { diff --git a/grammars/silver/compiler/modification/defaultattr/DefaultAttr.sv b/grammars/silver/compiler/modification/defaultattr/DefaultAttr.sv index 03c5ad9f0..833496bb8 100644 --- a/grammars/silver/compiler/modification/defaultattr/DefaultAttr.sv +++ b/grammars/silver/compiler/modification/defaultattr/DefaultAttr.sv @@ -99,10 +99,9 @@ top::ValueDclInfo ::= fn::String ty::Type top.transDefLHSDispatcher = errorTransAttrDefLHS; } -abstract production defaultLhsDefLHS -top::DefLHS ::= q::Decorated! QName +abstract production defaultLhsDefLHS implements BaseDefLHS +top::DefLHS ::= @q::QName { - undecorates to concreteDefLHS(q); top.name = q.name; top.unparse = q.unparse; top.found = !existingProblems && top.defLHSattr.attrDcl.isSynthesized; diff --git a/grammars/silver/compiler/translation/java/core/ProductionBody.sv b/grammars/silver/compiler/translation/java/core/ProductionBody.sv index e7e5cd7da..6e81b80b2 100644 --- a/grammars/silver/compiler/translation/java/core/ProductionBody.sv +++ b/grammars/silver/compiler/translation/java/core/ProductionBody.sv @@ -193,37 +193,37 @@ top::DefLHS ::= } aspect production childDefLHS -top::DefLHS ::= q::Decorated! QName +top::DefLHS ::= @q::QName { top.translation = s"${top.frame.className}.childInheritedAttributes[${top.frame.className}.i_${q.lookupValue.fullName}]"; } aspect production lhsDefLHS -top::DefLHS ::= q::Decorated! QName +top::DefLHS ::= @q::QName { top.translation = s"${top.frame.className}.synthesizedAttributes"; } aspect production localDefLHS -top::DefLHS ::= q::Decorated! QName +top::DefLHS ::= @q::QName { top.translation = s"${top.frame.className}.localInheritedAttributes[${q.lookupValue.dcl.attrOccursIndex}]"; } aspect production forwardDefLHS -top::DefLHS ::= q::Decorated! QName +top::DefLHS ::= @q::QName { top.translation = s"${top.frame.className}.forwardInheritedAttributes"; } aspect production errorDefLHS -top::DefLHS ::= q::Decorated! QName +top::DefLHS ::= @q::QName { top.translation = error("Internal compiler error: translation not defined in the presence of errors"); } aspect production childTransAttrDefLHS -top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur +top::DefLHS ::= @q::QName @attr::QNameAttrOccur { local inhsIndex::String = s"${top.frame.className}.childInheritedAttributes[${top.frame.className}.i_${q.lookupValue.fullName}][${attr.attrOccursIndex}_inhs]"; top.translation = s"((common.TransInhs)${inhsIndex}).inhs"; @@ -234,7 +234,7 @@ top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur } aspect production localTransAttrDefLHS -top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur +top::DefLHS ::= @q::QName @attr::QNameAttrOccur { local inhsIndex::String = s"${top.frame.className}.localInheritedAttributes[${q.lookupValue.dcl.attrOccursIndex}][${attr.attrOccursIndex}_inhs]"; top.translation = s"((common.TransInhs)${inhsIndex}).inhs"; @@ -245,7 +245,7 @@ top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur } aspect production errorTransAttrDefLHS -top::DefLHS ::= q::Decorated! QName attr::Decorated! QNameAttrOccur +top::DefLHS ::= @q::QName @attr::QNameAttrOccur { top.translation = error("Internal compiler error: translation not defined in the presence of errors"); } From b9a4038781e068b3563c570b9ac1456ff4bafbb9 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 12 Mar 2024 14:49:38 -0500 Subject: [PATCH 189/283] Don't try to project eqs from dispatch application --- grammars/silver/compiler/definition/flow/env/Expr.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index f29c125f2..06c029b70 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -227,7 +227,7 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp end; e.decSiteVertexInfo = nothing(); es.decSiteVertexInfo = top.decSiteVertexInfo; - es.alwaysDecorated = top.alwaysDecorated; + es.alwaysDecorated = false; } aspect production annoExpr From 76f624a8be83b66be98737585d603ba59633f5d2 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 12 Mar 2024 15:01:14 -0500 Subject: [PATCH 190/283] Project inherited equations when a dispatch prod is applied directly --- .../silver/compiler/definition/flow/env/Expr.sv | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index 06c029b70..b9ea3908e 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -41,7 +41,8 @@ inherited attribute decSiteVertexInfo :: Maybe; {-- - Is this expression unconditionally decorated. - - Can be false when decSiteVertexInfo is just(...)! For example: + - This determines whether we can rely on projected inherited equations being present. + - Can be false when decSiteVertexInfo is just(...) - for example: - - local foo::Expr = if cond then @e else bar; - foo.env = top.env; @@ -221,13 +222,18 @@ top::Expr ::= e::Decorated! Expr es::Decorated! AppExprs anns::Decorated! AnnoAp { top.flowVertexInfo = top.decSiteVertexInfo; es.appProd = - case e.typerep of - | dispatchType(ns) -> just(ns) - | _ -> nothing() + case e, e.typerep of + | productionReference(q), _ -> just(q.lookupValue.dcl.namedSignature) + | _, dispatchType(ns) -> just(ns) + | _, _ -> error("dispatchApplication: unexpected type") end; e.decSiteVertexInfo = nothing(); es.decSiteVertexInfo = top.decSiteVertexInfo; - es.alwaysDecorated = false; + es.alwaysDecorated = + case e of + | productionReference(q) -> top.alwaysDecorated + | _ -> false + end; } aspect production annoExpr From 0c2d49d90107c151148ad45df6cd1bada1bb9a1d Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 12 Mar 2024 15:22:34 -0500 Subject: [PATCH 191/283] Use dispatch for value defs --- .../typechecking/core/ProductionBody.sv | 2 +- .../analysis/uniqueness/ProductionBody.sv | 6 +++--- .../compiler/analysis/warnings/flow/Inh.sv | 4 ++-- .../compiler/definition/core/DclInfo.sv | 2 +- .../definition/core/ProductionBody.sv | 12 +++++------ .../definition/flow/env/ProductionBody.sv | 12 +++++------ .../modification/collection/Collection.sv | 20 ++++++++----------- .../modification/collection/DclInfo.sv | 4 ++-- .../collection/java/Collection.sv | 4 ++-- .../modification/copper/ProductionStmt.sv | 10 ++++------ .../translation/java/core/ProductionBody.sv | 4 ++-- 11 files changed, 37 insertions(+), 43 deletions(-) diff --git a/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv b/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv index 5bb7f3362..0ac2aedea 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv @@ -177,7 +177,7 @@ top::ProductionStmt ::= 'production' 'attribute' a::Name '::' te::TypeExpr ';' } aspect production localValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +top::ProductionStmt ::= @val::QName e::Expr { local attribute errCheck1 :: TypeCheck; errCheck1.finalSubst = top.finalSubst; diff --git a/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv b/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv index a061fbd5a..322c07efa 100644 --- a/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv +++ b/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv @@ -72,7 +72,7 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr top.errors <- uniqueContextErrors(e.uniqueRefs); } aspect production appendCollectionValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +top::ProductionStmt ::= @val::QName e::Expr { top.errors <- uniqueContextErrors(e.uniqueRefs); } @@ -87,7 +87,7 @@ top::ProductionStmt ::= 'print' e::Expr ';' top.errors <- uniqueContextErrors(e.uniqueRefs); } aspect production parserAttributeValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +top::ProductionStmt ::= @val::QName e::Expr { top.errors <- uniqueContextErrors(e.uniqueRefs); } @@ -107,7 +107,7 @@ top::ProductionStmt ::= 'if' '(' condition::Expr ')' th::ProductionStmt 'else' e top.errors <- uniqueContextErrors(condition.uniqueRefs); } aspect production termAttrValueValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +top::ProductionStmt ::= @val::QName e::Expr { top.errors <- uniqueContextErrors(e.uniqueRefs); } diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index e40926d58..e96d3e8e6 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -557,7 +557,7 @@ top::ProductionStmt ::= 'undecorates' 'to' e::Expr ';' } aspect production localValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +top::ProductionStmt ::= @val::QName e::Expr { local transitiveDeps :: [FlowVertex] = expandGraph(e.flowDeps, top.frame.flowGraph); @@ -597,7 +597,7 @@ top::ProductionStmt ::= 'attachNote' e::Expr ';' -- Partially skipping `appendCollectionValueDef`: it likewise forwards -- But we do have a special "exceeds check" to do here: aspect production appendCollectionValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +top::ProductionStmt ::= @val::QName e::Expr { local productionFlowGraph :: ProductionGraph = top.frame.flowGraph; local transitiveDeps :: [FlowVertex] = expandGraph(e.flowDeps, productionFlowGraph); diff --git a/grammars/silver/compiler/definition/core/DclInfo.sv b/grammars/silver/compiler/definition/core/DclInfo.sv index 3a9af408a..e30fdc240 100644 --- a/grammars/silver/compiler/definition/core/DclInfo.sv +++ b/grammars/silver/compiler/definition/core/DclInfo.sv @@ -9,7 +9,7 @@ synthesized attribute refDispatcher :: Reference occurs on ValueDclInfo; {-- - The production an "assignment" should forward to for this type of value -} -synthesized attribute defDispatcher :: (ProductionStmt ::= Decorated! QName Expr) occurs on ValueDclInfo; +synthesized attribute defDispatcher :: ValueDef occurs on ValueDclInfo; {-- - The production an "equation" left hand side should forward to for this type of value (i.e. the 'x' in 'x.a = e') -} diff --git a/grammars/silver/compiler/definition/core/ProductionBody.sv b/grammars/silver/compiler/definition/core/ProductionBody.sv index cd768b86a..c1073fe54 100644 --- a/grammars/silver/compiler/definition/core/ProductionBody.sv +++ b/grammars/silver/compiler/definition/core/ProductionBody.sv @@ -581,10 +581,11 @@ top::ProductionStmt ::= val::QName '=' e::Expr ';' else val.lookupValue.dcl.defDispatcher(val, e); } -abstract production errorValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +dispatch ValueDef = ProductionStmt ::= @val::QName e::Expr; + +abstract production errorValueDef implements ValueDef +top::ProductionStmt ::= @val::QName e::Expr { - undecorates to valueEq(val, '=', e, ';'); top.unparse = "\t" ++ val.unparse ++ " = " ++ e.unparse ++ ";"; e.isRoot = true; @@ -594,10 +595,9 @@ top::ProductionStmt ::= val::Decorated! QName e::Expr else [errFromOrigin(val, val.name ++ " cannot be assigned to.")]; } -abstract production localValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +abstract production localValueDef implements ValueDef +top::ProductionStmt ::= @val::QName e::Expr { - undecorates to valueEq(val, '=', e, ';'); top.unparse = "\t" ++ val.unparse ++ " = " ++ e.unparse ++ ";"; -- val is already valid here diff --git a/grammars/silver/compiler/definition/flow/env/ProductionBody.sv b/grammars/silver/compiler/definition/flow/env/ProductionBody.sv index bc97813f1..8f71f59a2 100644 --- a/grammars/silver/compiler/definition/flow/env/ProductionBody.sv +++ b/grammars/silver/compiler/definition/flow/env/ProductionBody.sv @@ -184,14 +184,14 @@ top::DefLHS ::= @q::QName @attr::QNameAttrOccur } aspect production errorValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +top::ProductionStmt ::= @val::QName e::Expr { e.decSiteVertexInfo = nothing(); e.alwaysDecorated = false; } aspect production localValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +top::ProductionStmt ::= @val::QName e::Expr { -- TODO: So, I'm just going to assume for the moment that we're always allowed to define the eq for a local... -- technically, it's possible to break this if you declare it in one grammar, but define it in another, but @@ -261,7 +261,7 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr } aspect production baseCollectionValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +top::ProductionStmt ::= @val::QName e::Expr { -- We actually don't want reference site flow projections in e, -- since we don't actually know the entire tree in which it is decorated. @@ -269,7 +269,7 @@ top::ProductionStmt ::= val::Decorated! QName e::Expr e.alwaysDecorated = false; } aspect production appendCollectionValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +top::ProductionStmt ::= @val::QName e::Expr { local locDefGram :: String = hackGramFromQName(val.lookupValue); @@ -306,7 +306,7 @@ top::ProductionStmt ::= 'print' e::Expr ';' e.alwaysDecorated = false; } aspect production parserAttributeValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +top::ProductionStmt ::= @val::QName e::Expr { e.decSiteVertexInfo = nothing(); e.alwaysDecorated = false; @@ -330,7 +330,7 @@ top::ProductionStmt ::= 'if' '(' condition::Expr ')' th::ProductionStmt 'else' e condition.alwaysDecorated = false; } aspect production termAttrValueValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +top::ProductionStmt ::= @val::QName e::Expr { e.decSiteVertexInfo = nothing(); e.alwaysDecorated = false; diff --git a/grammars/silver/compiler/modification/collection/Collection.sv b/grammars/silver/compiler/modification/collection/Collection.sv index 38e5dd2f3..e9d2ace86 100644 --- a/grammars/silver/compiler/modification/collection/Collection.sv +++ b/grammars/silver/compiler/modification/collection/Collection.sv @@ -224,10 +224,9 @@ top::ProductionStmt ::= 'production' 'attribute' a::Name '::' te::TypeExpr 'with --- The use semantics ---------------------------------------------------------- -- ERROR ON VALUE DEFS: -abstract production errorCollectionValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +abstract production errorCollectionValueDef implements ValueDef +top::ProductionStmt ::= @val::QName e::Expr { - undecorates to valContainsBase(val, ':=', e, ';'); -- Override to just e.errors since we don't want the standard error message about val cannot be assigned to. top.errors := e.errors; @@ -235,10 +234,9 @@ top::ProductionStmt ::= val::Decorated! QName e::Expr forwards to errorValueDef(val, @e); } -abstract production errorColNormalValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +abstract production errorColNormalValueDef implements ValueDef +top::ProductionStmt ::= @val::QName e::Expr { - undecorates to valueEq(val, '=', e, ';'); -- Override to just e.errors since we don't want the standard error message about val cannot be assigned to. top.errors := e.errors; @@ -249,19 +247,17 @@ top::ProductionStmt ::= val::Decorated! QName e::Expr -- NON-ERRORS for PRODUCTIONS -abstract production baseCollectionValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +abstract production baseCollectionValueDef implements ValueDef +top::ProductionStmt ::= @val::QName e::Expr { - undecorates to valContainsBase(val, ':=', e, ';'); top.unparse = "\t" ++ val.unparse ++ " := " ++ e.unparse ++ ";"; -- TODO: We override the translation, so this probably shouldn't be a forwarding production... forwards to localValueDef(val, @e); } -abstract production appendCollectionValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +abstract production appendCollectionValueDef implements ValueDef +top::ProductionStmt ::= @val::QName e::Expr { - undecorates to valContainsAppend(val, '<-', e, ';'); top.unparse = "\t" ++ val.unparse ++ " <- " ++ e.unparse ++ ";"; -- TODO: We override the translation, so this probably shouldn't be a forwarding production... diff --git a/grammars/silver/compiler/modification/collection/DclInfo.sv b/grammars/silver/compiler/modification/collection/DclInfo.sv index b3dd59600..0b69c1333 100644 --- a/grammars/silver/compiler/modification/collection/DclInfo.sv +++ b/grammars/silver/compiler/modification/collection/DclInfo.sv @@ -8,8 +8,8 @@ synthesized attribute isCollection::Boolean; synthesized attribute attrBaseDefDispatcher :: AttributeDef; synthesized attribute attrAppendDefDispatcher :: AttributeDef; -synthesized attribute baseDefDispatcher :: (ProductionStmt ::= Decorated! QName Expr); -synthesized attribute appendDefDispatcher :: (ProductionStmt ::= Decorated! QName Expr); +synthesized attribute baseDefDispatcher :: ValueDef; +synthesized attribute appendDefDispatcher :: ValueDef; aspect default production top::AttributeDclInfo ::= diff --git a/grammars/silver/compiler/modification/collection/java/Collection.sv b/grammars/silver/compiler/modification/collection/java/Collection.sv index cdab2a75e..0cff1923d 100644 --- a/grammars/silver/compiler/modification/collection/java/Collection.sv +++ b/grammars/silver/compiler/modification/collection/java/Collection.sv @@ -187,7 +187,7 @@ public class ${className} extends common.CollectionAttribute { ---------- LOCALS --- aspect production baseCollectionValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +top::ProductionStmt ::= @val::QName e::Expr { -- for locals, the CA object was created already top.translation = s""" @@ -196,7 +196,7 @@ top::ProductionStmt ::= val::Decorated! QName e::Expr """; } aspect production appendCollectionValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +top::ProductionStmt ::= @val::QName e::Expr { -- for locals, the CA object was created already top.translation = s""" diff --git a/grammars/silver/compiler/modification/copper/ProductionStmt.sv b/grammars/silver/compiler/modification/copper/ProductionStmt.sv index b3a6a3ef7..44a42548c 100644 --- a/grammars/silver/compiler/modification/copper/ProductionStmt.sv +++ b/grammars/silver/compiler/modification/copper/ProductionStmt.sv @@ -86,10 +86,9 @@ top::ProductionStmt ::= 'local' 'attribute' a::Name '::' te::TypeExpr ';' -- TODO see ugly hack in ActionCode.sv } -abstract production parserAttributeValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +abstract production parserAttributeValueDef implements ValueDef +top::ProductionStmt ::= @val::QName e::Expr { - undecorates to valueEq(val, '=', e, ';'); top.unparse = "\t" ++ val.unparse ++ " = " ++ e.unparse ++ ";"; propagate config, grammarName, compiledGrammars, env, frame, errors, finalSubst; @@ -259,10 +258,9 @@ top::DefLHS ::= @q::QName @attr::QNameAttrOccur forwards to parserAttributeDefLHS(q); } -abstract production termAttrValueValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +abstract production termAttrValueValueDef implements ValueDef +top::ProductionStmt ::= @val::QName e::Expr { - undecorates to valueEq(val, '=', e, ';'); top.unparse = "\t" ++ val.unparse ++ " = " ++ e.unparse ++ ";"; propagate config, grammarName, compiledGrammars, env, frame, errors, finalSubst; diff --git a/grammars/silver/compiler/translation/java/core/ProductionBody.sv b/grammars/silver/compiler/translation/java/core/ProductionBody.sv index 6e81b80b2..5db4ce478 100644 --- a/grammars/silver/compiler/translation/java/core/ProductionBody.sv +++ b/grammars/silver/compiler/translation/java/core/ProductionBody.sv @@ -276,13 +276,13 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr aspect production errorValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +top::ProductionStmt ::= @val::QName e::Expr { top.translation = error("Internal compiler error: translation not defined in the presence of errors"); } aspect production localValueDef -top::ProductionStmt ::= val::Decorated! QName e::Expr +top::ProductionStmt ::= @val::QName e::Expr { top.translation = s"\t\t// ${val.unparse} = ${e.unparse}\n" ++ From 1951e835aee6e95d3fc1e258ecdf51e6d897fd01 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 12 Mar 2024 16:10:13 -0500 Subject: [PATCH 192/283] Use dispatch for occurs on --- .../analysis/typechecking/core/OccursDcl.sv | 2 +- .../silver/compiler/definition/core/DclInfo.sv | 2 +- .../silver/compiler/definition/core/OccursDcl.sv | 15 +++++++++------ .../compiler/extension/autoattr/BiEquality.sv | 3 +-- .../compiler/extension/autoattr/Destruct.sv | 5 ++--- .../silver/compiler/extension/autoattr/Functor.sv | 5 ++--- .../silver/compiler/extension/doc/core/AGDcl.sv | 4 ++-- .../compiler/extension/strategyattr/Strategy.sv | 5 ++--- .../compiler/translation/java/core/OccursDcl.sv | 4 ++-- 9 files changed, 22 insertions(+), 23 deletions(-) diff --git a/grammars/silver/compiler/analysis/typechecking/core/OccursDcl.sv b/grammars/silver/compiler/analysis/typechecking/core/OccursDcl.sv index 4301077eb..d6fcfb2a9 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/OccursDcl.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/OccursDcl.sv @@ -1,7 +1,7 @@ grammar silver:compiler:analysis:typechecking:core; aspect production defaultAttributionDcl -top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs +top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs { local checkNT::TypeCheck = checkNonterminal(top.env, false, protoatty); checkNT.downSubst = emptySubst(); diff --git a/grammars/silver/compiler/definition/core/DclInfo.sv b/grammars/silver/compiler/definition/core/DclInfo.sv index e30fdc240..fc164c09e 100644 --- a/grammars/silver/compiler/definition/core/DclInfo.sv +++ b/grammars/silver/compiler/definition/core/DclInfo.sv @@ -41,7 +41,7 @@ synthesized attribute attrDefDispatcher :: AttributeDef occurs on AttributeDclIn {-- - The production an "occurs on" decl should forward to for this type of attribute (for extension use, defaultAttributionDcl for all syn/inh attrs.) -} -synthesized attribute attributionDispatcher :: (AGDcl ::= Decorated! QName BracketedOptTypeExprs QName BracketedOptTypeExprs) occurs on AttributeDclInfo; +synthesized attribute attributionDispatcher :: AttributionDcl occurs on AttributeDclInfo; -- -- non-interface values aspect production childDcl diff --git a/grammars/silver/compiler/definition/core/OccursDcl.sv b/grammars/silver/compiler/definition/core/OccursDcl.sv index a66c176f9..46f6b5e5a 100644 --- a/grammars/silver/compiler/definition/core/OccursDcl.sv +++ b/grammars/silver/compiler/definition/core/OccursDcl.sv @@ -1,9 +1,10 @@ grammar silver:compiler:definition:core; -abstract production defaultAttributionDcl -top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs -{ - undecorates to attributionDcl('attribute', at, attl, 'occurs', 'on', nt, nttl, ';'); +dispatch AttributionDcl = AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs; + +abstract production defaultAttributionDcl implements AttributionDcl +top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs +{ top.unparse = "attribute " ++ at.unparse ++ attl.unparse ++ " occurs on " ++ nt.unparse ++ nttl.unparse ++ ";"; -- TODO: this location is highly unreliable. @@ -137,7 +138,7 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: } abstract production errorAttributionDcl -top::AGDcl ::= msg::[Message] at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs +top::AGDcl ::= msg::[Message] @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs { undecorates to errorAGDcl(msg); top.unparse = "attribute " ++ at.unparse ++ attl.unparse ++ " occurs on " ++ nt.unparse ++ nttl.unparse ++ ";"; @@ -175,6 +176,8 @@ concrete production attributionDcl top::AGDcl ::= 'attribute' at::QName attl::BracketedOptTypeExprs 'occurs' 'on' nt::QName nttl::BracketedOptTypeExprs ';' { top.unparse = "attribute " ++ at.unparse ++ attl.unparse ++ " occurs on " ++ nt.unparse ++ nttl.unparse ++ ";"; + -- Note: we are supplying env to attl, nt, nttl here (and then re-decorating them after dispatching.) + -- This is needed to permit computing flow defs on this production. propagate env; -- Workaround for circular dependency due to dispatching on env: @@ -196,6 +199,6 @@ top::AGDcl ::= 'attribute' at::QName attl::BracketedOptTypeExprs 'occurs' 'on' n concrete production annotateDcl top::AGDcl ::= 'annotation' at::QName attl::BracketedOptTypeExprs 'occurs' 'on' nt::QName nttl::BracketedOptTypeExprs ';' { - forwards to attributionDcl('attribute', at, attl, $4, $5, nt, nttl, $8); + forwards to attributionDcl('attribute', @at, @attl, $4, $5, @nt, @nttl, $8); } diff --git a/grammars/silver/compiler/extension/autoattr/BiEquality.sv b/grammars/silver/compiler/extension/autoattr/BiEquality.sv index 47d1a82b4..47c249f42 100644 --- a/grammars/silver/compiler/extension/autoattr/BiEquality.sv +++ b/grammars/silver/compiler/extension/autoattr/BiEquality.sv @@ -31,9 +31,8 @@ top::AGDcl ::= 'biequality' 'attribute' synPartial::Name ',' syn::Name 'with' in } abstract production biequalityInhAttributionDcl -top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs +top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs { - undecorates to attributionDcl('attribute', at, attl, 'occurs', 'on', nt, nttl, ';'); top.unparse = "attribute " ++ at.unparse ++ attl.unparse ++ " occurs on " ++ nt.unparse ++ nttl.unparse ++ ";"; top.moduleNames := []; diff --git a/grammars/silver/compiler/extension/autoattr/Destruct.sv b/grammars/silver/compiler/extension/autoattr/Destruct.sv index 8664758f0..6cab1ef20 100644 --- a/grammars/silver/compiler/extension/autoattr/Destruct.sv +++ b/grammars/silver/compiler/extension/autoattr/Destruct.sv @@ -19,10 +19,9 @@ top::AGDcl ::= 'destruct' 'attribute' inh::Name ';' [attrDef(defaultEnvItem(destructDcl(inhFName, sourceGrammar=top.grammarName, sourceLocation=inh.nameLoc)))]); } -abstract production destructAttributionDcl -top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs +abstract production destructAttributionDcl implements AttributionDcl +top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs { - undecorates to attributionDcl('attribute', at, attl, 'occurs', 'on', nt, nttl, ';'); top.unparse = "attribute " ++ at.unparse ++ attl.unparse ++ " occurs on " ++ nt.unparse ++ nttl.unparse ++ ";"; top.moduleNames := []; diff --git a/grammars/silver/compiler/extension/autoattr/Functor.sv b/grammars/silver/compiler/extension/autoattr/Functor.sv index 20f647976..5981a4cce 100644 --- a/grammars/silver/compiler/extension/autoattr/Functor.sv +++ b/grammars/silver/compiler/extension/autoattr/Functor.sv @@ -19,10 +19,9 @@ top::AGDcl ::= 'functor' 'attribute' a::Name ';' [attrDef(defaultEnvItem(functorDcl(fName, sourceGrammar=top.grammarName, sourceLocation=a.nameLoc)))]); } -abstract production functorAttributionDcl -top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs +abstract production functorAttributionDcl implements AttributionDcl +top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs { - undecorates to attributionDcl('attribute', at, attl, 'occurs', 'on', nt, nttl, ';'); top.unparse = "attribute " ++ at.unparse ++ attl.unparse ++ " occurs on " ++ nt.unparse ++ nttl.unparse ++ ";"; top.moduleNames := []; diff --git a/grammars/silver/compiler/extension/doc/core/AGDcl.sv b/grammars/silver/compiler/extension/doc/core/AGDcl.sv index 980ea6df3..466e982d8 100644 --- a/grammars/silver/compiler/extension/doc/core/AGDcl.sv +++ b/grammars/silver/compiler/extension/doc/core/AGDcl.sv @@ -229,7 +229,7 @@ top::AGDcl ::= 'type' id::Name tl::BracketedOptTypeExprs 'foreign' '=' trans::St aspect production defaultAttributionDcl -top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs +top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs { top.docForName = ""; top.docUnparse = ""; @@ -320,7 +320,7 @@ top::AGDcl ::= n::Name } aspect production errorAttributionDcl -top::AGDcl ::= msg::[Message] at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs +top::AGDcl ::= msg::[Message] @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs { top.docForName = ""; top.docUnparse = ""; diff --git a/grammars/silver/compiler/extension/strategyattr/Strategy.sv b/grammars/silver/compiler/extension/strategyattr/Strategy.sv index b38c0513d..456f76616 100644 --- a/grammars/silver/compiler/extension/strategyattr/Strategy.sv +++ b/grammars/silver/compiler/extension/strategyattr/Strategy.sv @@ -55,10 +55,9 @@ top::AGDcl ::= isTotal::Boolean a::Name recVarNameEnv::[Pair] rec forwards to fwrd; } -abstract production strategyAttributionDcl -top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs +abstract production strategyAttributionDcl implements AttributionDcl +top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs { - undecorates to attributionDcl('attribute', at, attl, 'occurs', 'on', nt, nttl, ';'); propagate grammarName, env, flowEnv; production attribute localErrors::[Message] with ++; diff --git a/grammars/silver/compiler/translation/java/core/OccursDcl.sv b/grammars/silver/compiler/translation/java/core/OccursDcl.sv index 8d621a6d9..f317c401f 100644 --- a/grammars/silver/compiler/translation/java/core/OccursDcl.sv +++ b/grammars/silver/compiler/translation/java/core/OccursDcl.sv @@ -1,7 +1,7 @@ grammar silver:compiler:translation:java:core; aspect production defaultAttributionDcl -top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs +top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs { local ntfn :: String = nt.lookupType.fullName; local occursType :: String = if at.lookupAttribute.dcl.isSynthesized then "syn" else "inh"; @@ -36,7 +36,7 @@ top::AGDcl ::= at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl:: } aspect production errorAttributionDcl -top::AGDcl ::= msg::[Message] at::Decorated! QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs +top::AGDcl ::= msg::[Message] @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs { top.setupInh := error("Internal compiler error: translation not defined in the presence of errors"); top.valueWeaving := error("Internal compiler error: translation not defined in the presence of errors"); From c0cfb2cb9956d2097915a0f4897d89280efe802f Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 12 Mar 2024 16:12:02 -0500 Subject: [PATCH 193/283] Fix semantic highlighting for dispatchSigDcl --- grammars/silver/compiler/definition/core/DispatchDcl.sv | 2 ++ 1 file changed, 2 insertions(+) diff --git a/grammars/silver/compiler/definition/core/DispatchDcl.sv b/grammars/silver/compiler/definition/core/DispatchDcl.sv index d6b04d4b9..f80176e8b 100644 --- a/grammars/silver/compiler/definition/core/DispatchDcl.sv +++ b/grammars/silver/compiler/definition/core/DispatchDcl.sv @@ -21,4 +21,6 @@ top::AGDcl ::= 'dispatch' id::Name '=' sig::ProductionSignature ';' if isLower(substring(0,1,id.name)) then [errFromOrigin(id, "Types must be capitalized. Invalid dispatch name " ++ id.name)] else []; +} action { + insert semantic token IdTypeDcl_t at id.nameLoc; } From deae2f033a4fbab40df9388764ee4252a2473932 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 12 Mar 2024 16:36:08 -0500 Subject: [PATCH 194/283] Use dispatch for propagate --- .../compiler/extension/autoattr/BiEquality.sv | 12 +++++------- .../silver/compiler/extension/autoattr/DclInfo.sv | 14 +++++++------- .../silver/compiler/extension/autoattr/Destruct.sv | 5 ++--- .../silver/compiler/extension/autoattr/Equality.sv | 5 ++--- .../silver/compiler/extension/autoattr/Functor.sv | 5 ++--- .../compiler/extension/autoattr/Inherited.sv | 5 ++--- .../silver/compiler/extension/autoattr/Monoid.sv | 5 ++--- .../silver/compiler/extension/autoattr/Ordering.sv | 10 ++++------ .../compiler/extension/autoattr/Propagate.sv | 7 ++++--- .../silver/compiler/extension/autoattr/Threaded.sv | 10 ++++------ .../compiler/extension/strategyattr/Strategy.sv | 5 ++--- 11 files changed, 36 insertions(+), 47 deletions(-) diff --git a/grammars/silver/compiler/extension/autoattr/BiEquality.sv b/grammars/silver/compiler/extension/autoattr/BiEquality.sv index 47c249f42..663f2b190 100644 --- a/grammars/silver/compiler/extension/autoattr/BiEquality.sv +++ b/grammars/silver/compiler/extension/autoattr/BiEquality.sv @@ -30,7 +30,7 @@ top::AGDcl ::= 'biequality' 'attribute' synPartial::Name ',' syn::Name 'with' in attrDef(defaultEnvItem(biequalityDcl(inhFName, synPartialFName, synFName, sourceGrammar=top.grammarName, sourceLocation=syn.nameLoc)))]); } -abstract production biequalityInhAttributionDcl +abstract production biequalityInhAttributionDcl implements AttributionDcl top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs { top.unparse = "attribute " ++ at.unparse ++ attl.unparse ++ " occurs on " ++ nt.unparse ++ nttl.unparse ++ ";"; @@ -59,10 +59,9 @@ top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedO nt, nttl); } -abstract production propagateBiequalitySynPartial -top::ProductionStmt ::= inh::String synPartial::Decorated! QName syn::String +abstract production propagateBiequalitySynPartial implements Propagate +top::ProductionStmt ::= @synPartial::QName inh::String syn::String { - undecorates to propagateOneAttr(synPartial); top.unparse = s"propagate ${synPartial.unparse};"; forwards to @@ -95,10 +94,9 @@ top::ProductionStmt ::= inh::String synPartial::Decorated! QName syn::String }; } -abstract production propagateBiequalitySyn -top::ProductionStmt ::= inh::String synPartial::String syn::Decorated! QName +abstract production propagateBiequalitySyn implements Propagate +top::ProductionStmt ::= @syn::QName inh::String synPartial::String { - undecorates to propagateOneAttr(syn); top.unparse = s"propagate ${syn.unparse};"; forwards to diff --git a/grammars/silver/compiler/extension/autoattr/DclInfo.sv b/grammars/silver/compiler/extension/autoattr/DclInfo.sv index 677f95b09..13695dcf1 100644 --- a/grammars/silver/compiler/extension/autoattr/DclInfo.sv +++ b/grammars/silver/compiler/extension/autoattr/DclInfo.sv @@ -1,6 +1,6 @@ grammar silver:compiler:extension:autoattr; -synthesized attribute propagateDispatcher :: (ProductionStmt ::= Decorated! QName) occurs on AttributeDclInfo; +synthesized attribute propagateDispatcher :: Propagate occurs on AttributeDclInfo; synthesized attribute emptyVal::Expr occurs on AttributeDclInfo; @@ -95,7 +95,7 @@ top::AttributeDclInfo ::= inh::String syn::String top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations top.attributionDispatcher = defaultAttributionDcl; - top.propagateDispatcher = propagateEquality(inh, _); + top.propagateDispatcher = propagateEquality(inh); } abstract production orderingKeyDcl @@ -129,7 +129,7 @@ top::AttributeDclInfo ::= inh::String keySyn::String syn::String top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations top.attributionDispatcher = defaultAttributionDcl; - top.propagateDispatcher = propagateOrdering(inh, keySyn, _); + top.propagateDispatcher = propagateOrdering(inh, keySyn); } abstract production biequalityPartialDcl @@ -146,7 +146,7 @@ top::AttributeDclInfo ::= inh::String synPartial::String syn::String top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations top.attributionDispatcher = defaultAttributionDcl; - top.propagateDispatcher = propagateBiequalitySynPartial(inh, _, syn); + top.propagateDispatcher = propagateBiequalitySynPartial(inh, syn); } abstract production biequalityDcl @@ -163,7 +163,7 @@ top::AttributeDclInfo ::= inh::String synPartial::String syn::String top.dataAccessHandler = synDataAccessHandler; top.attrDefDispatcher = synthesizedAttributeDef; -- Allow normal syn equations top.attributionDispatcher = defaultAttributionDcl; - top.propagateDispatcher = propagateBiequalitySyn(inh, synPartial, _); + top.propagateDispatcher = propagateBiequalitySyn(inh, synPartial); } abstract production threadedInhDcl @@ -199,7 +199,7 @@ top::AttributeDclInfo ::= inh::String syn::String bound::[TyVar] ty::Type o::May then inhAppendColAttributeDef -- Allow normal inh append equations else nonCollectionErrorAppendAttributeDef; top.attributionDispatcher = defaultAttributionDcl; - top.propagateDispatcher = propagateThreadedInh(o.isJust, rev, _, syn); + top.propagateDispatcher = propagateThreadedInh(o.isJust, rev, syn); } abstract production threadedSynDcl @@ -235,5 +235,5 @@ top::AttributeDclInfo ::= inh::String syn::String bound::[TyVar] ty::Type o::May then synAppendColAttributeDef -- Allow normal syn append equations else nonCollectionErrorAppendAttributeDef; top.attributionDispatcher = defaultAttributionDcl; - top.propagateDispatcher = propagateThreadedSyn(o.isJust, rev, inh, _); + top.propagateDispatcher = propagateThreadedSyn(o.isJust, rev, inh); } diff --git a/grammars/silver/compiler/extension/autoattr/Destruct.sv b/grammars/silver/compiler/extension/autoattr/Destruct.sv index 6cab1ef20..f9e5d3921 100644 --- a/grammars/silver/compiler/extension/autoattr/Destruct.sv +++ b/grammars/silver/compiler/extension/autoattr/Destruct.sv @@ -70,10 +70,9 @@ top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedO - Propagate a destruct inherited attribute on the enclosing production - @param attr The name of the attribute to propagate -} -abstract production propagateDestruct -top::ProductionStmt ::= attr::Decorated! QName +abstract production propagateDestruct implements Propagate +top::ProductionStmt ::= @attr::QName { - undecorates to propagateOneAttr(attr); top.unparse = s"propagate ${attr.unparse};"; local numChildren::Integer = length(top.frame.signature.inputElements); diff --git a/grammars/silver/compiler/extension/autoattr/Equality.sv b/grammars/silver/compiler/extension/autoattr/Equality.sv index 9223e0b0e..fe83b369c 100644 --- a/grammars/silver/compiler/extension/autoattr/Equality.sv +++ b/grammars/silver/compiler/extension/autoattr/Equality.sv @@ -27,10 +27,9 @@ top::AGDcl ::= 'equality' 'attribute' syn::Name 'with' inh::QName ';' - Propagate a equality synthesized attribute on the enclosing production - @param attr The name of the attribute to propagate -} -abstract production propagateEquality -top::ProductionStmt ::= inh::String syn::Decorated! QName +abstract production propagateEquality implements Propagate +top::ProductionStmt ::= @syn::QName inh::String { - undecorates to propagateOneAttr(syn); top.unparse = s"propagate ${syn.unparse};"; forwards to diff --git a/grammars/silver/compiler/extension/autoattr/Functor.sv b/grammars/silver/compiler/extension/autoattr/Functor.sv index 5981a4cce..6e9be007f 100644 --- a/grammars/silver/compiler/extension/autoattr/Functor.sv +++ b/grammars/silver/compiler/extension/autoattr/Functor.sv @@ -52,10 +52,9 @@ top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedO - Propagate a functor attribute on the enclosing production - @param attr The name of the attribute to propagate -} -abstract production propagateFunctor -top::ProductionStmt ::= attr::Decorated! QName +abstract production propagateFunctor implements Propagate +top::ProductionStmt ::= @attr::QName { - undecorates to propagateOneAttr(attr); top.unparse = s"propagate ${attr.unparse};"; -- No explicit errors, for now. The only conceivable issue is the attribute not diff --git a/grammars/silver/compiler/extension/autoattr/Inherited.sv b/grammars/silver/compiler/extension/autoattr/Inherited.sv index fab9f717c..52f787a69 100644 --- a/grammars/silver/compiler/extension/autoattr/Inherited.sv +++ b/grammars/silver/compiler/extension/autoattr/Inherited.sv @@ -1,9 +1,8 @@ grammar silver:compiler:extension:autoattr; -abstract production propagateInh -top::ProductionStmt ::= attr::Decorated! QName +abstract production propagateInh implements Propagate +top::ProductionStmt ::= @attr::QName { - undecorates to propagateOneAttr(attr); top.unparse = s"propagate ${attr.unparse};"; local attrFullName::String = attr.lookupAttribute.dcl.fullName; diff --git a/grammars/silver/compiler/extension/autoattr/Monoid.sv b/grammars/silver/compiler/extension/autoattr/Monoid.sv index 4028ededb..668abd576 100644 --- a/grammars/silver/compiler/extension/autoattr/Monoid.sv +++ b/grammars/silver/compiler/extension/autoattr/Monoid.sv @@ -115,10 +115,9 @@ top::Operation ::= - Propagate a monoid attribute on the enclosing production - @param attr The name of the attribute to propagate -} -abstract production propagateMonoid -top::ProductionStmt ::= attr::Decorated! QName +abstract production propagateMonoid implements Propagate +top::ProductionStmt ::= @attr::QName { - undecorates to propagateOneAttr(attr); top.unparse = s"propagate ${attr.unparse};"; -- No explicit errors, for now. The only conceivable issue is the attribute not diff --git a/grammars/silver/compiler/extension/autoattr/Ordering.sv b/grammars/silver/compiler/extension/autoattr/Ordering.sv index 1d5581a3b..2ca544d43 100644 --- a/grammars/silver/compiler/extension/autoattr/Ordering.sv +++ b/grammars/silver/compiler/extension/autoattr/Ordering.sv @@ -34,10 +34,9 @@ top::AGDcl ::= 'ordering' 'attribute' keySyn::Name ',' syn::Name 'with' inh::QNa {-- - Propagate a ordering key synthesized attribute on the enclosing production -} -abstract production propagateOrderingKey -top::ProductionStmt ::= syn::Decorated! QName +abstract production propagateOrderingKey implements Propagate +top::ProductionStmt ::= @syn::QName { - undecorates to propagateOneAttr(syn); top.unparse = s"propagate ${syn.unparse};"; forwards to @@ -50,10 +49,9 @@ top::ProductionStmt ::= syn::Decorated! QName {-- - Propagate a ordering synthesized attribute on the enclosing production -} -abstract production propagateOrdering -top::ProductionStmt ::= inh::String keySyn::String syn::Decorated! QName +abstract production propagateOrdering implements Propagate +top::ProductionStmt ::= @syn::QName inh::String keySyn::String { - undecorates to propagateOneAttr(syn); top.unparse = s"propagate ${syn.unparse};"; local topName::String = top.frame.signature.outputElement.elementName; diff --git a/grammars/silver/compiler/extension/autoattr/Propagate.sv b/grammars/silver/compiler/extension/autoattr/Propagate.sv index af62f59ab..d3c80a360 100644 --- a/grammars/silver/compiler/extension/autoattr/Propagate.sv +++ b/grammars/silver/compiler/extension/autoattr/Propagate.sv @@ -143,10 +143,11 @@ top::ProductionStmt ::= attr::QName else attr.lookupAttribute.dcl.propagateDispatcher(attr); } -abstract production propagateError -top::ProductionStmt ::= attr::Decorated! QName +dispatch Propagate = ProductionStmt ::= @attr::QName; + +abstract production propagateError implements Propagate +top::ProductionStmt ::= @attr::QName { - undecorates to propagateOneAttr(attr); forwards to errorProductionStmt( [errFromOrigin(attr, s"Attribute ${attr.name} cannot be propagated")]); diff --git a/grammars/silver/compiler/extension/autoattr/Threaded.sv b/grammars/silver/compiler/extension/autoattr/Threaded.sv index 834d9783e..64ea3ab3b 100644 --- a/grammars/silver/compiler/extension/autoattr/Threaded.sv +++ b/grammars/silver/compiler/extension/autoattr/Threaded.sv @@ -96,10 +96,9 @@ concrete productions top::Direction { top.unparse = "right to left"; top.reversed = true; } -abstract production propagateThreadedInh -top::ProductionStmt ::= isCol::Boolean rev::Boolean inh::Decorated! QName syn::String +abstract production propagateThreadedInh implements Propagate +top::ProductionStmt ::= @inh::QName isCol::Boolean rev::Boolean syn::String { - undecorates to propagateOneAttr(inh); top.unparse = s"propagate ${inh.unparse};"; local lhsName::String = top.frame.signature.outputElement.elementName; @@ -133,10 +132,9 @@ top::ProductionStmt ::= isCol::Boolean rev::Boolean inh::Decorated! QName syn::S else [if !null(getValueDcl("forward", top.env)) then "forward" else lhsName])); } -abstract production propagateThreadedSyn -top::ProductionStmt ::= isCol::Boolean rev::Boolean inh::String syn::Decorated! QName +abstract production propagateThreadedSyn implements Propagate +top::ProductionStmt ::= @syn::QName isCol::Boolean rev::Boolean inh::String { - undecorates to propagateOneAttr(syn); top.unparse = s"propagate ${syn.unparse};"; local lhsName::String = top.frame.signature.outputElement.elementName; diff --git a/grammars/silver/compiler/extension/strategyattr/Strategy.sv b/grammars/silver/compiler/extension/strategyattr/Strategy.sv index 456f76616..35e2d2a23 100644 --- a/grammars/silver/compiler/extension/strategyattr/Strategy.sv +++ b/grammars/silver/compiler/extension/strategyattr/Strategy.sv @@ -116,10 +116,9 @@ top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedO - Propagate a strategy attribute on the enclosing production - @param attr The name of the attribute to propagate -} -abstract production propagateStrategy -top::ProductionStmt ::= attr::Decorated! QName +abstract production propagateStrategy implements Propagate +top::ProductionStmt ::= @attr::QName { - undecorates to propagateOneAttr(attr); top.unparse = s"propagate ${attr.unparse}"; production isTotal::Boolean = attr.lookupAttribute.dcl.isTotal; From 1e60e9370828a8b2adae35c0f2f11e863348a120 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 12 Mar 2024 16:42:56 -0500 Subject: [PATCH 195/283] Semantic token for implements --- grammars/silver/compiler/definition/core/ProductionDcl.sv | 3 +++ 1 file changed, 3 insertions(+) diff --git a/grammars/silver/compiler/definition/core/ProductionDcl.sv b/grammars/silver/compiler/definition/core/ProductionDcl.sv index 4d8677349..92ac7a7d6 100644 --- a/grammars/silver/compiler/definition/core/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/core/ProductionDcl.sv @@ -117,6 +117,9 @@ top::ProductionImplements ::= 'implements' id::QName | dispatchDcl(_) -> [] | _ -> [errFromOrigin(id, "Type '" ++ id.unparse ++ "' is not a dispatch signature type.")] end; +} action { + insert semantic token IdType_t at id.nameLoc; + sigNames = []; } concrete production productionImplementsNone From d413a8c2e1815ca772613355569b0436045df67f Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 12 Mar 2024 16:50:27 -0500 Subject: [PATCH 196/283] Use dispatch for deriving --- .../silver/compiler/extension/deriving/Derive.sv | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/grammars/silver/compiler/extension/deriving/Derive.sv b/grammars/silver/compiler/extension/deriving/Derive.sv index 4ce98e01b..cbc190af0 100644 --- a/grammars/silver/compiler/extension/deriving/Derive.sv +++ b/grammars/silver/compiler/extension/deriving/Derive.sv @@ -71,10 +71,11 @@ top::AGDcl ::= tc::QName nt::QName end; } -production deriveEqDcl -top::AGDcl ::= nt::Decorated! QName +dispatch Derive = AGDcl ::= @nt::QName; + +production deriveEqDcl implements Derive +top::AGDcl ::= @nt::QName { - undecorates to deriveDcl(qName("silver:core:Eq"), nt); top.unparse = s"derive silver:core:Eq on ${nt.unparse};"; top.moduleNames := []; @@ -185,10 +186,9 @@ top::AGDcl ::= nt::Decorated! QName }; } -production deriveOrdDcl -top::AGDcl ::= nt::Decorated! QName +production deriveOrdDcl implements Derive +top::AGDcl ::= @nt::QName { - undecorates to deriveDcl(qName("silver:core:Ord"), nt); top.unparse = s"derive silver:core:Ord on ${nt.unparse};"; top.moduleNames := []; From b5398a55eb556538f9b085c54f50cc88b0568c71 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 12 Mar 2024 17:02:02 -0500 Subject: [PATCH 197/283] Removing uses of 'undecorates to' --- .../silver/compiler/definition/core/Expr.sv | 19 ------------------- .../compiler/definition/core/OccursDcl.sv | 1 - .../definition/core/ProductionBody.sv | 2 -- .../implicit_monads/ProductionBody.sv | 4 ---- 4 files changed, 26 deletions(-) diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index 719599c96..52625cb30 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -312,7 +312,6 @@ dispatch Application = Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs; abstract production errorApplication implements Application top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { - undecorates to application(e, '(', es, ',', anns, ')'); top.unparse = e.unparse ++ "(" ++ es.unparse ++ "," ++ anns.unparse ++ ")"; top.errors <- @@ -330,7 +329,6 @@ top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs abstract production functionApplication implements Application top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { - undecorates to application(e, '(', es, ',', anns, ')'); top.unparse = e.unparse ++ "(" ++ es.unparse ++ "," ++ anns.unparse ++ ")"; top.freeVars := e.freeVars ++ es.freeVars ++ anns.freeVars; @@ -343,7 +341,6 @@ top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs abstract production functionInvocation implements Application top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { - undecorates to application(e, '(', es, ',', anns, ')'); top.unparse = e.unparse ++ "(" ++ es.unparse ++ "," ++ anns.unparse ++ ")"; local ety :: Type = performSubstitution(e.typerep, e.upSubst); @@ -354,7 +351,6 @@ top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs abstract production partialApplication implements Application top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { - undecorates to application(e, '(', es, ',', anns, ')'); top.unparse = e.unparse ++ "(" ++ es.unparse ++ "," ++ anns.unparse ++ ")"; local ety :: Type = performSubstitution(e.typerep, e.upSubst); @@ -368,7 +364,6 @@ top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs abstract production dispatchApplication implements Application top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { - undecorates to application(e, '(', es, ',', anns, ')'); top.unparse = e.unparse ++ "(" ++ es.unparse ++ "," ++ anns.unparse ++ ")"; top.typerep = performSubstitution(e.typerep, e.upSubst).outputType; @@ -423,7 +418,6 @@ dispatch Access = Expr ::= @e::Expr @q::QNameAttrOccur; abstract production errorAccessHandler implements Access top::Expr ::= @e::Expr @q::QNameAttrOccur { - undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; top.typerep = errorType(); @@ -439,7 +433,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur abstract production terminalAccessHandler implements Access top::Expr ::= @e::Expr @q::QNameAttrOccur { - undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; -- NO use of q.errors, as that become nonsensical here. @@ -464,7 +457,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur abstract production undecoratedAccessHandler implements Access top::Expr ::= @e::Expr @q::QNameAttrOccur { - undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; -- Note: LHS is UNdecorated, here we dispatch based on the kind of attribute. @@ -479,7 +471,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur abstract production dataAccessHandler implements Access top::Expr ::= @e::Expr @q::QNameAttrOccur { - undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; -- Note: LHS is data, here we dispatch based on the kind of attribute. @@ -497,7 +488,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur abstract production accessBouncer top::Expr ::= e::Expr @q::QNameAttrOccur target::Access { - undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; propagate config, grammarName, env, freeVars, frame, originRules, compiledGrammars; e.isRoot = false; @@ -527,7 +517,6 @@ Expr ::= @e::Expr @q::QNameAttrOccur target::Access abstract production decoratedAccessHandler implements Access top::Expr ::= @e::Expr @q::QNameAttrOccur { - undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; -- Note: LHS is decorated, here we dispatch based on the kind of attribute. @@ -542,7 +531,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur abstract production synDecoratedAccessHandler implements Access top::Expr ::= @e::Expr @q::QNameAttrOccur { - undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; top.typerep = q.typerep; @@ -551,7 +539,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur abstract production inhDecoratedAccessHandler implements Access top::Expr ::= @e::Expr @q::QNameAttrOccur { - undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; top.typerep = q.typerep; @@ -560,7 +547,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur abstract production transDecoratedAccessHandler implements Access top::Expr ::= @e::Expr @q::QNameAttrOccur { - undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; top.typerep = q.typerep.asNtOrDecType; @@ -569,7 +555,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur abstract production annoAccessHandler implements Access top::Expr ::= @e::Expr @q::QNameAttrOccur { - undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; production index :: Integer = @@ -581,7 +566,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur abstract production synDataAccessHandler implements Access top::Expr ::= @e::Expr @q::QNameAttrOccur { - undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; top.typerep = q.typerep; @@ -590,7 +574,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur abstract production inhUndecoratedAccessErrorHandler implements Access top::Expr ::= @e::Expr @q::QNameAttrOccur { - undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; top.typerep = q.typerep.asNtOrDecType; @@ -601,7 +584,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur abstract production transUndecoratedAccessErrorHandler implements Access top::Expr ::= @e::Expr @q::QNameAttrOccur { - undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; top.typerep = q.typerep.asNtOrDecType; @@ -612,7 +594,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur abstract production unknownDclAccessHandler implements Access top::Expr ::= @e::Expr @q::QNameAttrOccur { - undecorates to access(e, '.', q); top.unparse = e.unparse ++ "." ++ q.unparse; top.typerep = errorType(); diff --git a/grammars/silver/compiler/definition/core/OccursDcl.sv b/grammars/silver/compiler/definition/core/OccursDcl.sv index 46f6b5e5a..f69be4f21 100644 --- a/grammars/silver/compiler/definition/core/OccursDcl.sv +++ b/grammars/silver/compiler/definition/core/OccursDcl.sv @@ -140,7 +140,6 @@ top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedO abstract production errorAttributionDcl top::AGDcl ::= msg::[Message] @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs { - undecorates to errorAGDcl(msg); top.unparse = "attribute " ++ at.unparse ++ attl.unparse ++ " occurs on " ++ nt.unparse ++ nttl.unparse ++ ";"; top.occursDefs := []; top.errors <- msg; diff --git a/grammars/silver/compiler/definition/core/ProductionBody.sv b/grammars/silver/compiler/definition/core/ProductionBody.sv index c1073fe54..c7ef90022 100644 --- a/grammars/silver/compiler/definition/core/ProductionBody.sv +++ b/grammars/silver/compiler/definition/core/ProductionBody.sv @@ -342,7 +342,6 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr abstract production synthesizedAttributeDef implements AttributeDef top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { - undecorates to attributeDef(dl, '.', attr, '=', e, ';'); top.unparse = "\t" ++ dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; e.isRoot = true; @@ -358,7 +357,6 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr abstract production inheritedAttributeDef implements AttributeDef top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { - undecorates to attributeDef(dl, '.', attr, '=', e, ';'); top.unparse = "\t" ++ dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; e.isRoot = true; diff --git a/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv b/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv index d0c58b87d..7860b4794 100644 --- a/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv +++ b/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv @@ -188,7 +188,6 @@ fun buildExplicitAttrErrors [Message] ::= l::[Decorated QNameAttrOccur] = abstract production restrictedSynAttributeDef implements AttributeDef top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { - undecorates to attributeDef(dl, '.', attr, '=', e, ';'); top.unparse = dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; propagate grammarName, compiledGrammars, config, frame, env, flowEnv, finalSubst, originRules; @@ -215,7 +214,6 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr abstract production restrictedInhAttributeDef implements AttributeDef top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { - undecorates to attributeDef(dl, '.', attr, '=', e, ';'); top.unparse = dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; propagate grammarName, compiledGrammars, config, frame, env, flowEnv, finalSubst, originRules; @@ -245,7 +243,6 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr abstract production implicitSynAttributeDef implements AttributeDef top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { - undecorates to attributeDef(dl, '.', attr, '=', e, ';'); top.unparse = dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; propagate grammarName, compiledGrammars, config, frame, env, flowEnv, originRules; @@ -277,7 +274,6 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr abstract production implicitInhAttributeDef implements AttributeDef top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { - undecorates to attributeDef(dl, '.', attr, '=', e, ';'); top.unparse = dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; propagate grammarName, compiledGrammars, config, frame, env, flowEnv, originRules; From 734c5dbf859865bebea138cf7aa2c3c8029db188 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 12 Mar 2024 18:53:44 -0500 Subject: [PATCH 198/283] Remove support for 'undecorates to' --- .../typechecking/core/ProductionBody.sv | 15 +--------- .../analysis/uniqueness/ProductionBody.sv | 14 --------- .../compiler/analysis/warnings/flow/Inh.sv | 19 ------------ .../definition/core/ProductionBody.sv | 29 ++++--------------- .../compiler/definition/core/ProductionDcl.sv | 5 ---- .../compiler/definition/core/Terminals.sv | 1 - .../definition/flow/env/ProductionBody.sv | 6 ---- .../implicit_monads/ProductionBody.sv | 8 ----- .../translation/java/core/ProductionBody.sv | 6 ---- .../translation/java/core/ProductionDcl.sv | 13 ++------- 10 files changed, 10 insertions(+), 106 deletions(-) diff --git a/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv b/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv index 0ac2aedea..097aa80d5 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv @@ -3,7 +3,7 @@ grammar silver:compiler:analysis:typechecking:core; attribute upSubst, downSubst, finalSubst occurs on ProductionStmt, ForwardInhs, ForwardInh, ForwardLHSExpr; propagate upSubst, downSubst on ProductionStmt, ForwardInhs, ForwardInh, ForwardLHSExpr - excluding productionStmtAppend, attachNoteStmt, forwardsTo, forwardInh, undecoratesTo, returnDef, synthesizedAttributeDef, inheritedAttributeDef, localValueDef; + excluding productionStmtAppend, attachNoteStmt, forwardsTo, forwardInh, returnDef, synthesizedAttributeDef, inheritedAttributeDef, localValueDef; propagate finalSubst on ProductionStmt, ForwardInhs, ForwardInh, ForwardLHSExpr excluding productionStmtAppend; {-- @@ -75,19 +75,6 @@ top::ForwardInh ::= lhs::ForwardLHSExpr '=' e::Expr ';' else []; } -aspect production undecoratesTo -top::ProductionStmt ::= 'undecorates' 'to' e::Expr ';' -{ - local attribute errCheck1 :: TypeCheck; errCheck1.finalSubst = top.finalSubst; - - thread downSubst, upSubst on top, e, errCheck1, top; - - errCheck1 = check(e.typerep, top.frame.signature.outputElement.typerep); - top.errors <- if errCheck1.typeerror - then [errFromOrigin(e, "Undecorates's expected type is " ++ errCheck1.rightpp ++ ", but the actual type supplied is " ++ errCheck1.leftpp)] - else []; -} - aspect production attachNoteStmt top::ProductionStmt ::= 'attachNote' e::Expr ';' { diff --git a/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv b/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv index 322c07efa..d412f92c9 100644 --- a/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv +++ b/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv @@ -3,15 +3,6 @@ grammar silver:compiler:analysis:uniqueness; attribute uniqueRefs occurs on ProductionBody, ProductionStmts, ProductionStmt; propagate uniqueRefs on ProductionBody, ProductionStmts, ProductionStmt; -aspect production productionDcl -top::AGDcl ::= 'abstract' 'production' id::Name d::ProductionImplements ns::ProductionSignature body::ProductionBody -{ - top.errors <- - if any(map((.isUniqueDecorated), namedSig.inputTypes)) && null(body.undecorateExpr) - then [errFromOrigin(top, s"Production '${id.name}' has a unique reference in its signature but no 'undecorates to'.")] - else []; -} - aspect production attachNoteStmt top::ProductionStmt ::= 'attachNote' note::Expr ';' { @@ -32,11 +23,6 @@ top::ProductionStmt ::= 'return' e::Expr ';' s"The return of ${top.frame.fullName} is not a unique context as this function has no unique parameters."), e.uniqueRefs); } -aspect production undecoratesTo -top::ProductionStmt ::= 'undecorates' 'to' e::Expr ';' -{ - top.errors <- uniqueContextErrors(e.uniqueRefs); -} aspect production synthesizedAttributeDef top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index e96d3e8e6..c660a8a44 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -537,25 +537,6 @@ top::ForwardInh ::= lhs::ForwardLHSExpr '=' e::Expr ';' else []; } -aspect production undecoratesTo -top::ProductionStmt ::= 'undecorates' 'to' e::Expr ';' -{ - -- oh no again! - local myFlow :: EnvTree = head(searchEnvTree(top.grammarName, top.compiledGrammars)).grammarFlowTypes; - - local transitiveDeps :: [FlowVertex] = - expandGraph(e.flowDeps, top.frame.flowGraph); - - local lhsInhDeps :: [String] = set:toList(onlyLhsInh(transitiveDeps)); - - top.errors <- - if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ - if null(lhsInhDeps) then [] - else [mwdaWrnFromOrigin(top, "Undecorates equation has dependencies on " ++ implode(", ", lhsInhDeps))] - else []; -} - aspect production localValueDef top::ProductionStmt ::= @val::QName e::Expr { diff --git a/grammars/silver/compiler/definition/core/ProductionBody.sv b/grammars/silver/compiler/definition/core/ProductionBody.sv index c7ef90022..9aea06ada 100644 --- a/grammars/silver/compiler/definition/core/ProductionBody.sv +++ b/grammars/silver/compiler/definition/core/ProductionBody.sv @@ -2,13 +2,13 @@ grammar silver:compiler:definition:core; tracked nonterminal ProductionBody with config, grammarName, env, unparse, errors, defs, frame, compiledGrammars, - productionAttributes, forwardExpr, returnExpr, undecorateExpr; + productionAttributes, forwardExpr, returnExpr; tracked nonterminal ProductionStmts with config, grammarName, env, unparse, errors, defs, frame, compiledGrammars, - productionAttributes, forwardExpr, returnExpr, undecorateExpr, originRules; + productionAttributes, forwardExpr, returnExpr, originRules; tracked nonterminal ProductionStmt with config, grammarName, env, unparse, errors, defs, frame, compiledGrammars, - productionAttributes, forwardExpr, returnExpr, undecorateExpr, originRules; + productionAttributes, forwardExpr, returnExpr, originRules; flowtype decorate {frame, grammarName, compiledGrammars, config, env, flowEnv, downSubst} on ProductionBody; @@ -42,12 +42,11 @@ inherited attribute frame :: BlockContext; -} monoid attribute productionAttributes :: [Def]; {-- - - The forward, return and undecorate expressions for production/function bodies. + - The forward and return expressions for production/function bodies. - These are lists since we check for duplicates at the top level -} monoid attribute forwardExpr :: [Decorated Expr]; monoid attribute returnExpr :: [Decorated Expr]; -monoid attribute undecorateExpr :: [Decorated Expr]; {-- - The attribute we're defining on a DefLHS. @@ -60,7 +59,7 @@ synthesized attribute originRuleDefs :: [Decorated Expr] occurs on ProductionStm propagate config, grammarName, env, errors, frame, compiledGrammars on ProductionBody, ProductionStmts, ProductionStmt, DefLHS, ForwardInhs, ForwardInh, ForwardLHSExpr; -propagate defs, productionAttributes, forwardExpr, returnExpr, undecorateExpr on ProductionBody, ProductionStmts; +propagate defs, productionAttributes, forwardExpr, returnExpr on ProductionBody, ProductionStmts; propagate originRules on ProductionStmts, ProductionStmt, DefLHS, ForwardInhs, ForwardInh, ForwardLHSExpr excluding attachNoteStmt; @@ -97,7 +96,7 @@ top::ProductionStmt ::= h::ProductionStmt t::ProductionStmt top.unparse = h.unparse ++ "\n" ++ t.unparse; top.originRuleDefs = h.originRuleDefs ++ t.originRuleDefs; - propagate defs, productionAttributes, forwardExpr, returnExpr, undecorateExpr; + propagate defs, productionAttributes, forwardExpr, returnExpr; } abstract production errorProductionStmt @@ -117,7 +116,6 @@ top::ProductionStmt ::= top.productionAttributes := []; top.forwardExpr := []; top.returnExpr := []; - top.undecorateExpr := []; top.defs := []; @@ -277,21 +275,6 @@ top::ForwardLHSExpr ::= q::QNameAttrOccur q.attrFor = top.frame.signature.outputElement.typerep; } -concrete production undecoratesTo -top::ProductionStmt ::= 'undecorates' 'to' e::Expr ';' -{ - top.unparse = "\tundecorates to " ++ e.unparse; - - e.isRoot = true; - - top.undecorateExpr := [e]; - - top.errors <- - if !top.frame.permitForward -- Permitted in the same place as forwards to - then [errFromOrigin(top, "Undecorates is not permitted in this context. (Only permitted in non-aspect productions.)")] - else []; -} - concrete production attributeDef top::ProductionStmt ::= dl::DefLHS '.' attr::QNameAttrOccur '=' e::Expr ';' { diff --git a/grammars/silver/compiler/definition/core/ProductionDcl.sv b/grammars/silver/compiler/definition/core/ProductionDcl.sv index 4d8677349..0f0061e5a 100644 --- a/grammars/silver/compiler/definition/core/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/core/ProductionDcl.sv @@ -73,11 +73,6 @@ top::AGDcl ::= 'abstract' 'production' id::Name d::ProductionImplements ns::Prod if length(body.forwardExpr) > 1 then [errFromOrigin(top, "Production '" ++ id.name ++ "' has more than one forward declaration.")] else []; - - top.errors <- - if length(body.undecorateExpr) > 1 - then [errFromOrigin(top, "Production '" ++ id.name ++ "' has more than one undecorate declaration.")] - else []; top.errors <- if isLower(substring(0,1,id.name)) then [] diff --git a/grammars/silver/compiler/definition/core/Terminals.sv b/grammars/silver/compiler/definition/core/Terminals.sv index 43c14c7b7..db42c20cc 100644 --- a/grammars/silver/compiler/definition/core/Terminals.sv +++ b/grammars/silver/compiler/definition/core/Terminals.sv @@ -62,7 +62,6 @@ terminal To_kwd 'to' lexer classes {KEYWORD,RESERVED}; terminal Tracked_kwd 'tracked' lexer classes {KEYWORD}; terminal Translation_kwd 'translation' lexer classes {KEYWORD}; terminal Type_t 'type' lexer classes {KEYWORD}; -terminal Undecorates_t 'undecorates' lexer classes {KEYWORD,RESERVED}; terminal With_kwd 'with' lexer classes {KEYWORD,RESERVED}, precedence = 3; -- Precedence to fix Decorated Decorated Expr with {}, which is a semantic error either way terminal AttachNote_kwd 'attachNote' lexer classes {BUILTIN,RESERVED}; diff --git a/grammars/silver/compiler/definition/flow/env/ProductionBody.sv b/grammars/silver/compiler/definition/flow/env/ProductionBody.sv index 8f71f59a2..6a0f77d9b 100644 --- a/grammars/silver/compiler/definition/flow/env/ProductionBody.sv +++ b/grammars/silver/compiler/definition/flow/env/ProductionBody.sv @@ -78,12 +78,6 @@ top::ProductionStmt ::= 'return' e::Expr ';' e.decSiteVertexInfo = nothing(); e.alwaysDecorated = false; } -aspect production undecoratesTo -top::ProductionStmt ::= 'undecorates' 'to' e::Expr ';' -{ - e.decSiteVertexInfo = nothing(); - e.alwaysDecorated = false; -} aspect production attributeDef top::ProductionStmt ::= dl::DefLHS '.' attr::QNameAttrOccur '=' e::Expr ';' diff --git a/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv b/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv index 7860b4794..d68caca08 100644 --- a/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv +++ b/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv @@ -19,7 +19,6 @@ top::ProductionStmt ::= 'implicit' dl::DefLHS '.' attr::QNameAttrOccur '=' ';' top.defs := []; top.forwardExpr := []; top.returnExpr := []; - top.undecorateExpr := []; top.containsPluck = false; @@ -59,7 +58,6 @@ top::ProductionStmt ::= 'implicit' dl::DefLHS '.' attr::QNameAttrOccur '=' e::Ex top.defs := []; top.forwardExpr := []; top.returnExpr := []; - top.undecorateExpr := []; top.containsPluck = false; @@ -100,7 +98,6 @@ top::ProductionStmt ::= 'restricted' dl::DefLHS '.' attr::QNameAttrOccur '=' e:: top.defs := []; top.forwardExpr := []; top.returnExpr := []; - top.undecorateExpr := []; top.containsPluck = false; @@ -140,7 +137,6 @@ top::ProductionStmt ::= 'unrestricted' dl::DefLHS '.' attr::QNameAttrOccur '=' e top.defs := []; top.forwardExpr := []; top.returnExpr := []; - top.undecorateExpr := []; dl.defLHSattr = attr; attr.attrFor = dl.typerep; @@ -198,7 +194,6 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr top.containsPluck = false; top.forwardExpr := []; top.returnExpr := []; - top.undecorateExpr := []; local merrors::[Message] = --gives errors for implicit/unrestricted attributes used @@ -224,7 +219,6 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr top.containsPluck = false; top.forwardExpr := []; top.returnExpr := []; - top.undecorateExpr := []; local merrors::[Message] = --gives errors for implicit/unrestricted attributes used @@ -257,7 +251,6 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr top.containsPluck = false; top.forwardExpr := []; top.returnExpr := []; - top.undecorateExpr := []; forwards to if null(e.merrors) @@ -288,7 +281,6 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr top.containsPluck = false; top.forwardExpr := []; top.returnExpr := []; - top.undecorateExpr := []; forwards to if null(e.merrors) diff --git a/grammars/silver/compiler/translation/java/core/ProductionBody.sv b/grammars/silver/compiler/translation/java/core/ProductionBody.sv index 5db4ce478..6e98dce24 100644 --- a/grammars/silver/compiler/translation/java/core/ProductionBody.sv +++ b/grammars/silver/compiler/translation/java/core/ProductionBody.sv @@ -92,12 +92,6 @@ top::ForwardLHSExpr ::= q::QNameAttrOccur top.attrName = q.attrOccursInitIndex; } -aspect production undecoratesTo -top::ProductionStmt ::= 'undecorates' 'to' e::Expr ';' -{ - top.translation = ""; -} - aspect production localAttributeDcl top::ProductionStmt ::= 'local' 'attribute' a::Name '::' te::TypeExpr ';' { diff --git a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv index 2f0f94649..0dd041e35 100644 --- a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv +++ b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv @@ -31,9 +31,7 @@ top::AGDcl ::= 'abstract' 'production' id::Name d::ProductionImplements ns::Prod local undecChild :: (String ::= NamedSignatureElement) = \ x::NamedSignatureElement -> if x.typerep.isDecorated - then if isDecorable(x.typerep, body.env) - then error("Production " ++ fName ++ " has a decorable decorated child but no 'undecorates to'.") -- TODO: Remove this when this becomes a uniqueness analysis warning - else s"context.childDecoratedLazy(i_${x.elementName})" + then s"context.childDecoratedLazy(i_${x.elementName})" else if isDecorable(x.typerep, body.env) then s"context.childUndecoratedLazy(i_${x.elementName})" else s"child_${x.elementName}"; @@ -185,19 +183,14 @@ ${flatMap(makeInhOccursContextAccess(namedSig.freeVariables, namedSig.contextInh ${if isData then "" else s""" @Override public common.Node evalUndecorate(final common.DecoratedNode context) { - ${if !null(body.undecorateExpr) - then s"return (common.Node)${head(body.undecorateExpr).translation};" - else if !null(decorableChildren) + ${if !null(decorableChildren) then s"return new ${className}(${implode(", ", - -- A production node with no special undecoration behavior has the same origin as the - -- original node when implicitly undecorated. + -- An implicitly undecorated production node has the same origin as the original node. -- This will be overidden by duplicate when calling new(). (if wantsTracking then ["this.origin"] else []) ++ namedSig.contextRefElems ++ map(undecChild, namedSig.inputElements) ++ map(copyAnno, namedSig.namedInputElements))});" - -- TODO: Consider if all decorable children are directly undecorable. - -- This must avoid forcing children that are thunks, and probably also should be cached. else "return this;"} } From 74e6918b8f533438f8b9d34e30e78545e6b7888e Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 14 Mar 2024 16:39:56 -0500 Subject: [PATCH 199/283] Support getting the names of children for a production --- .../silver/compiler/translation/java/core/ProductionDcl.sv | 5 +++++ runtime/java/src/common/Node.java | 2 +- runtime/java/src/common/RTTIManager.java | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv index 52dad2a1e..2888d8488 100644 --- a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv +++ b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv @@ -52,6 +52,9 @@ top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::Pr local copyAnno :: (String ::= NamedSignatureElement) = (\x::NamedSignatureElement -> s"anno_${makeIdName(x.elementName)}"); + local getChildNames :: (String ::= NamedSignatureElement) = + (\x::NamedSignatureElement -> s"\"${x.elementName}\""); + local getChildTypes :: (String ::= NamedSignatureElement) = (\x::NamedSignatureElement -> case x.typerep of | nonterminalType(fn, _, _, _) -> s"\"${fn}\"" @@ -74,6 +77,7 @@ public final class ${className} extends ${fnnt} { ${makeIndexDcls(0, namedSig.inputElements)} + public static final String childNames[] = {${implode(",", map(getChildNames, namedSig.inputElements))}}; public static final String childTypes[] = {${implode(",", map(getChildTypes, namedSig.inputElements))}}; public static final int num_local_attrs = Init.${localVar}; @@ -330,6 +334,7 @@ ${body.translation} public int getAnnoCount() { return ${toString(length(namedSig.namedInputElements))}; } public String[] getOccursInh() { return ${className}.occurs_inh; } + public String[] getChildNames() { return ${className}.childNames; } public String[] getChildTypes() { return ${className}.childTypes; } public common.Lazy[][] getChildInheritedAttributes() { return ${className}.childInheritedAttributes; } } diff --git a/runtime/java/src/common/Node.java b/runtime/java/src/common/Node.java index da06c4fe4..61a3fe6bb 100644 --- a/runtime/java/src/common/Node.java +++ b/runtime/java/src/common/Node.java @@ -163,7 +163,7 @@ private final SilverException handleUndecorateError(final DecoratedNode context, /** * Determine if the child should be automatically decorated. * - * @param child A number in the range 0 - getNumberofChildren() + * @param child A number in the range 0 - getNumberOfChildren() * @return True if the child has a decorable type in the signature. */ public abstract boolean isChildDecorable(final int child); diff --git a/runtime/java/src/common/RTTIManager.java b/runtime/java/src/common/RTTIManager.java index 2f2f1f5b8..eee485aa8 100644 --- a/runtime/java/src/common/RTTIManager.java +++ b/runtime/java/src/common/RTTIManager.java @@ -93,6 +93,7 @@ public abstract T constructDirect( public abstract int getChildCount(); public abstract int getAnnoCount(); + public abstract String[] getChildNames(); public abstract String[] getChildTypes(); public abstract Lazy[][] getChildInheritedAttributes(); // Originally for autocopy, not currently used } From 9356996810f784cd9effa2a5ccd3bf4ae0ea3407 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 14 Mar 2024 17:06:55 -0500 Subject: [PATCH 200/283] Add a helper to lazily get the value of a local, without knowing if it is decorated --- runtime/java/src/common/DecoratedNode.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/runtime/java/src/common/DecoratedNode.java b/runtime/java/src/common/DecoratedNode.java index c3b9510ed..6fcf7d72b 100644 --- a/runtime/java/src/common/DecoratedNode.java +++ b/runtime/java/src/common/DecoratedNode.java @@ -783,6 +783,13 @@ public final Object childAsIsLazy(final int child) { // Straight up use whatever thunk (or not!) is in the node. return self.getChildLazy(child); } + public final Object localLazy(final int index) { + if(localValues[index] != null) + return localValues[index]; + + return new Thunk(() -> this.local(index)); + + } public final Object localDecoratedLazy(final int index) { if(localValues[index] != null) return localValues[index]; From 9a4df6f9fa5c47ff2d22ba4553e99d0ef3b151a5 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 14 Mar 2024 18:05:36 -0500 Subject: [PATCH 201/283] Put the source location of the equation in Lazy objects --- .../compiler/translation/java/core/Expr.sv | 9 ++++++- .../java/src/common/CollectionAttribute.java | 6 +++++ runtime/java/src/common/Lazy.java | 25 ++++++++++++++++++- runtime/java/src/common/TransInhs.java | 6 +++++ 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/grammars/silver/compiler/translation/java/core/Expr.sv b/grammars/silver/compiler/translation/java/core/Expr.sv index 9f6c5bdad..3f3fe5208 100644 --- a/grammars/silver/compiler/translation/java/core/Expr.sv +++ b/grammars/silver/compiler/translation/java/core/Expr.sv @@ -671,5 +671,12 @@ String ::= e::Decorated Expr -- we have hit the 64K bytecode limit in the past, which is why `Init` farms -- initialization code out across each production. So who knows. local swizzleOrigins::String = if e.config.noOrigins then "" else "final common.OriginContext originCtx = context.originCtx;"; - return s"new common.Lazy() { public final Object eval(final common.DecoratedNode context) { ${swizzleOrigins} return ${e.translation}; } }"; + local loc::Location = getParsedOriginLocationOrFallback(e); + local fileName::String = + case searchEnvTree(e.grammarName, e.compiledGrammars) of + | r :: _ -> r.grammarSource + | [] -> "" + end ++ loc.filename; + local sourceLocationTrans::String = s"new silver.core.Ploc(\"${fileName}\", ${toString(loc.line)}, ${toString(loc.column)}, ${toString(loc.endLine)}, ${toString(loc.endColumn)}, ${toString(loc.index)}, ${toString(loc.endIndex)})"; + return s"new common.Lazy() { public final Object eval(final common.DecoratedNode context) { ${swizzleOrigins} return ${e.translation}; } public final silver.core.NLocation getSourceLocation() { return ${sourceLocationTrans}; } }"; } diff --git a/runtime/java/src/common/CollectionAttribute.java b/runtime/java/src/common/CollectionAttribute.java index 13f800bad..e53420868 100644 --- a/runtime/java/src/common/CollectionAttribute.java +++ b/runtime/java/src/common/CollectionAttribute.java @@ -5,6 +5,8 @@ import common.exceptions.MissingDefinitionException; import common.exceptions.TraceException; +import silver.core.NLocation; + /** * This class is a specialized Lazy that allows additional elements to be inserted * during start-up initialization. These elements are then used by the custom @@ -47,6 +49,10 @@ public final void addPiece(final Lazy attribute) { } public abstract Object eval(final DecoratedNode context); + + public NLocation getSourceLocation() { + return base.getSourceLocation(); + } private static class BaseDefault implements Lazy { private final int index; diff --git a/runtime/java/src/common/Lazy.java b/runtime/java/src/common/Lazy.java index f15419d55..34a3e5c72 100644 --- a/runtime/java/src/common/Lazy.java +++ b/runtime/java/src/common/Lazy.java @@ -1,5 +1,7 @@ package common; +import silver.core.NLocation; + /** * Lazy is the interface used to create function pointers, essentially. * @@ -13,6 +15,17 @@ public interface Lazy { // TODO: probably make this Lazy... public Object eval(DecoratedNode context); + /** + * Get the source file location of the equation defining this Lazy. + * Null if this Lazy does not correspond to an equation. + * TODO: we should include this in stack traces. + * + * @return The source location of the equation defining this Lazy, or null if it is not available. + */ + public default NLocation getSourceLocation() { + return null; + } + /** * Create a Lazy that evaluates in some context and ignores the supplied one. * @@ -20,7 +33,13 @@ public interface Lazy { * @return A Lazy that evaluates in the supplied context. */ public default Lazy withContext(final DecoratedNode context) { - return (ignoredNewContext) -> eval(context); + return new Lazy() { + @Override + public Object eval(DecoratedNode ignoredNewContext) { return Lazy.this.eval(context); } + + @Override + public NLocation getSourceLocation() { return Lazy.this.getSourceLocation(); } + }; } public static class Trap implements Lazy { @@ -33,5 +52,9 @@ public Trap(String m) { public Object eval(DecoratedNode context) { return Util.error(m); } + + public NLocation getSourceLocation() { + return null; + } } } diff --git a/runtime/java/src/common/TransInhs.java b/runtime/java/src/common/TransInhs.java index 84aab3550..ae387d002 100644 --- a/runtime/java/src/common/TransInhs.java +++ b/runtime/java/src/common/TransInhs.java @@ -1,6 +1,7 @@ package common; import common.exceptions.SilverInternalError; +import silver.core.NLocation; /** * Represents the inherited attributes supplied to a translation attribute. @@ -21,6 +22,11 @@ public TransInhs(final int ni) { public Object eval(DecoratedNode context) { throw new SilverInternalError("TransInhs should never be evaluated!"); } + + @Override + public NLocation getSourceLocation() { + throw new SilverInternalError("TransInhs location should never be accessed!"); + } @Override public TransInhs withContext(final DecoratedNode context) { From c7d089f8c45cb771011fc05967a03623771a2108 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 21 Mar 2024 09:01:40 -0700 Subject: [PATCH 202/283] Remove support for unique references, start overhauling treatment of sharing in flow analysis --- .../analysis/typechecking/core/Expr.sv | 4 +- .../compiler/analysis/uniqueness/AGDcl.sv | 20 - .../compiler/analysis/uniqueness/Expr.sv | 403 +++--------------- .../analysis/uniqueness/ProductionBody.sv | 99 ----- .../compiler/analysis/uniqueness/RootSpec.sv | 24 +- .../analysis/uniqueness/SharedRefSite.sv | 29 ++ .../analysis/uniqueness/UniqueRefSite.sv | 38 -- .../compiler/analysis/warnings/flow/Inh.sv | 185 +++----- .../compiler/analysis/warnings/flow/MWDA.sv | 7 - .../definition/core/ProductionBody.sv | 4 +- .../silver/compiler/definition/core/Type.sv | 6 - .../silver/compiler/definition/env/Context.sv | 2 - .../silver/compiler/definition/env/Env.sv | 9 +- .../silver/compiler/definition/env/Type.sv | 6 - .../compiler/definition/flow/ast/Flow.sv | 79 +--- .../definition/flow/ast/VertexType.sv | 2 +- .../definition/flow/driver/DumpGraph.sv | 2 +- .../definition/flow/driver/FlowGraph.sv | 6 +- .../definition/flow/driver/ProductionGraph.sv | 64 ++- .../definition/flow/driver/StitchPoint.sv | 10 +- .../compiler/definition/flow/env/Expr.sv | 69 +-- .../compiler/definition/flow/env/FlowEnv.sv | 65 +-- .../definition/type/PrettyPrinting.sv | 6 - .../silver/compiler/definition/type/Type.sv | 14 - .../compiler/definition/type/Unification.sv | 15 - .../silver/compiler/definition/type/Util.sv | 24 +- .../definition/type/syntax/Terminals.sv | 1 - .../definition/type/syntax/TypeExpr.sv | 52 +-- .../silver/compiler/driver/util/FlowTypes.sv | 4 +- .../silver/compiler/driver/util/RootSpec.sv | 2 +- .../compiler/extension/autoattr/Functor.sv | 2 +- .../extension/implicit_monads/Expr.sv | 2 +- .../compiler/extension/implicit_monads/Let.sv | 4 +- .../compiler/extension/rewriting/Expr.sv | 6 +- .../compiler/extension/testing/WrongCode.sv | 2 +- .../concisefunctions/ConciseFunctions.sv | 3 + .../compiler/modification/let_fix/DclInfo.sv | 10 +- .../compiler/modification/let_fix/Let.sv | 5 +- .../compiler/modification/let_fix/java/Let.sv | 2 +- .../primitivepattern/PrimitiveMatch.sv | 4 +- .../modification/primitivepattern/Types.sv | 10 - .../primitivepattern/VarBinders.sv | 2 +- .../compiler/translation/java/core/Expr.sv | 84 ++-- .../translation/java/core/NamedSignature.sv | 36 +- .../translation/java/core/ProductionBody.sv | 22 +- .../translation/java/core/ProductionDcl.sv | 4 +- .../compiler/translation/java/core/Project.sv | 1 + .../compiler/translation/java/type/Type.sv | 10 - grammars/silver/core/Undecorate.sv | 13 - 49 files changed, 366 insertions(+), 1107 deletions(-) delete mode 100644 grammars/silver/compiler/analysis/uniqueness/AGDcl.sv delete mode 100644 grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv create mode 100644 grammars/silver/compiler/analysis/uniqueness/SharedRefSite.sv delete mode 100644 grammars/silver/compiler/analysis/uniqueness/UniqueRefSite.sv diff --git a/grammars/silver/compiler/analysis/typechecking/core/Expr.sv b/grammars/silver/compiler/analysis/typechecking/core/Expr.sv index 414bf6bc8..31e3f5dc1 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/Expr.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/Expr.sv @@ -221,10 +221,10 @@ top::Expr ::= '@' e::Expr thread downSubst, upSubst on top, e, errCheck1, top; - errCheck1 = check(e.typerep, uniqueDecoratedType(freshType(), inhSetType([]))); + errCheck1 = check(e.typerep, decoratedType(freshType(), inhSetType([]))); top.errors <- if errCheck1.typeerror - then [errFromOrigin(top, "Operand to @ must be a unique reference with no inherited attributes. Instead it is of type " ++ errCheck1.leftpp)] + then [errFromOrigin(top, "Operand to @ must be a reference with no inherited attributes. Instead it is of type " ++ errCheck1.leftpp)] else []; } diff --git a/grammars/silver/compiler/analysis/uniqueness/AGDcl.sv b/grammars/silver/compiler/analysis/uniqueness/AGDcl.sv deleted file mode 100644 index 312753373..000000000 --- a/grammars/silver/compiler/analysis/uniqueness/AGDcl.sv +++ /dev/null @@ -1,20 +0,0 @@ -grammar silver:compiler:analysis:uniqueness; - -attribute uniqueRefs occurs on Grammar, Root, AGDcls, AGDcl; -propagate uniqueRefs on Grammar, Root, AGDcls, AGDcl; - -aspect production globalValueDclConcrete -top::AGDcl ::= 'global' id::Name '::' cl::ConstraintList '=>' t::TypeExpr '=' e::Expr ';' -{ - top.errors <- uniqueContextErrors(e.uniqueRefs); -} -aspect production defaultConstraintClassBodyItem -top::ClassBodyItem ::= id::Name '::' cl::ConstraintList '=>' ty::TypeExpr '=' e::Expr ';' -{ - top.errors <- uniqueContextErrors(e.uniqueRefs); -} -aspect production instanceBodyItem -top::InstanceBodyItem ::= id::QName '=' e::Expr ';' -{ - top.errors <- uniqueContextErrors(e.uniqueRefs); -} diff --git a/grammars/silver/compiler/analysis/uniqueness/Expr.sv b/grammars/silver/compiler/analysis/uniqueness/Expr.sv index a1b68b1fa..d1531b870 100644 --- a/grammars/silver/compiler/analysis/uniqueness/Expr.sv +++ b/grammars/silver/compiler/analysis/uniqueness/Expr.sv @@ -1,381 +1,94 @@ grammar silver:compiler:analysis:uniqueness; -attribute uniqueRefs occurs on Expr, Exprs, AppExprs, AppExpr, PrimPatterns, PrimPattern; -propagate uniqueRefs on Expr, Exprs, AppExprs, AppExpr, PrimPatterns, PrimPattern - excluding - errorAccessHandler, terminalAccessHandler, - synDecoratedAccessHandler, inhDecoratedAccessHandler, - transDecoratedAccessHandler, - annoAccessHandler, synDataAccessHandler, - unknownDclAccessHandler, inhUndecoratedAccessErrorHandler, transUndecoratedAccessErrorHandler, - ifThenElse, lambdap, letp, matchPrimitiveReal, consPattern; +attribute sharedRefs occurs on Expr, Exprs, AppExprs, AppExpr, PrimPatterns, PrimPattern; +propagate sharedRefs on Expr, Exprs, AppExprs, AppExpr, PrimPatterns, PrimPattern + excluding ifThenElse, matchPrimitiveReal, consPattern; --- Unique references taken when this expression is wrapped in an attribute access -synthesized attribute accessUniqueRefs::[(String, UniqueRefSite)] occurs on Expr; - -aspect default production -top::Expr ::= -{ - top.accessUniqueRefs = top.uniqueRefs; -} - -aspect production childReference -top::Expr ::= @q::QName +aspect production decorationSiteExpr +top::Expr ::= '@' e::Expr { - top.uniqueRefs <- - case top.finalType, refSet of - | uniqueDecoratedType(_, _), just(inhs) - when isExportedBy(top.grammarName, [q.lookupValue.dcl.sourceGrammar], top.compiledGrammars) -> - [(top.frame.fullName ++ ":" ++ q.lookupValue.fullName, - uniqueRefSite( - sourceGrammar=top.grammarName, - sourceLocation=q.nameLoc, - refSet=inhs, - refFlowDeps=top.flowDeps - ))] - | _, _ -> [] + top.sharedRefs <- + case e.flowVertexInfo of + | just(v) -> [(top.frame.fullName ++ ":" ++ v.vertexName, sharedRefSite( + sourceGrammar=top.grammarName, + sourceLocation=getParsedOriginLocationOrFallback(top) + ))] + | nothing() -> [] end; - top.accessUniqueRefs = []; - top.errors <- - case top.finalType of - | uniqueDecoratedType(_, _) when q.lookupValue.found -> - -- Check that we are exported by the decoration site. - if !isExportedBy(top.grammarName, [q.lookupValue.dcl.sourceGrammar], top.compiledGrammars) - then [errFromOrigin(top, s"Orphaned unique reference to ${q.lookupValue.fullName} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] - -- Check that there is at most one unique reference taken to this decoration site. - else if length(lookupUniqueRefs(top.frame.fullName, q.lookupValue.fullName, top.flowEnv)) > 1 - then [errFromOrigin(top, s"Multiple unique references taken to ${q.name} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] - else [] + -- Grammars that can validly share this vertex + local vertexGrammars::[String] = + case e.flowVertexInfo of + | just(rhsVertexType(_)) -> [top.frame.sourceGrammar] + | just(localVertexType(fName)) when getValueDcl(fName, top.env) matches valDcl :: _ -> [valDcl.sourceGrammar] + | just(transAttrVertexType(rhsVertexType(sigName), transAttr)) -> + top.frame.sourceGrammar :: + case lookup(sigName, zip(top.frame.signature.inputNames, top.frame.signature.inputTypes)) of + | just(t) when getOccursDcl(transAttr, t.typeName, top.env) matches dcl :: _ -> + [dcl.sourceGrammar] + | _ -> [] + end + | just(transAttrVertexType(localVertexType(fName), transAttr)) -> + implode(":", init(explode(":", fName))) :: + case getValueDcl(fName, top.env) of + | valDcl :: _ when getOccursDcl(transAttr, valDcl.typeScheme.monoType.typeName, top.env) matches dcl :: _ -> + [dcl.sourceGrammar] + | _ -> [] + end | _ -> [] end; -} -aspect production localReference -top::Expr ::= @q::QName -{ - top.uniqueRefs <- - case top.finalType, refSet of - | uniqueDecoratedType(_, _), just(inhs) - when isExportedBy(top.grammarName, [q.lookupValue.dcl.sourceGrammar], top.compiledGrammars) -> - [(q.lookupValue.fullName, - uniqueRefSite( - sourceGrammar=top.grammarName, - sourceLocation=q.nameLoc, - refSet=inhs, - refFlowDeps=top.flowDeps - ))] - | _, _ -> [] - end; - top.accessUniqueRefs = []; top.errors <- - case top.finalType of - | uniqueDecoratedType(_, _) when q.lookupValue.found -> + case e.flowVertexInfo of + | just(lhsVertexType_real()) -> [errFromOrigin(e, s"Cannot share the production LHS.")] + | just(forwardVertexType_real()) -> [errFromOrigin(e, s"Cannot share the forward tree.")] + | just(anonVertexType(_)) -> [errFromOrigin(e, s"Cannot share an anonymously decorated tree.")] -- TODO: Not too hard to support? + | just(v) -> -- Check that we are exported by the decoration site. - if !isExportedBy(top.grammarName, [q.lookupValue.dcl.sourceGrammar], top.compiledGrammars) - then [errFromOrigin(top, s"Orphaned unique reference to ${q.lookupValue.fullName} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] + if !isExportedBy(top.grammarName, vertexGrammars, top.compiledGrammars) + then [errFromOrigin(top, s"Orphaned sharing of ${v.vertexName} in production ${top.frame.fullName}.")] -- Check that there is at most one unique reference taken to this decoration site. - else if length(lookupLocalUniqueRefs(q.lookupValue.fullName, top.flowEnv)) > 1 - then [errFromOrigin(top, s"Multiple unique references taken to ${q.name} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] - else [] - | _ -> [] + else + case lookupSharedRefs(top.frame.fullName, v, top.flowEnv) of + | [] -> [] -- Not possible? + | [_] -> [] + | srs -> [errFromOrigin(top, + s"Tree ${v.vertexName} in production ${top.frame.fullName} is shared in multiple places:\n" ++ + implode("\n", map(\ sr::SharedRefSite -> sr.sourceGrammar ++ ":" ++ sr.sourceLocation.unparse ++ "\n", srs)))] + end + | nothing() -> [errFromOrigin(e, s"This is not something that can be shared; shared trees must correspond to a known decoration site.")] end; -} -aspect production lhsReference -top::Expr ::= @q::QName -{ - top.errors <- - case top.finalType of - | uniqueDecoratedType(_, _) -> - [errFromOrigin(top, s"Cannot take a unique reference of type ${prettyType(top.finalType)} to ${q.name}.")] - | _ -> [] - end; -} -aspect production forwardReference -top::Expr ::= @q::QName -{ + top.errors <- - case top.finalType of - | uniqueDecoratedType(_, _) -> - [errFromOrigin(top, s"Cannot take a unique reference of type ${prettyType(top.finalType)} to the forward tree.")] + case e.flowVertexInfo of + | just(transAttrVertexType(v, transAttr)) + when lookupSharedRefs(top.frame.fullName, v, top.flowEnv) matches sr :: _ -> + [errFromOrigin(e, s"Cannot share ${v.vertexName}.${transAttr} in production ${top.frame.fullName}, because ${v.vertexName} is also shared (at ${sr.sourceGrammar}:${sr.sourceLocation.unparse}).")] | _ -> [] end; } -aspect production productionReference -top::Expr ::= @q::QName -{ - top.errors <- flatMap(\ tv::TyVar -> - let substTy::Type = performSubstitution(varType(tv), top.finalSubst) - in if substTy.isUniqueDecorated - then [errFromOrigin(top, s"Cannot specialize type variable ${prettyTypeWith(varType(tv), top.typerep.freeVariables)} of ${q.name}::${prettyType(top.typerep)} to a unique reference type ${prettyType(substTy)}")] - else [] - end, - top.typerep.freeVariables); -} -aspect production functionReference -top::Expr ::= @q::QName -{ - top.errors <- flatMap(\ tv::TyVar -> - let substTy::Type = performSubstitution(varType(tv), top.finalSubst) - in if substTy.isUniqueDecorated - then [errFromOrigin(top, s"Cannot specialize type variable ${prettyTypeWith(varType(tv), top.typerep.freeVariables)} of ${q.name}::${prettyType(top.typerep)} to a unique reference type ${prettyType(substTy)}")] - else [] - end, - top.typerep.freeVariables); -} -aspect production classMemberReference -top::Expr ::= @q::QName -{ - top.errors <- flatMap(\ tv::TyVar -> - let substTy::Type = performSubstitution(varType(tv), top.finalSubst) - in if substTy.isUniqueDecorated - then [errFromOrigin(top, s"Cannot specialize type variable ${prettyTypeWith(varType(tv), top.typerep.freeVariables)} of ${q.name}::${prettyType(top.typerep)} to a unique reference type ${prettyType(substTy)}")] - else [] - end, - top.typerep.freeVariables); -} -aspect production globalValueReference -top::Expr ::= @q::QName -{ - top.errors <- flatMap(\ tv::TyVar -> - let substTy::Type = performSubstitution(varType(tv), top.finalSubst) - in if substTy.isUniqueDecorated - then [errFromOrigin(top, s"Cannot specialize type variable ${prettyTypeWith(varType(tv), top.typerep.freeVariables)} of ${q.name}::${prettyType(top.typerep)} to a unique reference type ${prettyType(substTy)}")] - else [] - end, - top.typerep.freeVariables); -} - --- Whether nonterminal uniqueness is preserved for this argument position, --- i.e. this is an argument to a direct function or production application --- that will be copied upon undecoration. -inherited attribute isNtUniquenessPreserving::Boolean occurs on AppExprs, AppExpr; -propagate isNtUniquenessPreserving on AppExprs; - -monoid attribute appExprUniquenessErrors::[Message] occurs on AppExprs, AppExpr, AnnoAppExprs, AnnoExpr; -propagate appExprUniquenessErrors on AppExprs, AppExpr, AnnoAppExprs, AnnoExpr; - -aspect production functionInvocation -top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs -{ - top.errors <- es.appExprUniquenessErrors ++ anns.appExprUniquenessErrors; - es.isNtUniquenessPreserving = - case e of - | functionReference(_) -> true - | productionReference(_) -> true - | _ -> false - end; -} - -aspect production partialApplication -top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs -{ - top.errors <- es.appExprUniquenessErrors ++ anns.appExprUniquenessErrors; - es.isNtUniquenessPreserving = - case e of - | functionReference(_) -> true - | productionReference(_) -> true - | _ -> false - end; -} - -aspect production dispatchApplication -top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs -{ - top.errors <- es.appExprUniquenessErrors ++ anns.appExprUniquenessErrors; - es.isNtUniquenessPreserving = true; -} - -aspect production annoExpr -top::AnnoExpr ::= qn::QName '=' e::AppExpr -{ - e.isNtUniquenessPreserving = false; -} aspect production presentAppExpr top::AppExpr ::= e::Expr { - top.appExprUniquenessErrors <- - case top.appExprTyperep.baseType of - | varType(_) -> uniqueContextErrors(e.uniqueRefs) -- Would need linear types to make this work... - | nonterminalType(_, _, true, _) -> uniqueContextErrors(e.uniqueRefs) - | nonterminalType(_, _, _, _) when !top.isNtUniquenessPreserving -> uniqueContextErrors(e.uniqueRefs) - | _ -> [] - end; -} - -aspect production errorAccessHandler -top::Expr ::= @e::Expr @q::QNameAttrOccur -{ - top.uniqueRefs := e.accessUniqueRefs; -} -aspect production terminalAccessHandler -top::Expr ::= @e::Expr @q::QNameAttrOccur -{ - top.uniqueRefs := e.accessUniqueRefs; -} -aspect production synDecoratedAccessHandler -top::Expr ::= @e::Expr @q::QNameAttrOccur -{ - top.uniqueRefs := e.accessUniqueRefs; -} -aspect production inhDecoratedAccessHandler -top::Expr ::= @e::Expr @q::QNameAttrOccur -{ - top.uniqueRefs := e.accessUniqueRefs; -} -aspect production transDecoratedAccessHandler -top::Expr ::= @e::Expr @q::QNameAttrOccur -{ - top.uniqueRefs := - case top.finalType, refSet of - | uniqueDecoratedType(_, _), just(inhs) -> - [(case e.flowVertexInfo of - | just(rhsVertexType(sigName)) -> s"${top.frame.fullName}:${sigName}.${q.attrDcl.fullName}" - | just(localVertexType(fName)) -> s"${fName}.${q.attrDcl.fullName}" - | _ -> "" - end, - uniqueRefSite( - sourceGrammar=top.grammarName, - sourceLocation=getParsedOriginLocationOrFallback(top), - refSet=inhs, - refFlowDeps=top.flowDeps - ))] - | _, _ -> [] - end; - - top.errors <- - case top.finalType of - | uniqueDecoratedType(_, _) when q.found -> - case e.flowVertexInfo of - | just(rhsVertexType(sigName)) -> - -- Check that we are exported by the occurs-on or the production. - if !isExportedBy(top.grammarName, [q.dcl.sourceGrammar, top.frame.sourceGrammar], top.compiledGrammars) - then [errFromOrigin(top, s"Orphaned unique reference to ${top.unparse} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] - -- Check that there is at most one unique reference taken to this decoration site. - else - (if length(lookupTransUniqueRefs(top.frame.fullName, sigName, q.attrDcl.fullName, top.flowEnv)) > 1 - then [errFromOrigin(top, s"Multiple unique references taken to ${top.unparse} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] - -- Check that there isn't also a unique reference taken to e - else []) ++ - if !null(lookupUniqueRefs(top.frame.fullName, sigName, top.flowEnv)) - then [errFromOrigin(top, s"Cannot take a unique reference to ${top.unparse} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}) since there is also a unique reference taken to ${e.unparse}.")] - else [] - | just(localVertexType(fName)) -> - -- Check that we are exported by the occurs-on or the local. - if !isExportedBy(top.grammarName, [q.dcl.sourceGrammar, head(getValueDcl(fName, top.env)).sourceGrammar], top.compiledGrammars) - then [errFromOrigin(top, s"Orphaned unique reference to ${top.unparse} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] - -- Check that there is at most one unique reference taken to this decoration site. - else - (if length(lookupLocalTransUniqueRefs(fName, q.attrDcl.fullName, top.flowEnv)) > 1 - then [errFromOrigin(top, s"Multiple unique references taken to ${top.unparse} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}).")] - -- Check that there isn't also a unique reference taken to e - else []) ++ - case lookupLocalUniqueRefs(fName, top.flowEnv) of - | u :: _ -> - [errFromOrigin(top, s"Cannot take a unique reference to ${top.unparse} in production ${top.frame.fullName} (reference has type ${prettyType(top.finalType)}) since there is also a unique reference taken to ${e.unparse} at ${u.sourceGrammar}:${u.sourceLocation.unparse}.")] - | [] -> [] - end - | _ -> [errFromOrigin(top, s"Cannot take a unique reference (of type ${prettyType(top.finalType)}) to ${top.unparse}")] - end - | _ -> [] - end; -} -aspect production annoAccessHandler -top::Expr ::= @e::Expr @q::QNameAttrOccur -{ - top.uniqueRefs := e.accessUniqueRefs; -} -aspect production synDataAccessHandler -top::Expr ::= @e::Expr @q::QNameAttrOccur -{ - top.uniqueRefs := e.accessUniqueRefs; -} -aspect production inhUndecoratedAccessErrorHandler -top::Expr ::= @e::Expr @q::QNameAttrOccur -{ - top.uniqueRefs := e.accessUniqueRefs; -} -aspect production transUndecoratedAccessErrorHandler -top::Expr ::= @e::Expr @q::QNameAttrOccur -{ - top.uniqueRefs := e.accessUniqueRefs; -} -aspect production unknownDclAccessHandler -top::Expr ::= @e::Expr @q::QNameAttrOccur -{ - top.uniqueRefs := e.accessUniqueRefs; + -- TODO: Handle signature sharing } aspect production ifThenElse top::Expr ::= 'if' e1::Expr 'then' e2::Expr 'else' e3::Expr { - top.uniqueRefs := - e1.uniqueRefs ++ - unionMutuallyExclusiveRefs(e1.uniqueRefs, e2.uniqueRefs); -} - -aspect production lambdaParamReference -top::Expr ::= @q::QName -{ - top.uniqueRefs <- - if top.finalType.isUniqueDecorated - then [(q.name, uniqueRefSite( - refSet=top.finalType.inhSetMembers, - refFlowDeps=top.flowDeps, - sourceGrammar=top.grammarName, - sourceLocation=q.nameLoc - ))] - else []; - top.accessUniqueRefs = []; + top.sharedRefs := + e1.sharedRefs ++ + unionMutuallyExclusiveRefs(e1.sharedRefs, e2.sharedRefs); } -aspect production lambdap -top::Expr ::= params::LambdaRHS e::Expr -{ - top.uniqueRefs := filter(\ r::(String, UniqueRefSite) -> !contains(r.1, params.lambdaBoundVars), e.uniqueRefs); - top.errors <- flatMap(\ n::String -> - let rs::[UniqueRefSite] = lookupAll(n, e.uniqueRefs) - in - if length(rs) > 1 - then map(err(_, s"Multiple uses of unique reference lambda parameter ${n}"), map((.sourceLocation), rs)) - else [] - end, - params.lambdaBoundVars); -} - -aspect production lexicalLocalReference -top::Expr ::= @q::QName fi::Maybe fd::[FlowVertex] rs::[(String, UniqueRefSite)] -{ - top.errors <- - -- This check is needed due to how we handle let binding auto-undecoration in the type system: - -- unique and regular references can both undecorate and unique references can become regular ones, - -- but ensure that we don't create a unique reference out of a regular one. - case top.finalType, q.lookupValue.typeScheme.monoType of - | uniqueDecoratedType(_, _), uniqueDecoratedType(_, _) -> [] - | uniqueDecoratedType(_, _), _ -> - [errFromOrigin(top, s"${q.name} was not bound as a unique reference, but here it is used with type ${prettyType(top.finalType)}.")] - | _, _ -> [] - end; - - top.uniqueRefs <- rs; - top.accessUniqueRefs = []; -} - -aspect production letp -top::Expr ::= la::AssignExpr e::Expr -{ - -- Excluding refs from la, they flow up through the lexicalLocalReferences in e - top.uniqueRefs := e.uniqueRefs; -} aspect production matchPrimitiveReal top::Expr ::= e::Expr t::TypeExpr pr::PrimPatterns f::Expr { - top.uniqueRefs := e.uniqueRefs ++ unionMutuallyExclusiveRefs(pr.uniqueRefs, f.uniqueRefs); - top.errors <- uniqueContextErrors(e.uniqueRefs); + top.sharedRefs := e.sharedRefs ++ unionMutuallyExclusiveRefs(pr.sharedRefs, f.sharedRefs); } aspect production consPattern top::PrimPatterns ::= p::PrimPattern _ ps::PrimPatterns { - top.uniqueRefs := unionMutuallyExclusiveRefs(p.uniqueRefs, ps.uniqueRefs); + top.sharedRefs := unionMutuallyExclusiveRefs(p.sharedRefs, ps.sharedRefs); } diff --git a/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv b/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv deleted file mode 100644 index d412f92c9..000000000 --- a/grammars/silver/compiler/analysis/uniqueness/ProductionBody.sv +++ /dev/null @@ -1,99 +0,0 @@ -grammar silver:compiler:analysis:uniqueness; - -attribute uniqueRefs occurs on ProductionBody, ProductionStmts, ProductionStmt; -propagate uniqueRefs on ProductionBody, ProductionStmts, ProductionStmt; - -aspect production attachNoteStmt -top::ProductionStmt ::= 'attachNote' note::Expr ';' -{ - top.errors <- uniqueContextErrors(note.uniqueRefs); -} -aspect production forwardInh -top::ForwardInh ::= lhs::ForwardLHSExpr '=' e::Expr ';' -{ - top.errors <- uniqueContextErrors(e.uniqueRefs); -} -aspect production returnDef -top::ProductionStmt ::= 'return' e::Expr ';' -{ - top.errors <- - if any(map((.isUniqueDecorated), top.frame.signature.inputTypes)) then [] - else map(\ r::(String, UniqueRefSite) -> err(r.2.sourceLocation, - s"Unique reference to ${r.1} taken outside of a unique context. " ++ - s"The return of ${top.frame.fullName} is not a unique context as this function has no unique parameters."), - e.uniqueRefs); -} -aspect production synthesizedAttributeDef -top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr -{ - top.errors <- - if !attr.found || attr.attrDcl.isTranslation then [] - else uniqueContextErrors(e.uniqueRefs); -} -aspect production inheritedAttributeDef -top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr -{ - top.errors <- uniqueContextErrors(e.uniqueRefs); -} - --- Modifications -aspect production synAppendColAttributeDef -top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur {- <- -} e::Expr -{ - top.errors <- uniqueContextErrors(e.uniqueRefs); -} -aspect production inhAppendColAttributeDef -top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur {- <- -} e::Expr -{ - top.errors <- uniqueContextErrors(e.uniqueRefs); -} -aspect production synBaseColAttributeDef -top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr -{ - top.errors <- uniqueContextErrors(e.uniqueRefs); -} -aspect production inhBaseColAttributeDef -top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr -{ - top.errors <- uniqueContextErrors(e.uniqueRefs); -} -aspect production appendCollectionValueDef -top::ProductionStmt ::= @val::QName e::Expr -{ - top.errors <- uniqueContextErrors(e.uniqueRefs); -} -aspect production pluckDef -top::ProductionStmt ::= 'pluck' e::Expr ';' -{ - top.errors <- uniqueContextErrors(e.uniqueRefs); -} -aspect production printStmt -top::ProductionStmt ::= 'print' e::Expr ';' -{ - top.errors <- uniqueContextErrors(e.uniqueRefs); -} -aspect production parserAttributeValueDef -top::ProductionStmt ::= @val::QName e::Expr -{ - top.errors <- uniqueContextErrors(e.uniqueRefs); -} -aspect production pushTokenStmt -top::ProductionStmt ::= 'pushToken' '(' val::QName ',' lexeme::Expr ')' ';' -{ - top.errors <- uniqueContextErrors(lexeme.uniqueRefs); -} -aspect production insertSemanticTokenStmt -top::ProductionStmt ::= 'insert' 'semantic' 'token' n::QNameType 'at' loc::Expr ';' -{ - top.errors <- uniqueContextErrors(loc.uniqueRefs); -} -aspect production ifElseStmt -top::ProductionStmt ::= 'if' '(' condition::Expr ')' th::ProductionStmt 'else' el::ProductionStmt -{ - top.errors <- uniqueContextErrors(condition.uniqueRefs); -} -aspect production termAttrValueValueDef -top::ProductionStmt ::= @val::QName e::Expr -{ - top.errors <- uniqueContextErrors(e.uniqueRefs); -} diff --git a/grammars/silver/compiler/analysis/uniqueness/RootSpec.sv b/grammars/silver/compiler/analysis/uniqueness/RootSpec.sv index c3e45ce3d..0cea36687 100644 --- a/grammars/silver/compiler/analysis/uniqueness/RootSpec.sv +++ b/grammars/silver/compiler/analysis/uniqueness/RootSpec.sv @@ -1,35 +1,35 @@ grammar silver:compiler:analysis:uniqueness; -monoid attribute hasUniqueRefs::Boolean with false, ||; +monoid attribute hasSharedRefs::Boolean with false, ||; -attribute uniqueRefs, hasUniqueRefs occurs on InterfaceItems, InterfaceItem; -propagate uniqueRefs, hasUniqueRefs on InterfaceItems, InterfaceItem; +attribute sharedRefs, hasSharedRefs occurs on InterfaceItems, InterfaceItem; +propagate sharedRefs, hasSharedRefs on InterfaceItems, InterfaceItem; aspect production consInterfaceItem top::InterfaceItems ::= h::InterfaceItem t::InterfaceItems { - top.interfaceErrors <- if !top.hasUniqueRefs then ["Missing item uniqueRefs"] else []; + top.interfaceErrors <- if !top.hasSharedRefs then ["Missing item sharedRefs"] else []; } aspect default production top::InterfaceItem ::= { - propagate uniqueRefs, hasUniqueRefs; + propagate sharedRefs, hasSharedRefs; } -abstract production uniqueRefs -top::InterfaceItem ::= val::[(String, UniqueRefSite)] +abstract production sharedRefs +top::InterfaceItem ::= val::[(String, SharedRefSite)] { propagate isEqual; - top.uniqueRefs <- val; - top.hasUniqueRefs <- true; + top.sharedRefs <- val; + top.hasSharedRefs <- true; } aspect function packInterfaceItems InterfaceItems ::= r::Decorated RootSpec { - interfaceItems <- [uniqueRefs(r.uniqueRefs)]; + interfaceItems <- [sharedRefs(r.sharedRefs)]; } -attribute uniqueRefs occurs on RootSpec; -propagate uniqueRefs on RootSpec; +attribute sharedRefs occurs on RootSpec; +propagate sharedRefs on RootSpec; diff --git a/grammars/silver/compiler/analysis/uniqueness/SharedRefSite.sv b/grammars/silver/compiler/analysis/uniqueness/SharedRefSite.sv new file mode 100644 index 000000000..6b85a5b4f --- /dev/null +++ b/grammars/silver/compiler/analysis/uniqueness/SharedRefSite.sv @@ -0,0 +1,29 @@ +grammar silver:compiler:analysis:uniqueness; + +-- Shared references taken in this tree +monoid attribute sharedRefs::[(String, SharedRefSite)]; + +attribute sharedRefs occurs on + Grammar, Root, AGDcls, AGDcl, + ProductionBody, ProductionStmts, ProductionStmt; +propagate sharedRefs on + Grammar, Root, AGDcls, AGDcl, + ProductionBody, ProductionStmts, ProductionStmt; + +{-- + - Represents taking of a shared reference to a child or local/production attribute, + - to catch a tree being shared in multiple places. + -} +data SharedRefSite = sharedRefSite with + sourceGrammar, -- The grammar of where the reference was taken + sourceLocation; -- The location of where the reference was taken + +-- Append lists of references, ignoring duplicate refs to the same ref site +fun unionMutuallyExclusiveRefs +[(String, SharedRefSite)] ::= rs1::[(String, SharedRefSite)] rs2::[(String, SharedRefSite)] = + rs1 ++ filter(\ r::(String, SharedRefSite) -> !lookup(r.1, rs1).isJust, rs2); + +-- We don't care about the locations for correctness, don't compare it to avoid touching interface files. +instance Eq SharedRefSite { + eq = \ s1::SharedRefSite s2::SharedRefSite -> s1.sourceGrammar == s2.sourceGrammar; +} diff --git a/grammars/silver/compiler/analysis/uniqueness/UniqueRefSite.sv b/grammars/silver/compiler/analysis/uniqueness/UniqueRefSite.sv deleted file mode 100644 index f0cbe5b2b..000000000 --- a/grammars/silver/compiler/analysis/uniqueness/UniqueRefSite.sv +++ /dev/null @@ -1,38 +0,0 @@ -grammar silver:compiler:analysis:uniqueness; - --- Unique references taken in this tree -monoid attribute uniqueRefs::[(String, UniqueRefSite)]; - -{-- - - Represents taking of a unique reference to a child or local/production attribute. - - Since taking a unique reference means that inherited equations - - on the decoration site for attributes not in the reference set are forbidden, - - this info tracks what decoration sites have partial references taken. - -} -nonterminal UniqueRefSite with refSet, refFlowDeps, - sourceGrammar, -- The grammar of where the reference was taken - sourceLocation; -- The location of where the reference was taken - --- The attributes in the type of the taken reference -annotation refSet::[String]; - --- The flow dependencies of taking this reference -annotation refFlowDeps::[FlowVertex]; - -abstract production uniqueRefSite -top::UniqueRefSite ::= -{} - --- Append lists of references, ignoring duplicate refs to the same ref site -fun unionMutuallyExclusiveRefs -[(String, UniqueRefSite)] ::= rs1::[(String, UniqueRefSite)] rs2::[(String, UniqueRefSite)] = - rs1 ++ filter(\ r::(String, UniqueRefSite) -> !lookup(r.1, rs1).isJust, rs2); - --- Compare unique ref sites based on ref set. --- Source location doesn't matter, and we should never be comparing unique ref sites from different grammars. -instance Eq UniqueRefSite { - eq = \ r1::UniqueRefSite r2::UniqueRefSite -> r1.refSet == r2.refSet; -} - -global uniqueContextErrors::([Message] ::= [(String, UniqueRefSite)]) = - map(\ r::(String, UniqueRefSite) -> err(r.2.sourceLocation, s"Unique reference to ${r.1} taken outside of a unique context."), _); diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index c660a8a44..b175740f4 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -120,9 +120,10 @@ function checkEqDeps | rhsInhVertex(sigName, attrName) -> if !null(lookupInh(prodName, sigName, attrName, flowEnv)) || sigAttrViaReference(sigName, attrName, ns, realEnv) - || !null(lookupRefDecSite(prodName, sigName, flowEnv)) + || !null(lookupRefDecSite(prodName, rhsVertexType(sigName), flowEnv)) || case splitTransAttrInh(attrName) of - | just((transAttr, _)) -> !null(lookupTransRefDecSite(prodName, sigName, transAttr, flowEnv)) + | just((transAttr, _)) -> + !null(lookupRefDecSite(prodName, transAttrVertexType(rhsVertexType(sigName), transAttr), flowEnv)) | nothing() -> false end then [] @@ -138,9 +139,10 @@ function checkEqDeps if !null(lookupLocalInh(prodName, fName, attrName, flowEnv)) || fName == "forward" || localAttrViaReference(fName, attrName, realEnv) - || !null(lookupLocalRefDecSite(fName, flowEnv)) + || !null(lookupRefDecSite(prodName, localVertexType(fName), flowEnv)) || case splitTransAttrInh(attrName) of - | just((transAttr, _)) -> !null(lookupLocalTransRefDecSite(fName, transAttr, flowEnv)) + | just((transAttr, _)) -> + !null(lookupRefDecSite(prodName, transAttrVertexType(localVertexType(fName), transAttr), flowEnv)) | nothing() -> isForwardProdAttr(fName, realEnv) -- Inh on trans are not copied with forwarding end then [] @@ -277,14 +279,39 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr lhsInhDeps, inhDepsForSyn("forward", top.frame.lhsNtName, myFlow)))); + -- Make sure we aren't introducing any hidden transitive dependencies. + local refDecSiteInhDepsLhsInh :: Maybe> = - map(\ deps::[FlowVertex] -> onlyLhsInh(expandGraph(deps, top.frame.flowGraph)), dl.refDecSiteInhDeps); + case lookupRefPossibleDecSites(top.frame.fullName, dl.defLHSVertex, top.flowEnv) of + | [] -> nothing() + | vs -> just(onlyLhsInh(expandGraph( + dl.defLHSVertex.eqVertex ++ + map(\ v::VertexType -> v.inhVertex(attr.attrDcl.fullName), vs), + top.frame.flowGraph))) + end; + + local transBaseRefDecSiteInhDepsLhsInh :: Maybe> = + case dl.defLHSVertex of + | transAttrVertexType(v, transAttr) -> + case lookupRefPossibleDecSites(top.frame.fullName, v, top.flowEnv) of + | [] -> nothing() + | vs -> just(onlyLhsInh(expandGraph( + v.eqVertex ++ + map(\ v::VertexType -> v.inhVertex(transAttr ++ "." ++ attr.attrDcl.fullName), vs), + top.frame.flowGraph))) + end + | _ -> nothing() + end; -- problem = lhsinh deps - inh deps on dec site local lhsInhExceedsRefDecSiteDeps :: [String] = case refDecSiteInhDepsLhsInh of - -- A unique reference is taken that doesn't include this attribute, - -- make sure we aren't introducing any hidden transitive dependencies. + | just(deps) -> set:toList(set:difference(lhsInhDeps, deps)) + | _ -> [] + end; + + local lhsInhExceedsTransBaseRefDecSiteDeps :: [String] = + case transBaseRefDecSiteInhDepsLhsInh of | just(deps) -> set:toList(set:difference(lhsInhDeps, deps)) | _ -> [] end; @@ -298,104 +325,23 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr then [mwdaWrnFromOrigin(top, "Forward inherited equation exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsForwardFlowType))] else []; top.errors <- - case dl.lhsUniqueRefs of - | u :: _ when top.config.warnMissingInh && !null(lhsInhExceedsRefDecSiteDeps) -> + if top.config.warnMissingInh && !null(lhsInhExceedsRefDecSiteDeps) + then [mwdaWrnFromOrigin(top, s"Inherited override equation may exceed a flow type with hidden transitive dependencies on ${implode(", ", lhsInhExceedsRefDecSiteDeps)}; " ++ - s"${attr.attrDcl.fullName} on the reference taken at ${u.sourceGrammar}:${u.sourceLocation.unparse} may be expected to depend only on ${implode(", ", set:toList(refDecSiteInhDepsLhsInh.fromJust))}")] + s"${attr.attrDcl.fullName} on some reference to ${dl.defLHSVertex.vertexName} may be expected to depend only on ${implode(", ", set:toList(refDecSiteInhDepsLhsInh.fromJust))}")] + else []; + top.errors <- + case dl.defLHSVertex of + | transAttrVertexType(v, transAttr) + when top.config.warnMissingInh && !null(lhsInhExceedsTransBaseRefDecSiteDeps) -> + [mwdaWrnFromOrigin(top, + s"Inherited override equation may exceed a flow type with hidden transitive dependencies on ${implode(", ", lhsInhExceedsTransBaseRefDecSiteDeps)}; " ++ + s"${transAttr}.${attr.attrDcl.fullName} on some reference to ${v.vertexName} may be expected to depend only on ${implode(", ", set:toList(transBaseRefDecSiteInhDepsLhsInh.fromJust))}")] | _ -> [] end; } --- All unique references to the LHS's decoration site -synthesized attribute lhsUniqueRefs::[UniqueRefSite] occurs on DefLHS; - --- Minimum flow deps of this inherited attribute on any unique references to this decoration site -synthesized attribute refDecSiteInhDeps::Maybe<[FlowVertex]> occurs on DefLHS; - -flowtype DefLHS = lhsUniqueRefs {grammarName, config, frame, env, flowEnv}, refDecSiteInhDeps {grammarName, config, frame, env, flowEnv, defLHSattr}; - -aspect default production -top::DefLHS ::= -{ - top.lhsUniqueRefs = []; - top.refDecSiteInhDeps = nothing(); -} -aspect production childDefLHS -top::DefLHS ::= @q::QName -{ - top.lhsUniqueRefs = lookupUniqueRefs(top.frame.fullName, q.lookupValue.fullName, top.flowEnv); - top.refDecSiteInhDeps = - case top.lhsUniqueRefs of - | u :: _ when !contains(top.inhAttrName, u.refSet) -> just( - u.refFlowDeps ++ - map( - \ v::VertexType -> v.inhVertex(top.inhAttrName), - lookupRefPossibleDecSites(top.frame.fullName, q.lookupValue.fullName, top.flowEnv))) - | _ -> nothing() - end; -} -aspect production localDefLHS -top::DefLHS ::= @q::QName -{ - top.lhsUniqueRefs = lookupLocalUniqueRefs(q.lookupValue.fullName, top.flowEnv); - top.refDecSiteInhDeps = - case top.lhsUniqueRefs of - | u :: _ when !contains(top.inhAttrName, u.refSet) -> just( - u.refFlowDeps ++ - map( - \ v::VertexType -> v.inhVertex(top.inhAttrName), - lookupLocalRefPossibleDecSites(q.lookupValue.fullName, top.flowEnv))) - | _ -> nothing() - end; -} -aspect production childTransAttrDefLHS -top::DefLHS ::= @q::QName @attr::QNameAttrOccur -{ - local childUniqueRefs::[UniqueRefSite] = - lookupUniqueRefs(top.frame.fullName, q.lookupValue.fullName, top.flowEnv); - local childTransAttrUniqueRefs::[UniqueRefSite] = - lookupTransUniqueRefs(top.frame.fullName, q.lookupValue.fullName, attr.attrDcl.fullName, top.flowEnv); - top.lhsUniqueRefs = if !null(childUniqueRefs) then childUniqueRefs else childTransAttrUniqueRefs; - top.refDecSiteInhDeps = - case childUniqueRefs, childTransAttrUniqueRefs of - | u :: _, _ when !contains(top.inhAttrName, u.refSet) -> just( - u.refFlowDeps ++ - map( - \ v::VertexType -> v.inhVertex(top.inhAttrName), - lookupRefPossibleDecSites(top.frame.fullName, q.lookupValue.fullName, top.flowEnv))) - | _, u :: _ when !contains(top.defLHSattr.attrDcl.fullName, u.refSet) -> just( - u.refFlowDeps ++ - map( - \ v::VertexType -> v.inhVertex(top.defLHSattr.attrDcl.fullName), - lookupTransRefPossibleDecSites(top.frame.fullName, q.lookupValue.fullName, attr.attrDcl.fullName, top.flowEnv))) - | _, _ -> nothing() - end; -} -aspect production localTransAttrDefLHS -top::DefLHS ::= @q::QName @attr::QNameAttrOccur -{ - local localUniqueRefs::[UniqueRefSite] = - lookupUniqueRefs(top.frame.fullName, q.lookupValue.fullName, top.flowEnv); - local localTransAttrUniqueRefs::[UniqueRefSite] = - lookupTransUniqueRefs(top.frame.fullName, q.lookupValue.fullName, attr.attrDcl.fullName, top.flowEnv); - top.lhsUniqueRefs = if !null(localUniqueRefs) then localUniqueRefs else localTransAttrUniqueRefs; - top.refDecSiteInhDeps = - case localUniqueRefs, localTransAttrUniqueRefs of - | u :: _, _ when !contains(top.inhAttrName, u.refSet) -> just( - u.refFlowDeps ++ - map( - \ v::VertexType -> v.inhVertex(top.inhAttrName), - lookupLocalRefPossibleDecSites(q.lookupValue.fullName, top.flowEnv))) - | _, u :: _ when !contains(top.defLHSattr.attrDcl.fullName, u.refSet) -> just( - u.refFlowDeps ++ - map( - \ v::VertexType -> v.inhVertex(top.defLHSattr.attrDcl.fullName), - lookupLocalTransRefPossibleDecSites(q.lookupValue.fullName, attr.attrDcl.fullName, top.flowEnv))) - | _, _ -> nothing() - end; -} - ----- WARNING TODO BEGIN MASSIVE COPY & PASTE SESSION aspect production synBaseColAttributeDef top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr @@ -617,7 +563,7 @@ Step 2: Let's go check on expressions. This has two purposes: aspect production childReference top::Expr ::= @q::QName { - top.errors <- + top.errors <- if top.config.warnMissingInh && isDecorable(q.lookupValue.typeScheme.typerep, top.env) then if refSet.isJust then [] @@ -627,7 +573,7 @@ top::Expr ::= @q::QName aspect production lhsReference top::Expr ::= @q::QName { - top.errors <- + top.errors <- if top.config.warnMissingInh then if refSet.isJust then [] else [mwdaWrnFromOrigin(top, s"Cannot take a reference of type ${prettyType(top.finalType)}, as the reference set is not bounded.")] @@ -636,7 +582,7 @@ top::Expr ::= @q::QName aspect production localReference top::Expr ::= @q::QName { - top.errors <- + top.errors <- if top.config.warnMissingInh && isDecorable(q.lookupValue.typeScheme.typerep, top.env) then if refSet.isJust then [] @@ -646,7 +592,7 @@ top::Expr ::= @q::QName aspect production forwardReference top::Expr ::= @q::QName { - top.errors <- + top.errors <- if top.config.warnMissingInh then if refSet.isJust then [] else [mwdaWrnFromOrigin(top, s"Cannot take a reference of type ${prettyType(top.finalType)}, as the reference set is not bounded.")] @@ -717,13 +663,14 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur case e of | childReference(lq) -> if isDecorable(lq.lookupValue.typeScheme.typerep, top.env) && - null(lookupRefDecSite(top.frame.fullName, lq.lookupValue.fullName, top.flowEnv)) -- Decoration site projection, covered by checkAllEqDeps + null(lookupRefDecSite(top.frame.fullName, rhsVertexType(lq.lookupValue.fullName), top.flowEnv)) -- Decoration site projection, covered by checkAllEqDeps then let inhs :: [String] = filter(\ attr::String -> case splitTransAttrInh(attr) of -- If the dep is for an inh on a trans attribute, check for a decoration site projection for the trans attribute - | just((transAttr, _)) -> null(lookupTransRefDecSite(top.frame.fullName, lq.lookupValue.fullName, transAttr, top.flowEnv)) + | just((transAttr, _)) -> + null(lookupRefDecSite(top.frame.fullName, transAttrVertexType(rhsVertexType(lq.lookupValue.fullName), transAttr), top.flowEnv)) | _ -> true end, filter( @@ -738,13 +685,14 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur else [] | localReference(lq) -> if isDecorable(lq.lookupValue.typeScheme.typerep, top.env) && - null(lookupLocalRefDecSite(lq.lookupValue.fullName, top.flowEnv)) -- Decoration site projection, covered by checkAllEqDeps + null(lookupRefDecSite(top.frame.fullName, localVertexType(lq.lookupValue.fullName), top.flowEnv)) -- Decoration site projection, covered by checkAllEqDeps then let inhs :: [String] = filter(\ attr::String -> case splitTransAttrInh(attr) of -- If the dep is for an inh on a trans attribute, check for a decoration site projection for the trans attribute - | just((transAttr, _)) -> null(lookupLocalTransRefDecSite(lq.lookupValue.fullName, transAttr, top.flowEnv)) + | just((transAttr, _)) -> + null(lookupRefDecSite(top.frame.fullName, transAttrVertexType(localVertexType(lq.lookupValue.fullName), transAttr), top.flowEnv)) -- If the dep is for a normal inh attribute, ignore if the local is a forward production attribute | nothing() -> !lq.lookupValue.dcl.hasForward end, @@ -856,13 +804,14 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur case e of | childReference(lq) -> if isDecorable(lq.lookupValue.typeScheme.typerep, top.env) && - null(lookupRefDecSite(top.frame.fullName, lq.lookupValue.fullName, top.flowEnv)) -- Decoration site projection, covered by checkAllEqDeps + null(lookupRefDecSite(top.frame.fullName, rhsVertexType(lq.lookupValue.fullName), top.flowEnv)) -- Decoration site projection, covered by checkAllEqDeps then let inhs :: [String] = filter(\ attr::String -> case splitTransAttrInh(attr) of -- If the dep is for an inh on a trans attribute, check for a decoration site projection for the trans attribute - | just((transAttr, _)) -> null(lookupTransRefDecSite(top.frame.fullName, lq.lookupValue.fullName, transAttr, top.flowEnv)) + | just((transAttr, _)) -> + null(lookupRefDecSite(top.frame.fullName, transAttrVertexType(rhsVertexType(lq.lookupValue.fullName), transAttr), top.flowEnv)) | _ -> true end, filter( @@ -877,13 +826,14 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur else [] | localReference(lq) -> if isDecorable(lq.lookupValue.typeScheme.typerep, top.env) && - null(lookupLocalRefDecSite(lq.lookupValue.fullName, top.flowEnv)) -- Decoration site projection, covered by checkAllEqDeps + null(lookupRefDecSite(top.frame.fullName, localVertexType(lq.lookupValue.fullName), top.flowEnv)) -- Decoration site projection, covered by checkAllEqDeps then let inhs :: [String] = filter(\ attr::String -> case splitTransAttrInh(attr) of -- If the dep is for an inh on a trans attribute, check for a decoration site projection for the trans attribute - | just((transAttr, _)) -> null(lookupLocalTransRefDecSite(lq.lookupValue.fullName, transAttr, top.flowEnv)) + | just((transAttr, _)) -> + null(lookupRefDecSite(top.frame.fullName, transAttrVertexType(localVertexType(lq.lookupValue.fullName), transAttr), top.flowEnv)) -- If the dep is for a normal inh attribute, ignore if the local is a forward production attribute | nothing() -> !lq.lookupValue.dcl.hasForward end, @@ -997,20 +947,9 @@ Boolean ::= prodName::String sigName::String attrName::String flowEnv::FlowEn fun lookupAllDecSites [(String, VertexType)] ::= prodName::String vt::VertexType flowEnv::FlowEnv = (prodName, vt) :: case vt of - | lhsVertexType_real() -> [] - | rhsVertexType(sigName) -> - flatMap(lookupAllDecSites(prodName, _, flowEnv), lookupRefDecSite(prodName, sigName, flowEnv)) - | localVertexType(fName) -> - flatMap(lookupAllDecSites(prodName, _, flowEnv), lookupLocalRefDecSite(fName, flowEnv)) - | transAttrVertexType(rhsVertexType(sigName), transAttr) -> - flatMap(lookupAllDecSites(prodName, _, flowEnv), lookupTransRefDecSite(prodName, sigName, transAttr, flowEnv)) - | transAttrVertexType(localVertexType(fName), transAttr) -> - flatMap(lookupAllDecSites(prodName, _, flowEnv), lookupLocalTransRefDecSite(fName, transAttr, flowEnv)) - | transAttrVertexType(_, _) -> [] - | anonVertexType(fName) -> [] - | forwardVertexType_real() -> [] | subtermVertexType(_, remoteProdName, sigName) -> lookupAllDecSites(remoteProdName, rhsVertexType(sigName), flowEnv) + | _ -> flatMap(lookupAllDecSites(prodName, _, flowEnv), lookupRefDecSite(prodName, vt, flowEnv)) end; fun vertexHasInhEq Boolean ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv = diff --git a/grammars/silver/compiler/analysis/warnings/flow/MWDA.sv b/grammars/silver/compiler/analysis/warnings/flow/MWDA.sv index 710e9a645..9d552b53d 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/MWDA.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/MWDA.sv @@ -32,13 +32,6 @@ imports silver:compiler:modification:defaultattr; imports silver:compiler:modification:primitivepattern; imports silver:compiler:modification:copper only parserAttributeDefLHS; -fun isForwardProdAttr Boolean ::= a::String e::Env = - case getValueDclAll(a, e) of - | d :: _ -> d.hasForward - | _ -> false - end; - - -- TODO: better way of generating warnings. We ad-hoc check for errors before -- raising these warnings, but this is inherently fragile and results in crash diff --git a/grammars/silver/compiler/definition/core/ProductionBody.sv b/grammars/silver/compiler/definition/core/ProductionBody.sv index 9aea06ada..0f26990b6 100644 --- a/grammars/silver/compiler/definition/core/ProductionBody.sv +++ b/grammars/silver/compiler/definition/core/ProductionBody.sv @@ -512,7 +512,7 @@ top::DefLHS ::= @q::QName @attr::QNameAttrOccur local ty::Type = q.lookupValue.typeScheme.monoType; top.errors <- - if attr.found && !ty.isNonterminal && !ty.isUniqueDecorated + if attr.found && !ty.isNonterminal then [errFromOrigin(q, s"Inherited equations on translation attributes on child ${q.name} of type ${prettyType(new(ty))} are not supported")] else []; @@ -536,7 +536,7 @@ top::DefLHS ::= @q::QName @attr::QNameAttrOccur local ty::Type = q.lookupValue.typeScheme.monoType; top.errors <- - if attr.found && !ty.isNonterminal && !ty.isUniqueDecorated + if attr.found && !ty.isNonterminal then [errFromOrigin(q, s"Inherited equations on translation attributes on local ${q.name} of type ${prettyType(new(ty))} are not supported")] else []; diff --git a/grammars/silver/compiler/definition/core/Type.sv b/grammars/silver/compiler/definition/core/Type.sv index 83bd2799e..82e56a17b 100644 --- a/grammars/silver/compiler/definition/core/Type.sv +++ b/grammars/silver/compiler/definition/core/Type.sv @@ -46,12 +46,6 @@ top::Type ::= te::Type _ top.accessHandler = decoratedAccessHandler; } -aspect production uniqueDecoratedType -top::Type ::= te::Type _ -{ - top.accessHandler = decoratedAccessHandler; -} - aspect production functionType top::Type ::= _ _ { diff --git a/grammars/silver/compiler/definition/env/Context.sv b/grammars/silver/compiler/definition/env/Context.sv index 307276321..736bb11ac 100644 --- a/grammars/silver/compiler/definition/env/Context.sv +++ b/grammars/silver/compiler/definition/env/Context.sv @@ -262,8 +262,6 @@ Boolean ::= a::Type b::Type (isMoreSpecific(c1, c2) || isMoreSpecific(a1, a2)) && !(isMoreSpecific(c2, c1) || isMoreSpecific(a2, a1)) | decoratedType(t1, i1), decoratedType(t2, i2) -> (isMoreSpecific(t1, t2) || isMoreSpecific(i1, i2)) && !(isMoreSpecific(t2, t1) || isMoreSpecific(i2, i1)) - | uniqueDecoratedType(t1, i1), uniqueDecoratedType(t2, i2) -> - (isMoreSpecific(t1, t2) || isMoreSpecific(i1, i2)) && !(isMoreSpecific(t2, t1) || isMoreSpecific(i2, i1)) | _, _ -> false end; } diff --git a/grammars/silver/compiler/definition/env/Env.sv b/grammars/silver/compiler/definition/env/Env.sv index e243134a0..ee5da3f06 100644 --- a/grammars/silver/compiler/definition/env/Env.sv +++ b/grammars/silver/compiler/definition/env/Env.sv @@ -176,7 +176,6 @@ Boolean ::= t::Type e::Env case t of | skolemType(_) -> !null(searchEnvTree(t.typeName, e.occursTree)) | varType(_) -> !null(searchEnvTree(t.typeName, e.occursTree)) -- Can happen when pattern matching on a prod with occurs contexts - | uniqueDecoratedType(nt, _) -> isDecorable(nt, e) | _ -> t.isNonterminal && !t.isData end; } @@ -306,7 +305,6 @@ function getMinRefSet return case t of | decoratedType(_, i) -> getMinInhSetMembers([], i, e).fst - | uniqueDecoratedType(_, i) -> getMinInhSetMembers([], i, e).fst | _ -> [] end; } @@ -341,7 +339,12 @@ Maybe<[String]> ::= t::Type e::Env return case t of | decoratedType(_, i) -> getMaxInhSetMembers([], i, e).fst - | uniqueDecoratedType(_, i) -> getMaxInhSetMembers([], i, e).fst | _ -> just([]) end; } + +fun isForwardProdAttr Boolean ::= a::String e::Env = + case getValueDclAll(a, e) of + | d :: _ -> d.hasForward + | _ -> false + end; diff --git a/grammars/silver/compiler/definition/env/Type.sv b/grammars/silver/compiler/definition/env/Type.sv index c5a81b6ff..897ac7ede 100644 --- a/grammars/silver/compiler/definition/env/Type.sv +++ b/grammars/silver/compiler/definition/env/Type.sv @@ -57,12 +57,6 @@ top::Type ::= te::Type _ top.typeName = te.typeName; } -aspect production uniqueDecoratedType -top::Type ::= te::Type _ -{ - top.typeName = te.typeName; -} - aspect production varType top::Type ::= tv::TyVar { diff --git a/grammars/silver/compiler/definition/flow/ast/Flow.sv b/grammars/silver/compiler/definition/flow/ast/Flow.sv index bb4d884c6..fc6c1dd84 100644 --- a/grammars/silver/compiler/definition/flow/ast/Flow.sv +++ b/grammars/silver/compiler/definition/flow/ast/Flow.sv @@ -52,13 +52,13 @@ monoid attribute prodGraphContribs :: [Pair]; {-- Edge lists from equations - ONLY used to extract edges for a production graph from production-internal flowDefs. -} -synthesized attribute flowEdges :: [Pair]; +synthesized attribute flowEdges :: [(FlowVertex, FlowVertex)]; {-- Like flowEdges, but these edges originate from equations that are not - allowed to affect their OWN flow type. We must still track them because - they may affect others' flow types. - (e.g. extsyn = hostsyn; hostsyn = hostinh; need to reflect extsyn's dep on hostinh) -} -synthesized attribute suspectFlowEdges :: [Pair]; +synthesized attribute suspectFlowEdges :: [(FlowVertex, FlowVertex)]; {-- A list of extension syn attr occurrences, subject to ft lower bounds. -} monoid attribute hostSynTreeContribs :: [Pair]; @@ -169,7 +169,7 @@ top::FlowDef ::= prod::String attr::String deps::[FlowVertex] mayAffectFlowTy { top.synTreeContribs := [(crossnames(prod, attr), top)]; top.prodGraphContribs := [(prod, top)]; - local edges :: [Pair] = map(pair(fst=lhsSynVertex(attr), snd=_), deps); + local edges :: [(FlowVertex, FlowVertex)] = map(pair(fst=lhsSynVertex(attr), snd=_), deps); top.flowEdges = if mayAffectFlowType then edges else []; top.suspectFlowEdges = if mayAffectFlowType then [] else edges; } @@ -203,7 +203,7 @@ top::FlowDef ::= prod::String deps::[FlowVertex] mayAffectFlowType::Boolean { top.fwdTreeContribs := [(prod, top)]; top.prodGraphContribs := [(prod, top)]; - local edges :: [Pair] = map(pair(fst=forwardEqVertex(), snd=_), deps); + local edges :: [(FlowVertex, FlowVertex)] = map(pair(fst=forwardEqVertex(), snd=_), deps); top.flowEdges = if mayAffectFlowType then edges else []; top.suspectFlowEdges = if mayAffectFlowType then [] else edges; } @@ -324,7 +324,7 @@ abstract production extraEq top::FlowDef ::= prod::String src::FlowVertex deps::[FlowVertex] mayAffectFlowType::Boolean { top.prodGraphContribs := [(prod, top)]; - local edges :: [Pair] = map(pair(fst=src, snd=_), deps); + local edges :: [(FlowVertex, FlowVertex)] = map(pair(fst=src, snd=_), deps); top.flowEdges = if mayAffectFlowType then edges else []; top.suspectFlowEdges = if mayAffectFlowType then [] else edges; } @@ -411,76 +411,19 @@ top::FlowDef ::= prod::String parent::VertexType termProd::String sigName::St } {-- - - A unique reference to a child that is elsewhere decorated with additional inherited attributes. + - A tree that is elsewhere decorated with additional inherited attributes. - - @param prod the full name of the production - - @param sigName the name of the child - - @param alwaysDec is this decoration uncondtional (as opposed to e.g. a unique reference appearing in an if/else branch) + - @param ref the vertex type of the shared tree - @param decSite the vertex type that is supplying the attributes - - @param attrs the inherited attributes that are being supplied - -} -abstract production childRefDecSiteEq -top::FlowDef ::= prod::String sigName::String alwaysDec::Boolean decSite::VertexType attrs::[String] -{ - top.prodGraphContribs := [(prod, top)]; - top.flowEdges = map(\ attr::String -> (rhsInhVertex(sigName, attr), decSite.inhVertex(attr)), attrs); - top.refPossibleDecSiteContribs := [(s"${prod}:${sigName}", decSite)]; - top.refDecSiteContribs := if alwaysDec then top.refPossibleDecSiteContribs else []; -} - -{-- - - A unique reference to a local/production attribute that is elsewhere decorated with additional inherited attributes. - - - - @param prod the full name of the production - - @param fName the full name of the local/production attribute - @param alwaysDec is this decoration uncondtional (as opposed to e.g. a unique reference appearing in an if/else branch) - - @param decSite the vertex type that is supplying the attributes - - @param attrs the inherited attributes that are being supplied - -} -abstract production localRefDecSiteEq -top::FlowDef ::= prod::String fName::String alwaysDec::Boolean decSite::VertexType attrs::[String] -{ - top.prodGraphContribs := [(prod, top)]; - top.flowEdges = map(\ attr::String -> (localInhVertex(fName, attr), decSite.inhVertex(attr)), attrs); - top.refPossibleDecSiteContribs := [(fName, decSite)]; - top.refDecSiteContribs := if alwaysDec then top.refPossibleDecSiteContribs else []; -} - -{-- - - A unique reference to a translation attribute on a child that is elsewhere decorated with additional inherited attributes. - - - - @param prod the full name of the production - - @param sigName the name of the child - - @param transAttr the name of the translation attribute - - @param alwaysDec is this decoration uncondtional (as opposed to e.g. a unique reference appearing in an if/else branch) - - @param decSite the vertex type that is supplying the attributes - - @param attrs the inherited attributes that are being supplied - -} -abstract production childTransRefDecSiteEq -top::FlowDef ::= prod::String sigName::String transAttr::String alwaysDec::Boolean decSite::VertexType attrs::[String] -{ - top.prodGraphContribs := [(prod, top)]; - top.flowEdges = map(\ attr::String -> (rhsInhVertex(sigName, s"${transAttr}.${attr}"), decSite.inhVertex(attr)), attrs); - top.refPossibleDecSiteContribs := [(s"${prod}:${sigName}.${transAttr}", decSite)]; - top.refDecSiteContribs := if alwaysDec then top.refPossibleDecSiteContribs else []; -} - -{-- - - A unique reference to a translation attribute on a local/production attribute that is elsewhere decorated with additional inherited attributes. - - - - @param prod the full name of the production - - @param fName the full name of the local/production attribute - - @param transAttr the name of the translation attribute - - @param alwaysDec is this decoration uncondtional (as opposed to e.g. a unique reference appearing in an if/else branch) - - @param decSite the vertex type that is supplying the attributes - - @param attrs the inherited attributes that are being supplied -} -abstract production localTransRefDecSiteEq -top::FlowDef ::= prod::String fName::String transAttr::String alwaysDec::Boolean decSite::VertexType attrs::[String] +abstract production refDecSiteEq +top::FlowDef ::= prod::String nt::String ref::VertexType decSite::VertexType alwaysDec::Boolean { top.prodGraphContribs := [(prod, top)]; - top.flowEdges = map(\ attr::String -> (localInhVertex(fName, s"${transAttr}.${attr}"), decSite.inhVertex(attr)), attrs); - top.refPossibleDecSiteContribs := [(s"${fName}.${transAttr}", decSite)]; + top.flowEdges = []; -- Added as fixed edges duing flow graph computation, when we know all inh attributes on nt. + top.refPossibleDecSiteContribs := [(s"${prod}:${ref.vertexName}", decSite)]; top.refDecSiteContribs := if alwaysDec then top.refPossibleDecSiteContribs else []; } diff --git a/grammars/silver/compiler/definition/flow/ast/VertexType.sv b/grammars/silver/compiler/definition/flow/ast/VertexType.sv index 9407c855b..213a3e95c 100644 --- a/grammars/silver/compiler/definition/flow/ast/VertexType.sv +++ b/grammars/silver/compiler/definition/flow/ast/VertexType.sv @@ -81,7 +81,7 @@ top::VertexType ::= v::VertexType transAttr::String top.synVertex = \ attr::String -> v.synVertex(s"${transAttr}.${attr}"); top.inhVertex = \ attr::String -> v.inhVertex(s"${transAttr}.${attr}"); top.fwdVertex = v.synVertex(s"${transAttr}.forward"); - top.eqVertex = [v.synVertex(transAttr)]; + top.eqVertex = v.synVertex(transAttr) :: v.eqVertex; } {-- diff --git a/grammars/silver/compiler/definition/flow/driver/DumpGraph.sv b/grammars/silver/compiler/definition/flow/driver/DumpGraph.sv index ef1d85a30..0594e024e 100644 --- a/grammars/silver/compiler/definition/flow/driver/DumpGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/DumpGraph.sv @@ -111,7 +111,7 @@ fun generateDotGraph String ::= specs::[ProductionGraph] = end; -- "production/flowvertex" -> "production/flowvertex" -fun makeDotArrow String ::= p::String e::Pair style::String = +fun makeDotArrow String ::= p::String e::(FlowVertex, FlowVertex) style::String = "\"" ++ p ++ "/" ++ e.fst.dotName ++ "\" -> \"" ++ p ++ "/" ++ e.snd.dotName ++ "\"" ++ style ++ ";\n"; diff --git a/grammars/silver/compiler/definition/flow/driver/FlowGraph.sv b/grammars/silver/compiler/definition/flow/driver/FlowGraph.sv index f8059559f..39c960e55 100644 --- a/grammars/silver/compiler/definition/flow/driver/FlowGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/FlowGraph.sv @@ -64,9 +64,9 @@ fun isLhsInhSet Boolean ::= v::FlowVertex inhSet::set:Set = | _ -> false end; -fun createFlowGraph g:Graph ::= l::[Pair] = g:add(l, g:empty()); +fun createFlowGraph g:Graph ::= l::[(FlowVertex, FlowVertex)] = g:add(l, g:empty()); -fun extendFlowGraph g:Graph ::= l::[Pair] g::g:Graph = +fun extendFlowGraph g:Graph ::= l::[(FlowVertex, FlowVertex)] g::g:Graph = g:add(l, g); fun transitiveClose @@ -75,6 +75,6 @@ g:Graph ::= fun repairClosure g:Graph ::= - newEdges::[Pair] + newEdges::[(FlowVertex, FlowVertex)] graph::g:Graph = g:repairClosure(newEdges, graph); diff --git a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv index 0e80c7d8f..145b0666c 100644 --- a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv @@ -51,7 +51,7 @@ top::ProductionGraph ::= lhsNt::String flowTypeVertexes::[FlowVertex] graph::g:Graph - suspectEdges::[Pair] + suspectEdges::[(FlowVertex, FlowVertex)] stitchPoints::[StitchPoint] { top.prod = prod; @@ -59,7 +59,7 @@ top::ProductionGraph ::= top.flowTypeVertexes = flowTypeVertexes; top.stitchedGraph = \ flowTypes::EnvTree prodGraphs::EnvTree -> - let newEdges :: [Pair] = + let newEdges :: [(FlowVertex, FlowVertex)] = filter(edgeIsNew(_, graph), flatMap(stitchEdgesFor(_, flowTypes, prodGraphs), stitchPoints)) in let repaired :: g:Graph = @@ -79,7 +79,7 @@ top::ProductionGraph ::= top.cullSuspect = \ flowTypes::EnvTree -> -- this potentially introduces the same edge twice, but that's a nonissue - let newEdges :: [Pair] = + let newEdges :: [(FlowVertex, FlowVertex)] = flatMap(findAdmissibleEdges(_, graph, findFlowType(lhsNt, flowTypes)), suspectEdges) in let repaired :: g:Graph = repairClosure(newEdges, graph) @@ -155,11 +155,11 @@ ProductionGraph ::= dcl::ValueDclInfo defs::[FlowDef] flowEnv::FlowEnv realEn local nonForwarding :: Boolean = null(lookupFwd(prod, flowEnv)); -- Normal edges! - local normalEdges :: [Pair] = + local normalEdges :: [(FlowVertex, FlowVertex)] = flatMap((.flowEdges), defs); -- Insert implicit equations. - local fixedEdges :: [Pair] = + local fixedEdges :: [(FlowVertex, FlowVertex)] = normalEdges ++ (if nonForwarding then addDefEqs(prod, nt, syns, flowEnv) @@ -167,14 +167,15 @@ ProductionGraph ::= dcl::ValueDclInfo defs::[FlowDef] flowEnv::FlowEnv realEn (lhsSynVertex("forward"), forwardEqVertex()) :: addFwdSynEqs(prod, synsBySuspicion.fst, flowEnv) ++ addFwdInhEqs(prod, inhs, flowEnv)) ++ - flatMap(addFwdProdAttrInhEqs(prod, _, inhs, flowEnv), allFwdProdAttrs(defs)); + flatMap(addFwdProdAttrInhEqs(prod, _, inhs, flowEnv), allFwdProdAttrs(defs)) ++ + flatMap(addSharingEqs(realEnv, _), defs); -- (safe, suspect) local synsBySuspicion :: Pair<[String] [String]> = partition(contains(_, getNonSuspectAttrsForProd(prod, flowEnv)), syns); -- No implicit equations here, just keep track. - local suspectEdges :: [Pair] = + local suspectEdges :: [(FlowVertex, FlowVertex)] = flatMap((.suspectFlowEdges), defs) ++ -- If it's forwarding .snd is attributes not known at forwarding time. If it's non, then actually .snd is all attributes. Ignore. if nonForwarding then [] else addFwdSynEqs(prod, synsBySuspicion.snd, flowEnv); @@ -218,15 +219,19 @@ ProductionGraph ::= ns::NamedSignature flowEnv::FlowEnv realEnv::Env prodEnv: local nt :: NtName = "::nolhs"; -- the same hack we use elsewhere local defs :: [FlowDef] = getGraphContribsFor(prod, flowEnv); - local normalEdges :: [Pair] = + local normalEdges :: [(FlowVertex, FlowVertex)] = flatMap((.flowEdges), defs); + local fixedEdges :: [(FlowVertex, FlowVertex)] = + normalEdges ++ + flatMap(addSharingEqs(realEnv, _), defs); + -- In functions, this is just `<-` contributions to local collections from aspects. - local suspectEdges :: [Pair] = + local suspectEdges :: [(FlowVertex, FlowVertex)] = flatMap((.suspectFlowEdges), defs); local initialGraph :: g:Graph = - createFlowGraph(normalEdges); + createFlowGraph(fixedEdges); -- RHS and locals and forward. local stitchPoints :: [StitchPoint] = @@ -258,11 +263,11 @@ ProductionGraph ::= defs::[FlowDef] realEnv::Env prodEnv::EnvTree] = + local normalEdges :: [(FlowVertex, FlowVertex)] = flatMap((.flowEdges), defs); -- suspectEdges should always be empty! (No "aspects" where they could arise.) - local suspectEdges :: [Pair] = []; + local suspectEdges :: [(FlowVertex, FlowVertex)] = []; local initialGraph :: g:Graph = createFlowGraph(normalEdges); @@ -292,11 +297,11 @@ ProductionGraph ::= ns::NamedSignature defs::[FlowDef] realEnv::Env prodEnv:: local prod :: String = ns.fullName; local nt :: NtName = ns.outputElement.typerep.typeName; - local normalEdges :: [Pair] = + local normalEdges :: [(FlowVertex, FlowVertex)] = flatMap((.flowEdges), defs); -- suspectEdges should always be empty! (No "aspects" where they could arise.) - local suspectEdges :: [Pair] = []; + local suspectEdges :: [(FlowVertex, FlowVertex)] = []; local initialGraph :: g:Graph = createFlowGraph(normalEdges); @@ -335,7 +340,7 @@ ProductionGraph ::= nt::String flowEnv::FlowEnv realEnv::Env local extSyns :: [String] = removeAll(getHostSynsFor(nt, flowEnv), syns); -- The phantom edges: ext syn -> fwd.eq - local phantomEdges :: [Pair] = + local phantomEdges :: [(FlowVertex, FlowVertex)] = -- apparently this alias may sometimes be used. we should get rid of this by making good use of vertex types (lhsSynVertex("forward"), forwardEqVertex()) :: map(getPhantomEdge, extSyns); @@ -345,12 +350,12 @@ ProductionGraph ::= nt::String flowEnv::FlowEnv realEnv::Env local flowTypeVertexes :: [FlowVertex] = [forwardEqVertex()] ++ map(lhsSynVertex, syns); local initialGraph :: g:Graph = createFlowGraph(phantomEdges); - local suspectEdges :: [Pair] = []; + local suspectEdges :: [(FlowVertex, FlowVertex)] = []; return productionGraph("Phantom for " ++ nt, nt, flowTypeVertexes, initialGraph, suspectEdges, stitchPoints).transitiveClosure; } -fun getPhantomEdge Pair ::= at::String = +fun getPhantomEdge (FlowVertex, FlowVertex) ::= at::String = (lhsSynVertex(at), forwardEqVertex()); ---- Begin helpers for fixing up graphs ---------------------------------------- @@ -359,7 +364,7 @@ fun getPhantomEdge Pair ::= at::String = - Introduces implicit 'lhs.syn -> forward.syn' (& forward.eq) equations. - Called twice: once for safe edges, later for SUSPECT edges! -} -fun addFwdSynEqs [Pair] ::= prod::ProdName syns::[String] flowEnv::FlowEnv = +fun addFwdSynEqs [(FlowVertex, FlowVertex)] ::= prod::ProdName syns::[String] flowEnv::FlowEnv = if null(syns) then [] else (if null(lookupSyn(prod, head(syns), flowEnv)) then [(lhsSynVertex(head(syns)), forwardSynVertex(head(syns))), @@ -369,7 +374,7 @@ fun addFwdSynEqs [Pair] ::= prod::ProdName syns::[String] - Introduces implicit 'forward.inh = lhs.inh' equations. - Inherited equations are never suspect. -} -fun addFwdInhEqs [Pair] ::= prod::ProdName inhs::[String] flowEnv::FlowEnv = +fun addFwdInhEqs [(FlowVertex, FlowVertex)] ::= prod::ProdName inhs::[String] flowEnv::FlowEnv = if null(inhs) then [] else (if null(lookupFwdInh(prod, head(inhs), flowEnv)) then [(forwardInhVertex(head(inhs)), lhsInhVertex(head(inhs)))] else []) ++ addFwdInhEqs(prod, tail(inhs), flowEnv); @@ -378,7 +383,7 @@ fun addFwdInhEqs [Pair] ::= prod::ProdName inhs::[String] - Inherited equations are never suspect. -} fun addFwdProdAttrInhEqs -[Pair] ::= prod::ProdName fName::String inhs::[String] flowEnv::FlowEnv = +[(FlowVertex, FlowVertex)] ::= prod::ProdName fName::String inhs::[String] flowEnv::FlowEnv = if null(inhs) then [] else (if null(lookupLocalInh(prod, fName, head(inhs), flowEnv)) then [(localInhVertex(fName, head(inhs)), lhsInhVertex(head(inhs)))] else []) ++ addFwdProdAttrInhEqs(prod, fName, tail(inhs), flowEnv); @@ -392,7 +397,7 @@ fun allFwdProdAttrs [String] ::= d::[FlowDef] = - Introduces default equations deps. Realistically, should be empty, always. -} fun addDefEqs -[Pair] ::= prod::ProdName nt::NtName syns::[String] flowEnv :: FlowEnv = +[(FlowVertex, FlowVertex)] ::= prod::ProdName nt::NtName syns::[String] flowEnv :: FlowEnv = if null(syns) then [] else (if null(lookupSyn(prod, head(syns), flowEnv)) then let x :: [FlowDef] = lookupDef(nt, head(syns), flowEnv) @@ -400,6 +405,21 @@ fun addDefEqs end else []) ++ addDefEqs(prod, nt, tail(syns), flowEnv); +{-- + - Introduce edges for inherited attributes on shared references to their decoration sites. + -} + fun addSharingEqs [(FlowVertex, FlowVertex)] ::= realEnv::Env d::FlowDef = + case d of + | refDecSiteEq(_, nt, ref, decSite, _) when + case ref of + | localVertexType(fName) -> !isForwardProdAttr(fName, realEnv) + | _ -> false + end -> + map( + \ attr::String -> (ref.inhVertex(attr), decSite.inhVertex(attr)), + getInhAndInhOnTransAttrsOn(nt, realEnv)) + | _ -> [] + end; ---- End helpers for fixing up graphs ------------------------------------------ @@ -506,7 +526,7 @@ fun prodGraphToEnv Pair ::= p::ProductionGraph = (p.prod - always an lhsInhVertex. -} function findAdmissibleEdges -[Pair] ::= edge::Pair graph::g:Graph ft::FlowType +[(FlowVertex, FlowVertex)] ::= edge::(FlowVertex, FlowVertex) graph::g:Graph ft::FlowType { -- The current flow type of the edge's source vertex (which is always a thing in the flow type) local currentDeps :: set:Set = diff --git a/grammars/silver/compiler/definition/flow/driver/StitchPoint.sv b/grammars/silver/compiler/definition/flow/driver/StitchPoint.sv index 094f22a7f..da635b1bb 100644 --- a/grammars/silver/compiler/definition/flow/driver/StitchPoint.sv +++ b/grammars/silver/compiler/definition/flow/driver/StitchPoint.sv @@ -2,7 +2,7 @@ grammar silver:compiler:definition:flow:driver; data nonterminal StitchPoint with stitchEdges; -synthesized attribute stitchEdges :: ([Pair] ::= EnvTree EnvTree); +synthesized attribute stitchEdges :: ([(FlowVertex, FlowVertex)] ::= EnvTree EnvTree); {-- - Introduces internal edges corresponding to the flow type of 'nt' @@ -61,7 +61,7 @@ top::StitchPoint ::= - @return edges from 'sourceType.inhVertex(attr)' to 'targetType.inhVertex(??)' -} fun projectAttribute -[Pair] ::= +[(FlowVertex, FlowVertex)] ::= attr::String sourceType::VertexType targetType::VertexType @@ -78,10 +78,10 @@ fun projectAttribute -- Useful for mapping fun stitchEdgesFor -[Pair] ::= sp::StitchPoint ntEnv::EnvTree prodEnv::EnvTree = +[(FlowVertex, FlowVertex)] ::= sp::StitchPoint ntEnv::EnvTree prodEnv::EnvTree = sp.stitchEdges(ntEnv, prodEnv); -fun edgeIsNew Boolean ::= edge::Pair e::g:Graph = +fun edgeIsNew Boolean ::= edge::(FlowVertex, FlowVertex) e::g:Graph = !g:contains(edge, e); {-- @@ -91,7 +91,7 @@ fun edgeIsNew Boolean ::= edge::Pair e::g:Graph ::= vt::VertexType edge::Pair = +fun flowTypeEdge (FlowVertex, FlowVertex) ::= vt::VertexType edge::Pair = if edge.fst == "forward" then (vt.fwdVertex, vt.inhVertex(edge.snd)) else diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index fb8f11841..3ce773a29 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -90,21 +90,6 @@ top::Expr ::= @q::QName if isDecorable(q.lookupValue.typeScheme.monoType, top.env) && top.finalType.isDecorated then just(rhsVertexType(q.lookupValue.fullName)) else nothing(); - - -- Inherited attributes on q's NT that aren't in the reference set and don't have an equation: - local notSuppliedInhs::[String] = - filter( - isEquationMissing(lookupInh(top.frame.fullName, q.lookupValue.fullName, _, top.flowEnv), _), - removeAll( - origRefSet, - getInhAndInhOnTransAttrsOn(top.finalType.decoratedType.typeName, top.env))); - -- Add remote equations for reference site decoration with attributes that aren't supplied here - top.flowDefs <- - case top.decSiteVertexInfo of - | just(decSite) when top.finalType.isUniqueDecorated -> - [childRefDecSiteEq(top.frame.fullName, q.lookupValue.fullName, top.alwaysDecorated, decSite, notSuppliedInhs)] - | _ -> [] - end; } aspect production lhsReference top::Expr ::= @q::QName @@ -134,25 +119,6 @@ top::Expr ::= @q::QName if isDecorable(q.lookupValue.typeScheme.monoType, top.env) && top.finalType.isDecorated then just(localVertexType(q.lookupValue.fullName)) else nothing(); - - -- If this is a forward production attribute, then all inh attributes have an equation here. - local isForwardProdAttr::Boolean = q.lookupValue.found && q.lookupValue.dcl.hasForward; - - -- Inherited attributes on q's NT that aren't in the reference set and don't have an equation: - local notSuppliedInhs::[String] = - if isForwardProdAttr then [] else - filter( - isEquationMissing(lookupLocalInh(top.frame.fullName, q.lookupValue.fullName, _, top.flowEnv), _), - removeAll( - origRefSet, - getInhAndInhOnTransAttrsOn(top.finalType.decoratedType.typeName, top.env))); - -- Add remote equations for reference site decoration with attributes that aren't supplied here - top.flowDefs <- - case top.decSiteVertexInfo of - | just(decSite) when top.finalType.isUniqueDecorated && !isForwardProdAttr -> - [localRefDecSiteEq(top.frame.fullName, q.lookupValue.fullName, top.alwaysDecorated, decSite, notSuppliedInhs)] - | _ -> [] - end; } aspect production forwardReference top::Expr ::= @q::QName @@ -260,7 +226,7 @@ top::AppExpr ::= e::Expr end; e.decSiteVertexInfo = case top.decSiteVertexInfo, top.appProd of - | just(parent), just(ns) when isDecorable(e.finalType, top.env) -> + | just(parent), just(ns) when isDecorable(e.finalType, top.env) -> -- TODO: Signature sharing??? just(subtermVertexType(parent, ns.fullName, sigName)) | _, _ -> nothing() end; @@ -346,28 +312,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur if top.finalType.isDecorated then map(vertex.inhVertex, fromMaybe([], refSet)) else [] | nothing() -> e.flowDeps end; - - local allInhs::[String] = getInhAndInhOnTransAttrsOn(top.finalType.decoratedType.typeName, top.env); - top.flowDefs <- - case top.decSiteVertexInfo of - | just(decSite) when top.finalType.isUniqueDecorated -> - case e of - | childReference(cqn) -> - [childTransRefDecSiteEq( - top.frame.fullName, cqn.lookupValue.fullName, q.attrDcl.fullName, top.alwaysDecorated, decSite, - filter( - isEquationMissing(lookupInh(top.frame.fullName, cqn.lookupValue.fullName, _, top.flowEnv), _), - allInhs))] - | localReference(lqn) -> - [localTransRefDecSiteEq( - top.frame.fullName, lqn.lookupValue.fullName, q.attrDcl.fullName, top.alwaysDecorated, decSite, - filter( - isEquationMissing(lookupLocalInh(top.frame.fullName, lqn.lookupValue.fullName, _, top.flowEnv), _), - allInhs))] - | _ -> [] - end - | _ -> [] - end; e.decSiteVertexInfo = nothing(); } aspect production annoAccessHandler @@ -457,8 +401,13 @@ aspect production decorationSiteExpr top::Expr ::= '@' e::Expr { top.flowVertexInfo = e.flowVertexInfo; - e.decSiteVertexInfo = top.decSiteVertexInfo; - e.alwaysDecorated = top.alwaysDecorated; + + top.flowDefs <- + case e.flowVertexInfo, top.decSiteVertexInfo of + | just(ref), just(decSite) -> + [refDecSiteEq(top.frame.fullName, e.typerep.typeName, ref, decSite, top.alwaysDecorated)] + | _, _ -> [] + end; } aspect production ifThenElse @@ -522,7 +471,7 @@ top::AssignExpr ::= id::Name '::' t::TypeExpr '=' e::Expr } aspect production lexicalLocalReference -top::Expr ::= @q::QName fi::Maybe fd::[FlowVertex] _ +top::Expr ::= @q::QName fi::Maybe fd::[FlowVertex] { -- Because of the auto-undecorate behavior, we need to check for the case -- where `t` should be equivalent to `new(t)` and report accoringly. diff --git a/grammars/silver/compiler/definition/flow/env/FlowEnv.sv b/grammars/silver/compiler/definition/flow/env/FlowEnv.sv index f96ba3d81..7e8f640c7 100644 --- a/grammars/silver/compiler/definition/flow/env/FlowEnv.sv +++ b/grammars/silver/compiler/definition/flow/env/FlowEnv.sv @@ -15,7 +15,7 @@ monoid attribute flowDefs :: [FlowDef]; monoid attribute specDefs :: [(String, String, [String], [String])]; -- (nt, attr, [inhs], [referenced flow specs]) monoid attribute refDefs :: [(String, [String])]; -data nonterminal FlowEnv with synTree, inhTree, defTree, fwdTree, prodTree, fwdInhTree, refTree, uniqueRefTree, refPossibleDecSiteTree, refDecSiteTree, localInhTree, localTree, nonSuspectTree, hostSynTree, specTree, prodGraphTree; +data nonterminal FlowEnv with synTree, inhTree, defTree, fwdTree, prodTree, fwdInhTree, refTree, sharedRefTree, refPossibleDecSiteTree, refDecSiteTree, localInhTree, localTree, nonSuspectTree, hostSynTree, specTree, prodGraphTree; synthesized attribute synTree :: EnvTree; synthesized attribute inhTree :: EnvTree; @@ -24,7 +24,7 @@ synthesized attribute fwdTree :: EnvTree; synthesized attribute fwdInhTree :: EnvTree; synthesized attribute prodTree :: EnvTree; synthesized attribute refTree :: EnvTree<[String]>; -synthesized attribute uniqueRefTree :: EnvTree; +synthesized attribute sharedRefTree :: EnvTree; synthesized attribute refPossibleDecSiteTree :: EnvTree; synthesized attribute refDecSiteTree :: EnvTree; synthesized attribute localInhTree ::EnvTree; @@ -37,7 +37,7 @@ synthesized attribute prodGraphTree :: EnvTree; abstract production flowEnv top::FlowEnv ::= specContribs::[(String, String, [String], [String])] refContribs::[(String, [String])] - uniqueRefContribs::[(String, UniqueRefSite)] + sharedRefContribs::[(String, SharedRefSite)] d::FlowDefs { top.synTree = directBuildTree(d.synTreeContribs); @@ -47,7 +47,7 @@ top::FlowEnv ::= top.fwdInhTree = directBuildTree(d.fwdInhTreeContribs); top.prodTree = directBuildTree(d.prodTreeContribs); top.refTree = directBuildTree(refContribs); - top.uniqueRefTree = directBuildTree(uniqueRefContribs); + top.sharedRefTree = directBuildTree(sharedRefContribs); top.refPossibleDecSiteTree = directBuildTree(d.refPossibleDecSiteContribs); top.refDecSiteTree = directBuildTree(d.refDecSiteContribs); top.localInhTree = directBuildTree(d.localInhTreeContribs); @@ -85,56 +85,17 @@ fun lookupLocalInh [FlowDef] ::= prod::String fName::String attr::String e::F fun lookupLocalEq [FlowDef] ::= prod::String fName::String e::FlowEnv = searchEnvTree(crossnames(prod, fName), e.localTree); --- unique references taken for a child -fun lookupUniqueRefs [UniqueRefSite] ::= prod::String sigName::String e::FlowEnv = - searchEnvTree(prod ++ ":" ++ sigName, e.uniqueRefTree); +-- places where this tree is shared +fun lookupSharedRefs [SharedRefSite] ::= prod::String v::VertexType e::FlowEnv = + searchEnvTree(s"${prod}:${v.vertexName}", e.sharedRefTree); --- unique references taken for a local/production attribute -fun lookupLocalUniqueRefs [UniqueRefSite] ::= fName::String e::FlowEnv = - searchEnvTree(fName, e.uniqueRefTree); +-- possible decoration sites for places where this tree is shared +fun lookupRefPossibleDecSites [VertexType] ::= prod::String v::VertexType e::FlowEnv = + searchEnvTree(s"${prod}:${v.vertexName}", e.refPossibleDecSiteTree); --- unique references taken for a translation attribute on a child -fun lookupTransUniqueRefs -[UniqueRefSite] ::= prod::String sigName::String attrName::String e::FlowEnv = - searchEnvTree(prod ++ ":" ++ sigName ++ "." ++ attrName, e.uniqueRefTree); - --- unique references taken for a translation attribute on a local -fun lookupLocalTransUniqueRefs [UniqueRefSite] ::= fName::String attrName::String e::FlowEnv = - searchEnvTree(fName ++ "." ++ attrName, e.uniqueRefTree); - --- possible decoration sites for unique references taken for a child -fun lookupRefPossibleDecSites [VertexType] ::= prod::String sigName::String e::FlowEnv = - searchEnvTree(s"${prod}:${sigName}", e.refPossibleDecSiteTree); - --- possible decoration sites for unique references taken for a local/production attribute -fun lookupLocalRefPossibleDecSites [VertexType] ::= fName::String e::FlowEnv = - searchEnvTree(fName, e.refPossibleDecSiteTree); - --- possible decoration sites for unique references taken for a translation attribute on a child -fun lookupTransRefPossibleDecSites -[VertexType] ::= prod::String sigName::String attrName::String e::FlowEnv = - searchEnvTree(s"${prod}:${sigName}.${attrName}", e.refPossibleDecSiteTree); - --- possible decoration sites for unique references taken for a translation attribute on a local/production attribute -fun lookupLocalTransRefPossibleDecSites [VertexType] ::= fName::String attrName::String e::FlowEnv = - searchEnvTree(s"${fName}.${attrName}", e.refPossibleDecSiteTree); - --- unconditional decoration sites for unique references taken for a child -fun lookupRefDecSite [VertexType] ::= prod::String sigName::String e::FlowEnv = - searchEnvTree(s"${prod}:${sigName}", e.refDecSiteTree); - --- unconditional decoration sites for unique references taken for a local/production attribute -fun lookupLocalRefDecSite [VertexType] ::= fName::String e::FlowEnv = - searchEnvTree(fName, e.refDecSiteTree); - --- unconditional decoration sites for unique references taken for a translation attribute on a child -fun lookupTransRefDecSite -[VertexType] ::= prod::String sigName::String attrName::String e::FlowEnv = - searchEnvTree(s"${prod}:${sigName}.${attrName}", e.refDecSiteTree); - --- unconditional decoration sites for unique references taken for a translation attribute on a local/production attribute -fun lookupLocalTransRefDecSite [VertexType] ::= fName::String attrName::String e::FlowEnv = - searchEnvTree(s"${fName}.${attrName}", e.refDecSiteTree); +-- unconditional decoration sites for places where this tree is shared +fun lookupRefDecSite [VertexType] ::= prod::String v::VertexType e::FlowEnv = + searchEnvTree(s"${prod}:${v.vertexName}", e.refDecSiteTree); {-- - This is a glorified lambda function, to help look for equations. diff --git a/grammars/silver/compiler/definition/type/PrettyPrinting.sv b/grammars/silver/compiler/definition/type/PrettyPrinting.sv index c08ad402f..170d6c9d3 100644 --- a/grammars/silver/compiler/definition/type/PrettyPrinting.sv +++ b/grammars/silver/compiler/definition/type/PrettyPrinting.sv @@ -216,12 +216,6 @@ top::Type ::= t::Type i::Type top.typepp = s"Decorated ${t.typepp} with ${i.typepp}"; } -aspect production uniqueDecoratedType -top::Type ::= t::Type i::Type -{ - top.typepp = s"Decorated! ${t.typepp} with ${i.typepp}"; -} - aspect production ntOrDecType top::Type ::= nt::Type inhs::Type hidden::Type { diff --git a/grammars/silver/compiler/definition/type/Type.sv b/grammars/silver/compiler/definition/type/Type.sv index 285178725..5b07ffdae 100644 --- a/grammars/silver/compiler/definition/type/Type.sv +++ b/grammars/silver/compiler/definition/type/Type.sv @@ -254,20 +254,6 @@ top::Type ::= te::Type i::Type top.freeVariables = setUnionTyVars(te.freeVariables, i.freeVariables); } -{-- - - A *unique decorated* nonterminal type. - - Represents a reference with some exact set of provided inherited attributes, - - may be decorated with additional attributes. - - @param te MUST be a 'nonterminalType' or 'varType'/'skolemType' - - @param i MUST have kind InhSet - -} -abstract production uniqueDecoratedType -top::Type ::= te::Type i::Type -{ - top.kindrep = starKind(); - top.freeVariables = setUnionTyVars(te.freeVariables, i.freeVariables); -} - {-- - An intermediate type. This *should* never appear as the type of a symbol, - etc. Rather, this is a helper type only used within expressions. diff --git a/grammars/silver/compiler/definition/type/Unification.sv b/grammars/silver/compiler/definition/type/Unification.sv index fcf3f8285..5d1571bd9 100644 --- a/grammars/silver/compiler/definition/type/Unification.sv +++ b/grammars/silver/compiler/definition/type/Unification.sv @@ -153,17 +153,6 @@ top::Type ::= te::Type i::Type end; } -aspect production uniqueDecoratedType -top::Type ::= te::Type i::Type -{ - top.unify = - case top.unifyWith of - | uniqueDecoratedType(ote, oi) -> composeSubst(unify(te, ote), unify(i, oi)) - | ntOrDecType(_,_,_) -> errorSubst("dte-nodte: try again") - | _ -> errorSubst("Tried to unify unique decorated type with " ++ prettyType(top.unifyWith)) - end; -} - aspect production ntOrDecType top::Type ::= nt::Type inhs::Type hidden::Type { @@ -180,10 +169,6 @@ top::Type ::= nt::Type inhs::Type hidden::Type -- Ensure compatibility between Decorated nonterminal types, then specialize ourselves unifyAllShortCircuit([ote, oi, top.unifyWith], [nt, inhs, hidden]) - | uniqueDecoratedType(ote, oi) -> - -- Ensure compatibility between Decorated nonterminal types, then specialize ourselves - unifyAllShortCircuit([ote, oi, top.unifyWith], - [nt, inhs, hidden]) | nonterminalType(_, _, _, _) -> -- Ensure compatibility between nonterminal types, then specialize ourselves unifyAllShortCircuit([top.unifyWith, top.unifyWith], diff --git a/grammars/silver/compiler/definition/type/Util.sv b/grammars/silver/compiler/definition/type/Util.sv index 1bacb01ad..3c5eb2ac8 100644 --- a/grammars/silver/compiler/definition/type/Util.sv +++ b/grammars/silver/compiler/definition/type/Util.sv @@ -20,10 +20,6 @@ monoid attribute freeFlexibleVars :: [TyVar] with [], setUnionTyVars; -- Also used by 'new()' synthesized attribute isDecorated :: Boolean; --- Determines whether a type is a unique decorated nonterminal type --- Used in determining whether a type may be supplied with inherited attributes. -synthesized attribute isUniqueDecorated :: Boolean; - -- Determines whether a type is an (undecorated) nonterminal type -- Used in determining whether a type may be supplied with inherited attributes. synthesized attribute isNonterminal :: Boolean; @@ -51,7 +47,7 @@ synthesized attribute unifyInstanceNonterminal :: Substitution; synthesized attribute unifyInstanceDecorated :: Substitution; synthesized attribute unifyInstanceDecorable :: Substitution; -- NT or unique decorated -attribute arity, isError, isDecorated, isUniqueDecorated, isNonterminal, isData, isTerminal, asNtOrDecType, compareTo, isEqual occurs on PolyType; +attribute arity, isError, isDecorated, isNonterminal, isData, isTerminal, asNtOrDecType, compareTo, isEqual occurs on PolyType; aspect production monoType top::PolyType ::= ty::Type @@ -59,7 +55,6 @@ top::PolyType ::= ty::Type top.arity = ty.arity; top.isError = ty.isError; top.isDecorated = ty.isDecorated; - top.isUniqueDecorated = ty.isUniqueDecorated; top.isNonterminal = ty.isNonterminal; top.isData = ty.isData; top.isTerminal = ty.isTerminal; @@ -77,7 +72,6 @@ top::PolyType ::= bound::[TyVar] ty::Type top.arity = ty.arity; top.isError = ty.isError; top.isDecorated = ty.isDecorated; - top.isUniqueDecorated = ty.isUniqueDecorated; top.isNonterminal = ty.isNonterminal; top.isData = ty.isData; top.isTerminal = ty.isTerminal; @@ -96,7 +90,6 @@ top::PolyType ::= bound::[TyVar] contexts::[Context] ty::Type top.arity = ty.arity; top.isError = ty.isError; top.isDecorated = ty.isDecorated; - top.isUniqueDecorated = ty.isUniqueDecorated; top.isNonterminal = ty.isNonterminal; top.isData = ty.isData; top.isTerminal = ty.isTerminal; @@ -109,7 +102,7 @@ top::PolyType ::= bound::[TyVar] contexts::[Context] ty::Type top.compareTo.typerep == performRenaming(ty, eqSub); } -attribute isError, inputTypes, outputType, namedTypes, arity, baseType, argTypes, isDecorated, isUniqueDecorated, isNonterminal, isData, isTracked, isTerminal, isApplicable, decoratedType, asNtOrDecType, defaultSpecialization, inhSetMembers, freeSkolemVars, freeFlexibleVars, unifyInstanceNonterminal, unifyInstanceDecorated, unifyInstanceDecorable occurs on Type; +attribute isError, inputTypes, outputType, namedTypes, arity, baseType, argTypes, isDecorated, isNonterminal, isData, isTracked, isTerminal, isApplicable, decoratedType, asNtOrDecType, defaultSpecialization, inhSetMembers, freeSkolemVars, freeFlexibleVars, unifyInstanceNonterminal, unifyInstanceDecorated, unifyInstanceDecorable occurs on Type; propagate freeSkolemVars, freeFlexibleVars on Type; @@ -125,7 +118,6 @@ top::Type ::= top.inhSetMembers = []; top.isDecorated = false; - top.isUniqueDecorated = false; top.isNonterminal = false; top.isData = false; top.isTracked = false; @@ -245,18 +237,6 @@ top::Type ::= te::Type i::Type top.unifyInstanceDecorated = emptySubst(); } -aspect production uniqueDecoratedType -top::Type ::= te::Type i::Type -{ - top.isDecorated = true; - top.isUniqueDecorated = true; - top.decoratedType = te; - top.asNtOrDecType = ntOrDecType(te, freshInhSet(), freshType()); - top.inhSetMembers = i.inhSetMembers; - top.unifyInstanceDecorated = emptySubst(); - top.unifyInstanceDecorable = emptySubst(); -} - aspect production ntOrDecType top::Type ::= nt::Type inhs::Type hidden::Type { diff --git a/grammars/silver/compiler/definition/type/syntax/Terminals.sv b/grammars/silver/compiler/definition/type/syntax/Terminals.sv index d7effb56d..5bef82ecc 100644 --- a/grammars/silver/compiler/definition/type/syntax/Terminals.sv +++ b/grammars/silver/compiler/definition/type/syntax/Terminals.sv @@ -14,7 +14,6 @@ disambiguate LCurly_t, InhSetLCurly_t { pluck LCurly_t; } terminal Boolean_tkwd 'Boolean' lexer classes {TYPE,RESERVED}; terminal Decorated_tkwd 'Decorated' lexer classes {TYPE,RESERVED}, precedence=1; -terminal UniqueDecorated_tkwd 'Decorated!' lexer classes {TYPE,RESERVED}, precedence=1; terminal Float_tkwd 'Float' lexer classes {TYPE,RESERVED}; terminal Integer_tkwd 'Integer' lexer classes {TYPE,RESERVED}; terminal String_tkwd 'String' lexer classes {TYPE,RESERVED}; diff --git a/grammars/silver/compiler/definition/type/syntax/TypeExpr.sv b/grammars/silver/compiler/definition/type/syntax/TypeExpr.sv index 8682a87b4..c87b2046e 100644 --- a/grammars/silver/compiler/definition/type/syntax/TypeExpr.sv +++ b/grammars/silver/compiler/definition/type/syntax/TypeExpr.sv @@ -59,7 +59,7 @@ flowtype typerep {grammarName, env, flowEnv} on TypeExpr, Signature; flowtype maybeType {grammarName, env, flowEnv} on SignatureLHS; flowtype types {grammarName, env, flowEnv} on TypeExprs, BracketedTypeExprs, BracketedOptTypeExprs; -propagate errors on TypeExpr, Signature, SignatureLHS, TypeExprs, BracketedTypeExprs, BracketedOptTypeExprs, NamedTypeExprs excluding refTypeExpr, uniqueRefTypeExpr; +propagate errors on TypeExpr, Signature, SignatureLHS, TypeExprs, BracketedTypeExprs, BracketedOptTypeExprs, NamedTypeExprs excluding refTypeExpr; propagate config, grammarName, env, flowEnv, lexicalTypeVariables, lexicalTyVarKinds on TypeExpr, Signature, SignatureLHS, TypeExprs, BracketedTypeExprs, BracketedOptTypeExprs, NamedTypeExprs; propagate appLexicalTyVarKinds on TypeExprs, BracketedTypeExprs, BracketedOptTypeExprs; @@ -361,56 +361,6 @@ top::TypeExpr ::= 'Decorated' t::TypeExpr end; } -concrete production uniqueRefTypeExpr -top::TypeExpr ::= 'Decorated!' t::TypeExpr 'with' i::TypeExpr -{ - top.unparse = "Decorated! " ++ t.unparse ++ " with " ++ i.unparse; - - i.onNt = t.typerep; - - top.typerep = uniqueDecoratedType(t.typerep, i.typerepInhSet); - - top.errors := i.errorsInhSet ++ t.errors; - top.errors <- - case t.typerep.baseType of - | nonterminalType(fn,_,true,_) -> [errFromOrigin(t, s"${fn} is a data nonterminal and cannot be decorated")] - | nonterminalType(_,_,_,_) -> [] - | skolemType(_) -> [] - | varType(_) -> [] - | _ -> [errFromOrigin(t, t.unparse ++ " is not a nonterminal, and cannot be Decorated!.")] - end; - top.errors <- - if i.typerep.kindrep != inhSetKind() - then [errFromOrigin(i, s"${i.unparse} has kind ${prettyKind(i.typerep.kindrep)}, but kind InhSet is expected here")] - else []; - top.errors <- t.errorsKindStar; - - top.lexicalTyVarKinds <- - case i of - | typeVariableTypeExpr(tv) -> [(tv.lexeme, inhSetKind())] - | _ -> [] - end; -} - -concrete production uniqueRefDefaultTypeExpr -top::TypeExpr ::= 'Decorated!' t::TypeExpr -{ - top.unparse = "Decorated! " ++ t.unparse; - - top.typerep = - uniqueDecoratedType(t.typerep, - inhSetType(sort(concat(getInhsForNtRef(t.typerep.typeName, top.flowEnv))))); - - top.errors <- - case t.typerep.baseType of - | nonterminalType(fn,_,true,_) -> [errFromOrigin(t, s"${fn} is a data nonterminal and cannot be decorated")] - | nonterminalType(_,_,_,_) -> [] - | skolemType(_) -> [errFromOrigin(t, "polymorphic Decorated! types must specify an explicit reference set")] - | varType(_) -> [errFromOrigin(t, "polymorphic Decorated! types must specify an explicit reference set")] - | _ -> [errFromOrigin(t, t.unparse ++ " is not a nonterminal, and cannot be Decorated!.")] - end; -} - concrete production funTypeExpr top::TypeExpr ::= '(' sig::Signature ')' { diff --git a/grammars/silver/compiler/driver/util/FlowTypes.sv b/grammars/silver/compiler/driver/util/FlowTypes.sv index df7e4cdca..914c2b4c7 100644 --- a/grammars/silver/compiler/driver/util/FlowTypes.sv +++ b/grammars/silver/compiler/driver/util/FlowTypes.sv @@ -16,8 +16,8 @@ top::Compilation ::= g::Grammars r::Grammars buildGrammars::[String] benv::Bu local allFlowDefs :: FlowDefs = foldr(consFlow, nilFlow(), flatMap((.flowDefs), allLatestGrammars)); local allSpecDefs :: [(String, String, [String], [String])] = flatMap((.specDefs), allLatestGrammars); local allRefDefs :: [(String, [String])] = flatMap((.refDefs), allLatestGrammars); - local allUniqueRefs :: [(String, UniqueRefSite)] = flatMap((.uniqueRefs), allLatestGrammars); - local allFlowEnv :: FlowEnv = flowEnv(allSpecDefs, allRefDefs, allUniqueRefs, allFlowDefs); + local allSharedRefs :: [(String, SharedRefSite)] = flatMap((.sharedRefs), allLatestGrammars); + local allFlowEnv :: FlowEnv = flowEnv(allSpecDefs, allRefDefs, allSharedRefs, allFlowDefs); -- Look up tree for production info local prodTree :: EnvTree = directBuildTree(allFlowDefs.prodGraphContribs); diff --git a/grammars/silver/compiler/driver/util/RootSpec.sv b/grammars/silver/compiler/driver/util/RootSpec.sv index b0dc6401a..e4afe0163 100644 --- a/grammars/silver/compiler/driver/util/RootSpec.sv +++ b/grammars/silver/compiler/driver/util/RootSpec.sv @@ -90,7 +90,7 @@ top::RootSpec ::= g::Grammar oldInterface::Maybe grammarName:: flowEnv( flatMap((.specDefs), rootSpecs), flatMap((.refDefs), rootSpecs), - flatMap((.uniqueRefs), rootSpecs), + flatMap((.sharedRefs), rootSpecs), foldr(consFlow, nilFlow(), flatMap((.flowDefs), rootSpecs))); production newInterface::InterfaceItems = packInterfaceItems(top); diff --git a/grammars/silver/compiler/extension/autoattr/Functor.sv b/grammars/silver/compiler/extension/autoattr/Functor.sv index 6e9be007f..54ea3d492 100644 --- a/grammars/silver/compiler/extension/autoattr/Functor.sv +++ b/grammars/silver/compiler/extension/autoattr/Functor.sv @@ -96,7 +96,7 @@ Expr ::= env::Env attrName::Decorated QName input::NamedSignatureElement local attrOccursOnHead :: Boolean = !null(getOccursDcl(attrName.lookupAttribute.dcl.fullName, input.typerep.typeName, env)); local validTypeHead :: Boolean = - (isDecorable(input.typerep, env) || input.typerep.isNonterminal) && !input.typerep.isUniqueDecorated; + isDecorable(input.typerep, env) || input.typerep.isNonterminal; return if validTypeHead && attrOccursOnHead diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index 0d576c30f..6ccf55d39 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -1232,7 +1232,7 @@ top::Expr ::= '@' e::Expr e.mDownSubst = top.mDownSubst; errCheck1.downSubst = e.mUpSubst; top.mUpSubst = errCheck1.upSubst; - errCheck1 = check(e.typerep, uniqueDecoratedType(freshType(), inhSetType([]))); + errCheck1 = check(e.typerep, decoratedType(freshType(), inhSetType([]))); top.merrors <- if errCheck1.typeerror then [errFromOrigin(top, "Operand to @ must be a unique reference with no inherited attributes. Instead it is of type " ++ errCheck1.leftpp)] diff --git a/grammars/silver/compiler/extension/implicit_monads/Let.sv b/grammars/silver/compiler/extension/implicit_monads/Let.sv index 6d64e1237..105e79cb9 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Let.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Let.sv @@ -116,7 +116,7 @@ top::AssignExpr ::= id::Name '::' t::TypeExpr '=' e::Expr top.mdefs = [lexicalLocalDef(top.grammarName, id.nameLoc, fName, performSubstitution(t.typerep, top.mUpSubst), - e.flowVertexInfo, e.flowDeps, e.uniqueRefs)]; + e.flowVertexInfo, e.flowDeps)]; top.bindInList = if isMonad(e.mtyperep, top.env) && fst(monadsMatch(e.mtyperep, top.expectedMonad, top.mUpSubst)) then [(id, t)] @@ -133,7 +133,7 @@ top::AssignExpr ::= id::Name '::' t::TypeExpr '=' e::Expr aspect production lexicalLocalReference -top::Expr ::= @q::QName _ _ _ +top::Expr ::= @q::QName _ _ { top.merrors := []; propagate mDownSubst, mUpSubst; diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index 659788fe5..23e54eac8 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -26,7 +26,7 @@ top::Expr ::= } aspect production lexicalLocalReference -top::Expr ::= @q::QName _ _ _ +top::Expr ::= @q::QName _ _ { -- In regular pattern matching nonterminal values are always effectively decorated, but we are -- using the same typing behavior while matching on *undecorated* trees. So when a variable is @@ -297,7 +297,7 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur }), consASTExpr(eUndec.transform, inh.transform), nilNamedASTExpr()) - | lexicalLocalReference(qn, _, _, _) when + | lexicalLocalReference(qn, _, _) when case lookup(qn.name, top.boundVars) of | just(bindingIsDecorated) -> !bindingIsDecorated | nothing() -> false @@ -633,7 +633,7 @@ top::AssignExpr ::= id::Name '::' t::TypeExpr '=' e::Expr -- primitive pattern variable was implictly decorated. local isDecorated::Boolean = case e of - | lexicalLocalReference(qn, _, _, _) -> + | lexicalLocalReference(qn, _, _) -> fromMaybe(e.finalType.isDecorated, lookup(qn.name, top.boundVars)) | _ -> e.finalType.isDecorated end; diff --git a/grammars/silver/compiler/extension/testing/WrongCode.sv b/grammars/silver/compiler/extension/testing/WrongCode.sv index 066aeb50e..559c8f905 100644 --- a/grammars/silver/compiler/extension/testing/WrongCode.sv +++ b/grammars/silver/compiler/extension/testing/WrongCode.sv @@ -87,7 +87,7 @@ top::AGDcl ::= 'wrongFlowCode' s::String_t '{' ags::AGDcls '}' else []; -- These need to be passed up for the flow analysis to work: - propagate defs, flowDefs, uniqueRefs; + propagate defs, flowDefs, sharedRefs; forwards to emptyAGDcl(); } diff --git a/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv b/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv index 3101b0946..9a79e4d41 100644 --- a/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv +++ b/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv @@ -50,6 +50,9 @@ top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' e.frame = functionContext(namedSig, myFlowGraph, sourceGrammar=top.grammarName); e.originRules = []; e.isRoot = true; +} action { + insert semantic token IdFnProdDcl_t at id.nameLoc; + sigNames = []; } monoid attribute shortFunctionDefs::[Def] occurs on FunctionSignature, ProductionRHS, ProductionRHSElem; diff --git a/grammars/silver/compiler/modification/let_fix/DclInfo.sv b/grammars/silver/compiler/modification/let_fix/DclInfo.sv index 33425701b..110130776 100644 --- a/grammars/silver/compiler/modification/let_fix/DclInfo.sv +++ b/grammars/silver/compiler/modification/let_fix/DclInfo.sv @@ -3,25 +3,25 @@ grammar silver:compiler:modification:let_fix; import silver:compiler:definition:flow:ast only VertexType, FlowVertex; abstract production lexicalLocalDcl -top::ValueDclInfo ::= fn::String ty::Type fi::Maybe fd::[FlowVertex] rs::[(String, UniqueRefSite)] +top::ValueDclInfo ::= fn::String ty::Type fi::Maybe fd::[FlowVertex] { top.fullName = fn; top.isEqual = -- Should never show up in an interface file anyway... case top.compareTo of - | lexicalLocalDcl(fn2, ty2, _, _, _) -> fn == fn2 && ty == ty2 + | lexicalLocalDcl(fn2, ty2, _, _) -> fn == fn2 && ty == ty2 | _ -> false end; top.typeScheme = monoType(ty); - top.refDispatcher = lexicalLocalReference(fi, fd, rs); + top.refDispatcher = lexicalLocalReference(fi, fd); top.defDispatcher = errorValueDef; -- should be impossible (never in scope at production level?) top.defLHSDispatcher = errorDefLHS; -- ditto top.transDefLHSDispatcher = errorTransAttrDefLHS; } fun lexicalLocalDef -Def ::= sg::String sl::Location fn::String ty::Type fi::Maybe fd::[FlowVertex] rs::[(String, UniqueRefSite)] = - valueDef(defaultEnvItem(lexicalLocalDcl(fn,ty,fi,fd,rs,sourceGrammar=sg,sourceLocation=sl))); +Def ::= sg::String sl::Location fn::String ty::Type fi::Maybe fd::[FlowVertex] = + valueDef(defaultEnvItem(lexicalLocalDcl(fn,ty,fi,fd,sourceGrammar=sg,sourceLocation=sl))); diff --git a/grammars/silver/compiler/modification/let_fix/Let.sv b/grammars/silver/compiler/modification/let_fix/Let.sv index 79e5062fa..daf899581 100644 --- a/grammars/silver/compiler/modification/let_fix/Let.sv +++ b/grammars/silver/compiler/modification/let_fix/Let.sv @@ -95,7 +95,7 @@ top::AssignExpr ::= id::Name '::' t::TypeExpr '=' e::Expr -- auto-undecorate feature, so that's why we bother substituting. -- (er, except that we're starting with t, which is a Type... must be because we fake these -- in e.g. the pattern matching code, so type variables might appear there?) - top.defs <- [lexicalLocalDef(top.grammarName, id.nameLoc, fName, semiTy, e.flowVertexInfo, e.flowDeps, e.uniqueRefs)]; + top.defs <- [lexicalLocalDef(top.grammarName, id.nameLoc, fName, semiTy, e.flowVertexInfo, e.flowDeps)]; -- TODO: At present, this isn't working properly, because the local scope is -- whatever scope encloses the real local scope... hrmm! @@ -120,7 +120,7 @@ top::AssignExpr ::= id::Name '::' t::TypeExpr '=' e::Expr } abstract production lexicalLocalReference implements Reference -top::Expr ::= @q::QName fi::Maybe fd::[FlowVertex] rs::[(String, UniqueRefSite)] +top::Expr ::= @q::QName fi::Maybe fd::[FlowVertex] { top.unparse = q.unparse; top.errors := []; @@ -145,7 +145,6 @@ top::Expr ::= @q::QName fi::Maybe fd::[FlowVertex] rs::[(String, case q.lookupValue.typeScheme.monoType of | ntOrDecType(t, i, _) -> ntOrDecType(t, i, freshType()) | decoratedType(t, i) -> ntOrDecType(t, i, freshType()) - | uniqueDecoratedType(t, i) -> ntOrDecType(t, i, freshType()) | t -> t end; diff --git a/grammars/silver/compiler/modification/let_fix/java/Let.sv b/grammars/silver/compiler/modification/let_fix/java/Let.sv index 00d008974..5451acab2 100644 --- a/grammars/silver/compiler/modification/let_fix/java/Let.sv +++ b/grammars/silver/compiler/modification/let_fix/java/Let.sv @@ -57,7 +57,7 @@ fun makeSpecialLocalBinding String ::= fn::String et::String ty::String = s"final common.Thunk<${ty}> ${makeLocalValueName(fn)} = ${wrapThunkText(et, ty)};\n"; aspect production lexicalLocalReference -top::Expr ::= @q::QName _ _ _ +top::Expr ::= @q::QName _ _ { -- To account for a magic case where we generate a let expression with a type -- that is, for example, a ntOrDecType or something, diff --git a/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv b/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv index cc5980254..bf904ec42 100644 --- a/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv +++ b/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv @@ -537,8 +537,8 @@ top::PrimPattern ::= h::Name t::Name e::Expr propagate finalSubst; local consdefs :: [Def] = - [lexicalLocalDef(top.grammarName, h.nameLoc, h_fName, elemType, nothing(), [], []), - lexicalLocalDef(top.grammarName, t.nameLoc, t_fName, top.scrutineeType, nothing(), [], [])]; + [lexicalLocalDef(top.grammarName, h.nameLoc, h_fName, elemType, nothing(), []), + lexicalLocalDef(top.grammarName, t.nameLoc, t_fName, top.scrutineeType, nothing(), [])]; e.env = newScopeEnv(consdefs, top.env); e.isRoot = false; diff --git a/grammars/silver/compiler/modification/primitivepattern/Types.sv b/grammars/silver/compiler/modification/primitivepattern/Types.sv index 4222838a0..8c074ece9 100644 --- a/grammars/silver/compiler/modification/primitivepattern/Types.sv +++ b/grammars/silver/compiler/modification/primitivepattern/Types.sv @@ -220,16 +220,6 @@ top::Type ::= te::Type i::Type end; } -aspect production uniqueDecoratedType -top::Type ::= te::Type i::Type -{ - top.refine = - case top.refineWith of - | uniqueDecoratedType(oi, ote) -> composeSubst(refine(te, ote), refine(i, oi)) - | _ -> errorSubst("Tried to refine unique decorated type with " ++ prettyType(top.refineWith)) - end; -} - aspect production functionType top::Type ::= params::Integer namedParams::[String] { diff --git a/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv b/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv index 30646db21..b1e64a15a 100644 --- a/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv +++ b/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv @@ -159,7 +159,7 @@ top::VarBinder ::= n::Name else []; -- Unique refs are forbidden in the scrutinee. - top.defs <- [lexicalLocalDef(top.grammarName, n.nameLoc, fName, ty, vt, deps, [])]; + top.defs <- [lexicalLocalDef(top.grammarName, n.nameLoc, fName, ty, vt, deps)]; top.boundNames <- [n.name]; top.translation = diff --git a/grammars/silver/compiler/translation/java/core/Expr.sv b/grammars/silver/compiler/translation/java/core/Expr.sv index 4257ef306..448a2843f 100644 --- a/grammars/silver/compiler/translation/java/core/Expr.sv +++ b/grammars/silver/compiler/translation/java/core/Expr.sv @@ -2,7 +2,6 @@ grammar silver:compiler:translation:java:core; import silver:compiler:driver only noOrigins; -import silver:compiler:definition:flow:ast; {-- - A translation string that will be a thunk instead of the raw value. @@ -79,10 +78,6 @@ top::Expr ::= @q::QName -- the reason we do .childDecorated().undecorate() is that it's not safe to mix as-is/decorated accesses to the same child. -- this is a potential source of minor inefficiency for functions that do not decorate. s"((${top.finalType.transType})context.childDecorated(${childIDref}).undecorate())" - else if top.finalType.isUniqueDecorated && top.alwaysDecorated then - -- Unique reference to a child that is a remote decoration site: - -- Note that this is not cached; uniqueness guarantees that it should only be demanded once. - s"context.createDecoratedChild(${childIDref})" else -- Normal decorated reference: -- This may create the child, or demand it via the remote decoration site if the child has one. @@ -95,10 +90,7 @@ top::Expr ::= @q::QName then s"context.childAsIsLazy(${childIDref})" else if !top.finalType.isDecorated then s"common.Thunk.transformUndecorate(context.childDecoratedLazy(${childIDref}))" - else if top.finalType.isUniqueDecorated && top.alwaysDecorated then - wrapThunk(top.translation, true) - else - s"context.childDecoratedLazy(${childIDref})"; + else s"context.childDecoratedLazy(${childIDref})"; } aspect production localReference @@ -109,8 +101,6 @@ top::Expr ::= @q::QName then s"context.<${top.finalType.transType}>localAsIs(${q.lookupValue.dcl.attrOccursIndex})" else if !top.finalType.isDecorated then s"((${top.finalType.transType})context.localDecorated(${q.lookupValue.dcl.attrOccursIndex}).undecorate())" - else if top.finalType.isUniqueDecorated && top.alwaysDecorated then - s"context.evalLocalDecorated(${q.lookupValue.dcl.attrOccursIndex})" else s"context.localDecorated(${q.lookupValue.dcl.attrOccursIndex})"; -- reminder: look at comments for childReference @@ -121,10 +111,7 @@ top::Expr ::= @q::QName then s"context.localAsIsLazy(${q.lookupValue.dcl.attrOccursIndex})" else if !top.finalType.isDecorated then s"common.Thunk.transformUndecorate(context.localDecoratedLazy(${q.lookupValue.dcl.attrOccursIndex}))" - else if top.finalType.isUniqueDecorated && top.alwaysDecorated then - wrapThunk(top.translation, true) - else - s"context.localDecoratedLazy(${q.lookupValue.dcl.attrOccursIndex})"; + else s"context.localDecoratedLazy(${q.lookupValue.dcl.attrOccursIndex})"; } aspect production lhsReference @@ -253,7 +240,7 @@ top::Expr ::= @e::Expr @es::AppExprs @annos::AnnoAppExprs top.translation = e.invokeTranslation; top.lazyTranslation = e.invokeLazyTranslation; - e.invokeIsUnique = !null(top.uniqueRefs); + e.invokeIsUnique = !null(top.sharedRefs); e.invokeArgs = es; e.invokeNamedArgs = annos; e.sameProdAsProductionDefinedOn = @@ -391,39 +378,12 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur top.translation = if !top.finalType.isDecorated then s"((${top.finalType.transType})${e.translation}.translation(${q.attrOccursIndex}, ${q.attrOccursIndex}_inhs, ${q.attrOccursIndex}_dec_site).undecorate())" - else if top.finalType.isUniqueDecorated && top.alwaysDecorated && - case e of - | childReference(cqn) -> true - | localReference(lqn) -> true - | _ -> false - end then - -- Unique reference to a translation attribute on a child or local that is a remote decoration site: - -- Note that this is not cached; uniqueness guarantees that it should only be demanded once. - s"${e.translation}.evalTrans(${q.attrOccursIndex}, ${q.attrOccursIndex}_inhs)" else - -- Normal decorated reference: - -- This may create the child, or demand it via the remote decoration site if the child has one. + -- This may create the tree, or demand it via the remote decoration site if it has one. s"${e.translation}.translation(${q.attrOccursIndex}, ${q.attrOccursIndex}_inhs, ${q.attrOccursIndex}_dec_site)"; -- TODO: Specialized thunks for accesses on child/local, for efficency top.lazyTranslation = wrapThunk(top.translation, top.frame.lazyApplication); - - top.initTransDecSites <- - case top.decSiteVertexInfo of - | just(decSite) when top.finalType.isUniqueDecorated && top.alwaysDecorated -> - case e of - | childReference(cqn) -> - s"\t\t// Decoration site for ${q.unparse}: ${decSite.vertexName}\n" ++ - s"\t\t${top.frame.className}.childInheritedAttributes[${top.frame.className}.i_${cqn.lookupValue.fullName}][${q.attrOccursInitIndex}_dec_site] = " ++ - s"(context) -> ${refAccessTranslation(top.env, top.flowEnv, top.frame.lhsNtName, decSite)};\n" - | localReference(lqn) -> - s"\t\t// Decoration site for ${q.unparse}: ${decSite.vertexName}\n" ++ - s"\t\t${top.frame.className}.localInheritedAttributes[${lqn.lookupValue.dcl.attrOccursIndex}][${q.attrOccursInitIndex}_dec_site] = " ++ - s"(context) -> ${refAccessTranslation(top.env, top.flowEnv, top.frame.lhsNtName, decSite)};\n" - | _ -> "" - end - | _ -> "" - end; } aspect production terminalAccessHandler @@ -533,14 +493,46 @@ top::ExprLHSExpr ::= q::QNameAttrOccur } - aspect production decorationSiteExpr top::Expr ::= '@' e::Expr { top.translation = s"new ${top.finalType.transType}.DecorationSiteWrapper(${ - if top.finalType.isTracked then makeOriginContextRef(top) ++ ".makeNewConstructionOrigin(true), " else ""}${e.translation})"; + if top.finalType.isTracked then makeOriginContextRef(top) ++ ".makeNewConstructionOrigin(true), " else ""}${ + if top.alwaysDecorated + -- This production may depend on additional inherited attributes supplied through this tree + -- through its shared decoration site, so e.translation will access the tree through its decoration site. + -- We need the raw tree here to avoid a circularity. + -- This is not cached, as the uniqueness analysis gurantees it will only be demanded once. + then sharedRefTranslation(top.env, top.frame, e.flowVertexInfo.fromJust) + -- We won't depend on any attributes later supplied to the tree, just demand it the normal way here. + else e.translation})"; top.lazyTranslation = wrapThunk(top.translation, top.frame.lazyApplication); + + top.initTransDecSites <- + case top.decSiteVertexInfo of + | just(decSite) when top.alwaysDecorated -> + case e.flowVertexInfo of + | just(transAttrVertexType(rhsVertexType(sigName), transAttr)) -> + case lookup(sigName, zip(top.frame.signature.inputNames, top.frame.signature.inputTypes)) of + | just(ty) when getOccursDcl(transAttr, ty.typeName, top.env) matches occDcl :: _ -> + s"\t\t// Decoration site for ${e.flowVertexInfo.fromJust.vertexName}: ${decSite.vertexName}\n" ++ + s"\t\t${top.frame.className}.childInheritedAttributes[${top.frame.className}.i_${sigName}][${occDcl.attrOccursInitIndex}_dec_site] = " ++ + s"(context) -> ${refAccessTranslation(top.env, top.flowEnv, top.frame.lhsNtName, decSite)};\n" + | _ -> error("Couldn't find occurs dcl for " ++ transAttr ++ " on " ++ sigName) + end + | just(transAttrVertexType(localVertexType(fName), transAttr)) -> + case getValueDcl(fName, top.env) of + | dcl :: _ when getOccursDcl(transAttr, dcl.typeScheme.typeName, top.env) matches occDcl :: _ -> + s"\t\t// Decoration site for ${e.flowVertexInfo.fromJust.vertexName}: ${decSite.vertexName}\n" ++ + s"\t\t${top.frame.className}.localInheritedAttributes[${dcl.attrOccursIndex}][${occDcl.attrOccursInitIndex}_dec_site] = " ++ + s"(context) -> ${refAccessTranslation(top.env, top.flowEnv, top.frame.lhsNtName, decSite)};\n" + | _ -> error("Couldn't find occurs dcl for " ++ transAttr ++ " on " ++ fName) + end + | _ -> "" + end + | _ -> "" + end; } aspect production trueConst diff --git a/grammars/silver/compiler/translation/java/core/NamedSignature.sv b/grammars/silver/compiler/translation/java/core/NamedSignature.sv index ea46c4e40..7ae023bb4 100644 --- a/grammars/silver/compiler/translation/java/core/NamedSignature.sv +++ b/grammars/silver/compiler/translation/java/core/NamedSignature.sv @@ -264,7 +264,7 @@ s"""private Object child_${n}; top.childStaticElem = if lookupBy(typeNameEq, ty, top.sigInhOccurs).isJust then s"\t\tchildInheritedAttributes[i_${n}] = new common.Lazy[count_inh__ON__${ntType.transTypeName}];\n" - else if ty.isNonterminal && !ty.isData || ty.isUniqueDecorated && ntType.isNonterminal + else if ty.isNonterminal && !ty.isData then s"\t\tchildInheritedAttributes[i_${n}] = new common.Lazy[${makeNTName(ntType.typeName)}.num_inh_attrs];\n" else ""; @@ -325,11 +325,13 @@ function makeChildDecSiteAccessCase String ::= env::Env flowEnv::FlowEnv lhsNtName::String prodName::String n::NamedSignatureElement { return - case lookupUniqueRefs(prodName, n.elementName, flowEnv), lookupRefDecSite(prodName, n.elementName, flowEnv) of - | [u], [v] -> s"\t\t\tcase i_${n.elementName}: return (context) -> ${refAccessTranslation(env, flowEnv, lhsNtName, v)};\n" - | _, _ -> "" + case lookupRefDecSite(prodName, rhsVertexType(n.elementName), flowEnv) of + | [v] -> s"\t\t\tcase i_${n.elementName}: return (context) -> ${refAccessTranslation(env, flowEnv, lhsNtName, v)};\n" + | _ -> "" end; } + +-- Translation of accessing the a tree that is shared in a position corresponding to some flow vertex type. fun refAccessTranslation String ::= env::Env flowEnv::FlowEnv lhsNtName::String v::VertexType = case v of | lhsVertexType_real() -> error("lhs can't be a ref decoration site") @@ -354,6 +356,32 @@ fun refAccessTranslation String ::= env::Env flowEnv::FlowEnv lhsNtName::String s"${refAccessTranslation(env, flowEnv, lhsNtName, parent)}.childDecorated(${makeProdName(prodName)}.i_${sigName})" end; +-- Translation of demanding the tree corresponding to a flow vertex type, to be shared. +-- Note that this is not cached; uniqueness analysis guarantees that it should only be demanded once. +fun sharedRefTranslation String ::= env::Env frame::BlockContext v::VertexType = + case v of + | rhsVertexType(sigName) -> s"context.createDecoratedChild(${frame.className}.i_${sigName})" + | localVertexType(fName) -> + case getValueDcl(fName, env) of + | dcl :: _ -> s"context.evalLocalDecorated(${dcl.attrOccursIndex})" + | _ -> error("Couldn't find decl for local " ++ fName) + end + | transAttrVertexType(rhsVertexType(sigName), transAttr) -> + case lookup(sigName, zip(frame.signature.inputNames, frame.signature.inputTypes)) of + | just(ty) when getOccursDcl(transAttr, ty.typeName, env) matches occDcl :: _ -> + s"context.childDecorated(${frame.className}.i_${sigName}).evalTrans(${occDcl.attrOccursIndex}, ${occDcl.attrOccursIndex}_inhs)" + | _ -> error("Couldn't find occurs dcl for " ++ transAttr ++ " on " ++ sigName) + end + | transAttrVertexType(localVertexType(fName), transAttr) -> + case getValueDcl(fName, env) of + | dcl :: _ when getOccursDcl(transAttr, dcl.typeScheme.typeName, env) matches occDcl :: _ -> + s"context.localDecorated(${dcl.attrOccursIndex}).evalTrans(${occDcl.attrOccursIndex}, ${occDcl.attrOccursIndex}_inhs)" + | _ -> error("Couldn't find occurs dcl for " ++ transAttr ++ " on " ++ fName) + end + | _ -> error("Sharing for invalid sort of tree " ++ v.vertexName) + end; + + function makeAnnoAssign String ::= n::NamedSignatureElement { diff --git a/grammars/silver/compiler/translation/java/core/ProductionBody.sv b/grammars/silver/compiler/translation/java/core/ProductionBody.sv index 6e98dce24..d0d8d6d78 100644 --- a/grammars/silver/compiler/translation/java/core/ProductionBody.sv +++ b/grammars/silver/compiler/translation/java/core/ProductionBody.sv @@ -104,9 +104,8 @@ top::ProductionStmt ::= 'local' 'attribute' a::Name '::' te::TypeExpr ';' if isDecorable(te.typerep, top.env) then s"\t\t//${top.unparse}\n" ++ - if te.typerep.isNonterminal || te.typerep.isUniqueDecorated - then - s"\t\t${top.frame.className}.localInheritedAttributes[${ugh_dcl_hack.attrOccursInitIndex}] = new common.Lazy[${makeNTName(te.typerep.typeName)}.num_inh_attrs];\n" + if te.typerep.isNonterminal + then s"\t\t${top.frame.className}.localInheritedAttributes[${ugh_dcl_hack.attrOccursInitIndex}] = new common.Lazy[${makeNTName(te.typerep.typeName)}.num_inh_attrs];\n" else s"\t\t${top.frame.className}.localInheritedAttributes[${ugh_dcl_hack.attrOccursInitIndex}] = new common.Lazy[${top.frame.className}.count_inh__ON__${makeIdName(transTypeNameWith(te.typerep, top.frame.signature.freeVariables))}];\n" else ""; @@ -117,12 +116,12 @@ top::ProductionStmt ::= 'local' 'attribute' a::Name '::' te::TypeExpr ';' else ""; top.translation = - case lookupLocalUniqueRefs(fName, top.flowEnv), lookupLocalRefDecSite(fName, top.flowEnv) of - | [u], [v] -> + case lookupRefDecSite(top.frame.fullName, localVertexType(fName), top.flowEnv) of + | [v] -> s"\t\t//${top.unparse}\n" ++ s"\t\t${top.frame.className}.localDecSites[${ugh_dcl_hack.attrOccursInitIndex}] = " ++ s"(context) -> ${refAccessTranslation(top.env, top.flowEnv, top.frame.lhsNtName, v)};\n" - | _, _ -> "" + | _ -> "" end; } @@ -138,9 +137,8 @@ top::ProductionStmt ::= 'production' 'attribute' a::Name '::' te::TypeExpr ';' if isDecorable(te.typerep, top.env) then s"\t\t//${top.unparse}\n" ++ - if te.typerep.isNonterminal || te.typerep.isUniqueDecorated - then - s"\t\t${top.frame.className}.localInheritedAttributes[${ugh_dcl_hack.attrOccursInitIndex}] = new common.Lazy[${makeNTName(te.typerep.typeName)}.num_inh_attrs];\n" + if te.typerep.isNonterminal + then s"\t\t${top.frame.className}.localInheritedAttributes[${ugh_dcl_hack.attrOccursInitIndex}] = new common.Lazy[${makeNTName(te.typerep.typeName)}.num_inh_attrs];\n" else s"\t\t${top.frame.className}.localInheritedAttributes[${ugh_dcl_hack.attrOccursInitIndex}] = new common.Lazy[${top.frame.className}.count_inh__ON__${makeIdName(transTypeNameWith(te.typerep, top.frame.signature.freeVariables))}];\n" else ""; @@ -151,12 +149,12 @@ top::ProductionStmt ::= 'production' 'attribute' a::Name '::' te::TypeExpr ';' else ""; top.translation = - case lookupLocalUniqueRefs(fName, top.flowEnv), lookupLocalRefDecSite(fName, top.flowEnv) of - | [u], [v] -> + case lookupRefDecSite(top.frame.fullName, localVertexType(fName), top.flowEnv) of + | [v] -> s"\t\t//${top.unparse}\n" ++ s"\t\t${top.frame.className}.localDecSites[${ugh_dcl_hack.attrOccursInitIndex}] = " ++ s"(context) -> ${refAccessTranslation(top.env, top.flowEnv, top.frame.lhsNtName, v)};\n" - | _, _ -> "" + | _ -> "" end; } diff --git a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv index 0dd041e35..431d6a3d6 100644 --- a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv +++ b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv @@ -102,9 +102,7 @@ ${namedSig.childStatic} super(${implode(", ", (if wantsTracking then ["origin"] else []) ++ (if isData then [] - else if any(map(\ x::NamedSignatureElement -> x.typerep.isUniqueDecorated, namedSig.inputElements)) - then ["true"] - else ["isUniqueInvocation"]) ++ + else ["isUniqueInvocation"]) ++ map((.annoRefElem), namedSig.namedInputElements))}); ${implode("", map(makeChildAssign, namedSig.inputElements))} ${contexts.contextInitTrans} diff --git a/grammars/silver/compiler/translation/java/core/Project.sv b/grammars/silver/compiler/translation/java/core/Project.sv index 6d0f68e51..487bae0a9 100644 --- a/grammars/silver/compiler/translation/java/core/Project.sv +++ b/grammars/silver/compiler/translation/java/core/Project.sv @@ -8,6 +8,7 @@ imports silver:compiler:definition:type:syntax; imports silver:compiler:definition:env; imports silver:compiler:definition:type; imports silver:compiler:definition:flow:env; +imports silver:compiler:definition:flow:ast; imports silver:compiler:analysis:uniqueness; imports silver:compiler:analysis:typechecking:core only finalType; diff --git a/grammars/silver/compiler/translation/java/type/Type.sv b/grammars/silver/compiler/translation/java/type/Type.sv index 9a057f362..1a099264f 100644 --- a/grammars/silver/compiler/translation/java/type/Type.sv +++ b/grammars/silver/compiler/translation/java/type/Type.sv @@ -179,16 +179,6 @@ top::Type ::= te::Type i::Type top.transTypeName = "Decorated_" ++ te.transTypeName; } -aspect production uniqueDecoratedType -top::Type ::= te::Type i::Type -{ - -- TODO: this should probably be a generic. e.g. "DecoratedNode" - top.transType = "common.DecoratedNode"; - top.transClassType = "common.DecoratedNode"; - top.transTypeRep = s"new common.DecoratedTypeRep(${te.transTypeRep})"; - top.transTypeName = "Decorated_" ++ te.transTypeName; -} - aspect production functionType top::Type ::= params::Integer namedParams::[String] { diff --git a/grammars/silver/core/Undecorate.sv b/grammars/silver/core/Undecorate.sv index bdc346fa4..a0154cf9a 100644 --- a/grammars/silver/core/Undecorate.sv +++ b/grammars/silver/core/Undecorate.sv @@ -13,19 +13,6 @@ foreign { "java": return "common.OriginsUtil.duplicatePoly(%x%.undecorate(), originCtx)"; } -@{- - - Undecorate a unique reference. - - - - @param x The reference to undecorate. - - @return A new, undecorated term coresponding to x. - -} -function newUnique -a ::= x::Decorated! a with i -{ return error("foreign function"); } -foreign { - "java": return "common.OriginsUtil.duplicatePoly(%x%.undecorate(), originCtx)"; -} - @{- - Type-safe cast of one decorated type into one with a smaller reference set. - From c15e108d04b1370ae214475feee9fe0d53176c57 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 22 Mar 2024 16:35:47 -0700 Subject: [PATCH 203/283] Add missing error message for concise function return type mismatch --- .../modification/concisefunctions/ConciseFunctions.sv | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv b/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv index c946c1d0c..7da3ca426 100644 --- a/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv +++ b/grammars/silver/compiler/modification/concisefunctions/ConciseFunctions.sv @@ -23,6 +23,10 @@ top::AGDcl ::= 'fun' id::Name ns::FunctionSignature '=' e::Expr ';' top.defs := [shortFunDef(top.grammarName, id.nameLoc, namedSig)]; local errCheck1 :: TypeCheck = check(e.typerep, namedSig.outputElement.typerep); + top.errors <- + if errCheck1.typeerror + then [errFromOrigin(e, s"Expected result type is ${errCheck1.rightpp}, but the expression has type ${errCheck1.leftpp}.")] + else []; e.downSubst = emptySubst(); errCheck1.downSubst = e.upSubst; From c40b3f029be23f123e8ace6f5626110b7d1b1ded Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 22 Mar 2024 16:45:13 -0700 Subject: [PATCH 204/283] Add test case for wrong concise function ret type --- test/silver_features/ConciseFunctions.sv | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/silver_features/ConciseFunctions.sv b/test/silver_features/ConciseFunctions.sv index 8ef967bc8..a799b0f22 100644 --- a/test/silver_features/ConciseFunctions.sv +++ b/test/silver_features/ConciseFunctions.sv @@ -51,4 +51,8 @@ equalityTest(getInhKey(bnd), "key", String, silver_tests); fun getInhKey2 {inhKey} subset i => String ::= x::Decorated TestBinding with i = x.inhKey; fun getVal2 {inhKey} subset i, attribute val i occurs on a => Integer ::= thing::Decorated a with i = thing.val; -equalityTest(getInhKey2(bnd), "key", String, silver_tests); \ No newline at end of file +equalityTest(getInhKey2(bnd), "key", String, silver_tests); + +wrongCode "Expected result type is Integer, but the expression has type Float." { + fun badRet Integer ::= s::String = 3.14; +} \ No newline at end of file From baccd21da94d23ec44919b2d49da1c1cefd28e6c Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 25 Mar 2024 12:07:26 -0700 Subject: [PATCH 205/283] Initial work on completeness checking for inh attributes supplied via dispatch signatures, currently broken --- .../compiler/analysis/warnings/flow/Inh.sv | 44 +++++++++---- .../analysis/warnings/flow/MwdaFlag.sv | 2 + .../analysis/warnings/flow/SIgSharing.sv | 64 +++++++++++++++++++ .../silver/compiler/definition/env/DclInfo.sv | 5 +- .../compiler/definition/flow/ast/Flow.sv | 47 ++++++++++---- .../compiler/definition/flow/env/Expr.sv | 20 +++++- .../compiler/definition/flow/env/FlowEnv.sv | 12 +++- 7 files changed, 165 insertions(+), 29 deletions(-) create mode 100644 grammars/silver/compiler/analysis/warnings/flow/SIgSharing.sv diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index b175740f4..5f0c670ef 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -47,9 +47,9 @@ Either ::= args::[String] -------------------------------------------------------------------------------- {-- - - Given a name of a child, return whether it has a normal decorated nonterminal - - type (covered by the more specific checks on accesses from references) or a - - unique decorated nonterminal type decorated with the attr. + - Given a name of a child, return whether it has a decorated nonterminal + - type (covered by the more specific checks on accesses from references) + - decorated with the attr. - True if nonsensicle. -} function sigAttrViaReference @@ -60,9 +60,9 @@ Boolean ::= sigName::String attrName::String ns::NamedSignature e::Env } {-- - - Given a name of a local, return whether it has a normal decorated nonterminal - - type (covered by the more specific checks on accesses from references) or a - - unique decorated nonterminal type decorated with the attr. + - Given a name of a local, return whether it has a decorated nonterminal + - type (covered by the more specific checks on accesses from references) + - decorated with the attr. - True if nonsensicle. -} function localAttrViaReference @@ -74,6 +74,26 @@ Boolean ::= sigName::String attrName::String e::Env return null(d) || !isDecorable(ty, e) || contains(attrName, getMinRefSet(ty, e)); } +{-- + - Given the name of a child, return whether it is shared in the production's + - signature, with all productions forwarding to this production supplying the + - inherited attribute to the child. + -} +fun sigAttrViaSharing +Boolean ::= sigName::String attrName::String ns::NamedSignature flowEnv::FlowEnv realEnv::Env = + lookup(sigName, zip(ns.inputNames, ns.inputElements)).fromJust.elementShared && + all(map( + \ s::(String, VertexType) -> !remoteProdMissingInhEq(s.1, s.2, attrName, flowEnv), + lookupSigShareSites(ns.fullName, sigName, flowEnv) ++ + case getValueDcl(ns.fullName, realEnv) of + | v :: _ when v.implementedSignature matches just(sig) -> + lookupSigShareSites( + sig.fullName, + head(drop(positionOf(sigName, ns.inputNames), sig.inputNames)), + flowEnv) + | _ -> [] + end)); + {-- - Used as a stop-gap measure to ensure equations exist. - Given a needed equation (represented by FlowVertex 'v'), @@ -120,6 +140,7 @@ function checkEqDeps | rhsInhVertex(sigName, attrName) -> if !null(lookupInh(prodName, sigName, attrName, flowEnv)) || sigAttrViaReference(sigName, attrName, ns, realEnv) + || sigAttrViaSharing(sigName, attrName, ns, flowEnv, realEnv) || !null(lookupRefDecSite(prodName, rhsVertexType(sigName), flowEnv)) || case splitTransAttrInh(attrName) of | just((transAttr, _)) -> @@ -168,7 +189,7 @@ function checkEqDeps -- A dependency on a projected equation in another production. -- Again, SYN are safe. We need to check only for INH. | subtermInhVertex(parent, termProdName, sigName, attrName) -> - if !remoteProdMissingInhEq(termProdName, sigName, attrName, flowEnv) + if !remoteProdMissingInhEq(termProdName, rhsVertexType(sigName), attrName, flowEnv) then [] else [mwdaWrnAmbientOrigin(config, s"Equation has transitive dependencies on a missing remote equation.\n\tRemote production: ${termProdName}\n\tChild: ${sigName}\n\tMissing inherited equations for: ${attrName}")] | subtermSynVertex(parent, termProdName, sigName, attrName) -> [] @@ -925,7 +946,7 @@ top::VarBinder ::= n::Name -- Child: top.bindingName -- Inh: each of requiredInhs local missingInhs :: [String] = - filter(remoteProdMissingInhEq(top.matchingAgainst.fromJust.fullName, top.bindingName, _, top.flowEnv), + filter(remoteProdMissingInhEq(top.matchingAgainst.fromJust.fullName, rhsVertexType(top.bindingName), _, top.flowEnv), removeAll(getMinRefSet(top.bindingType, top.env), requiredInhs)); top.errors <- @@ -937,11 +958,12 @@ top::VarBinder ::= n::Name else []; } --- Is this there an equation for this inh attr on any decoration site for this child? +-- Is this there an equation for this inh attr on any decoration site for this vertex? fun remoteProdMissingInhEq -Boolean ::= prodName::String sigName::String attrName::String flowEnv::FlowEnv = !any(unzipWith( +Boolean ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv = + !any(unzipWith( vertexHasInhEq(_, _, attrName, flowEnv), - lookupAllDecSites(prodName, rhsVertexType(sigName), flowEnv))); + lookupAllDecSites(prodName, vt, flowEnv))); -- Find all decoration sites productions/vertices for this vertex fun lookupAllDecSites [(String, VertexType)] ::= prodName::String vt::VertexType flowEnv::FlowEnv = diff --git a/grammars/silver/compiler/analysis/warnings/flow/MwdaFlag.sv b/grammars/silver/compiler/analysis/warnings/flow/MwdaFlag.sv index 7d6ffb62d..ef30cddd2 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/MwdaFlag.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/MwdaFlag.sv @@ -16,6 +16,7 @@ top::CmdArgs ::= rest::CmdArgs top.warnEqdef = true; top.warnOrphaned = true; top.warnFwd = true; + top.warnSharing = true; forwards to rest; } @@ -28,6 +29,7 @@ top::CmdArgs ::= rest::CmdArgs top.warnEqdef = true; top.warnOrphaned = true; top.warnFwd = true; + top.warnSharing = true; } aspect function parseArgs diff --git a/grammars/silver/compiler/analysis/warnings/flow/SIgSharing.sv b/grammars/silver/compiler/analysis/warnings/flow/SIgSharing.sv new file mode 100644 index 000000000..84030797d --- /dev/null +++ b/grammars/silver/compiler/analysis/warnings/flow/SIgSharing.sv @@ -0,0 +1,64 @@ +grammar silver:compiler:analysis:warnings:flow; + +synthesized attribute warnSharing :: Boolean occurs on CmdArgs; + +aspect production endCmdArgs +top::CmdArgs ::= l::[String] +{ + top.warnSharing = false; +} +abstract production warnSharingFlag +top::CmdArgs ::= rest::CmdArgs +{ + top.warnSharing = true; + forwards to rest; +} +aspect function parseArgs +Either ::= args::[String] +{ + flags <- [ + flagSpec(name="--warn-sharing", paramString=nothing(), + help="warn about improper use of tree sharing", + flagParser=flag(warnSharingFlag))]; +} + +-- TODO: Handle dependencies for inh overrides on forward/forward prod attrs +aspect production productionReference +top::Expr ::= @q::QName +{ + top.errors <- + if !top.config.warnSharing + || !q.lookupValue.found + || !any(map((.elementShared), q.lookupValue.dcl.namedSignature.inputElements)) + || q.lookupValue.dcl.implementedSignature.isJust + then [] + else case top.decSiteVertexInfo of + | just(forwardVertexType_real()) -> [] + | just(localVertexType(fName)) when isForwardProdAttr(fName, top.env) -> [] + | _ -> [mwdaWrnFromOrigin(top, s"Production ${q.name} has shared children in its signature, and can only be applied in the root position of a forward or forward production attribute equation.")] + end; +} + +aspect production dispatchApplication +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs +{ + top.errors <- + if !top.config.warnSharing + then [] + else case top.decSiteVertexInfo of + | just(forwardVertexType_real()) -> [] + | just(localVertexType(fName)) when isForwardProdAttr(fName, top.env) -> [] + | _ -> [mwdaWrnFromOrigin(e, s"Dispatch can only be applied in the root position of a forward or forward production attribute equation.")] + end; +} + +aspect production presentAppExpr +top::AppExpr ::= e::Expr +{ + top.errors <- + case e.flowVertexInfo of + | nothing() when top.config.warnSharing && sigIsShared -> + [mwdaWrnFromOrigin(e, "Shared tree must correspond to a known decoration site")] + | _ -> [] + end; +} diff --git a/grammars/silver/compiler/definition/env/DclInfo.sv b/grammars/silver/compiler/definition/env/DclInfo.sv index 4fa9aa34c..c424a47f4 100644 --- a/grammars/silver/compiler/definition/env/DclInfo.sv +++ b/grammars/silver/compiler/definition/env/DclInfo.sv @@ -30,6 +30,7 @@ synthesized attribute definedMembers :: [String]; -- values synthesized attribute namedSignature :: NamedSignature; +synthesized attribute implementedSignature :: Maybe; synthesized attribute hasForward :: Boolean; -- occurs @@ -51,7 +52,7 @@ inherited attribute givenSubstitution :: Substitution; closed nonterminal ValueDclInfo with sourceGrammar, sourceLocation, fullName, compareTo, isEqual, - typeScheme, namedSignature, hasForward, substitutedDclInfo, givenSubstitution; + typeScheme, namedSignature, implementedSignature, hasForward, substitutedDclInfo, givenSubstitution; propagate isEqual on ValueDclInfo excluding globalValueDcl, classMemberDcl; aspect default production @@ -59,6 +60,7 @@ top::ValueDclInfo ::= { -- Values that are not fun/prod have this valid default. top.namedSignature = bogusNamedSignature(); + top.implementedSignature = nothing(); top.hasForward = false; top.substitutedDclInfo = error("Internal compiler error: must be defined for all value declarations that are production attributes"); @@ -121,6 +123,7 @@ top::ValueDclInfo ::= ns::NamedSignature dispatch::Maybe hasForw drop(length(dSig.inputElements), ns.inputTypes) ++ [dispatchType(dSig)])) end; + top.implementedSignature = dispatch; top.hasForward = hasForward; } abstract production funDcl diff --git a/grammars/silver/compiler/definition/flow/ast/Flow.sv b/grammars/silver/compiler/definition/flow/ast/Flow.sv index fc6c1dd84..f2e792770 100644 --- a/grammars/silver/compiler/definition/flow/ast/Flow.sv +++ b/grammars/silver/compiler/definition/flow/ast/Flow.sv @@ -10,45 +10,45 @@ grammar silver:compiler:definition:flow:ast; - - extraEq (handling collections '<-') - which the thesis does not address. -} -data nonterminal FlowDef with synTreeContribs, inhTreeContribs, defTreeContribs, fwdTreeContribs, fwdInhTreeContribs, prodTreeContribs, prodGraphContribs, flowEdges, localInhTreeContribs, suspectFlowEdges, hostSynTreeContribs, nonSuspectContribs, localTreeContribs, refPossibleDecSiteContribs, refDecSiteContribs; -data nonterminal FlowDefs with synTreeContribs, inhTreeContribs, defTreeContribs, fwdTreeContribs, fwdInhTreeContribs, prodTreeContribs, prodGraphContribs, localInhTreeContribs, hostSynTreeContribs, nonSuspectContribs, localTreeContribs, refPossibleDecSiteContribs, refDecSiteContribs; +data nonterminal FlowDef with flowEdges, suspectFlowEdges; +data nonterminal FlowDefs; {-- lookup (production, attribute) to find synthesized equations - Used to ensure a necessary lhs.syn equation exists. - Also decides whether to add a forward or default equation while computing flow types. -} -monoid attribute synTreeContribs :: [Pair]; +monoid attribute synTreeContribs :: [(String, FlowDef)]; {-- lookup (production, sig, attribute) to find inherited equation - Used to ensure a necessary rhs.inh equation exists. -} -monoid attribute inhTreeContribs :: [Pair]; +monoid attribute inhTreeContribs :: [(String, FlowDef)]; {-- lookup (nonterminal, attribute) to find default syn equations - Used to obtain default equation dependencies, when it exists. -} -monoid attribute defTreeContribs :: [Pair]; +monoid attribute defTreeContribs :: [(String, FlowDef)]; {-- lookup (production) to find forward equations. - Decides whether default or forward equations should be added. -} -monoid attribute fwdTreeContribs :: [Pair]; +monoid attribute fwdTreeContribs :: [(String, FlowDef)]; {-- lookup (production, attr) to find forward INHERITED equations - Used to ensure equations for inherited attributes exist for all inh of a fwd. -} -monoid attribute fwdInhTreeContribs :: [Pair]; +monoid attribute fwdInhTreeContribs :: [(String, FlowDef)]; {-- lookup (production, local, attr) to find local INHERITED equations. - ONLY used to check whether an equation exists. -} -monoid attribute localInhTreeContribs :: [Pair]; +monoid attribute localInhTreeContribs :: [(String, FlowDef)]; {-- lookup (production, local) to find the local equation -} -monoid attribute localTreeContribs :: [Pair]; +monoid attribute localTreeContribs :: [(String, FlowDef)]; {-- lookup (nonterminal) to find all non-forwarding production. - ONLY used to determine all productions that need an equation for a new attribute. -} -monoid attribute prodTreeContribs :: [Pair]; +monoid attribute prodTreeContribs :: [(String, FlowDef)]; {-- find all equations having to do DIRECTLY with a production (directly meaning e.g. no default equations, even if they might affect it) These FlowDefs MUST have a flowEdges for this production. -} -monoid attribute prodGraphContribs :: [Pair]; +monoid attribute prodGraphContribs :: [(String, FlowDef)]; {-- Edge lists from equations - ONLY used to extract edges for a production graph from production-internal flowDefs. -} @@ -61,7 +61,7 @@ synthesized attribute flowEdges :: [(FlowVertex, FlowVertex)]; synthesized attribute suspectFlowEdges :: [(FlowVertex, FlowVertex)]; {-- A list of extension syn attr occurrences, subject to ft lower bounds. -} -monoid attribute hostSynTreeContribs :: [Pair]; +monoid attribute hostSynTreeContribs :: [(String, FlowDef)]; {-- A list of attributes for a production that are non-suspect -} monoid attribute nonSuspectContribs :: [Pair]; @@ -73,7 +73,19 @@ monoid attribute refPossibleDecSiteContribs :: [(String, VertexType)]; {-- lookup dec site to find places that a unique reference to this ref site are *unconditionally* decorated. -} monoid attribute refDecSiteContribs :: [(String, VertexType)]; -propagate synTreeContribs, inhTreeContribs, defTreeContribs, fwdTreeContribs, fwdInhTreeContribs, localInhTreeContribs, localTreeContribs, prodTreeContribs, prodGraphContribs, hostSynTreeContribs, nonSuspectContribs, refPossibleDecSiteContribs, refDecSiteContribs +monoid attribute sigShareContribs :: [(String, String, VertexType)]; + +attribute + synTreeContribs, inhTreeContribs, defTreeContribs, + fwdTreeContribs, fwdInhTreeContribs, localInhTreeContribs, localTreeContribs, prodTreeContribs, + prodGraphContribs, hostSynTreeContribs, nonSuspectContribs, + refPossibleDecSiteContribs, refDecSiteContribs, sigShareContribs + occurs on FlowDefs, FlowDef; +propagate + synTreeContribs, inhTreeContribs, defTreeContribs, + fwdTreeContribs, fwdInhTreeContribs, localInhTreeContribs, localTreeContribs, prodTreeContribs, + prodGraphContribs, hostSynTreeContribs, nonSuspectContribs, + refPossibleDecSiteContribs, refDecSiteContribs, sigShareContribs on FlowDefs; abstract production consFlow @@ -106,6 +118,7 @@ top::FlowDef ::= top.suspectFlowEdges = []; -- flowEdges is required, but suspect is typically not! top.refPossibleDecSiteContribs := []; top.refDecSiteContribs := []; + top.sigShareContribs := []; -- require prodGraphContibs, flowEdges } @@ -427,6 +440,14 @@ top::FlowDef ::= prod::String nt::String ref::VertexType decSite::VertexType top.refDecSiteContribs := if alwaysDec then top.refPossibleDecSiteContribs else []; } +abstract production sigShareSite +top::FlowDef ::= sourceProd::String source::VertexType targetProd::String target::String +{ + top.prodGraphContribs := []; + top.flowEdges = []; + top.sigShareContribs := [(crossnames(targetProd, target), sourceProd, source)]; +} + -- fun crossnames String ::= a::String b::String = a ++ " @ " ++ b; diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index 3ce773a29..09e03eb54 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -165,7 +165,7 @@ top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs | productionReference(q) -> just(q.lookupValue.dcl.namedSignature) | _ -> nothing() end; - e.decSiteVertexInfo = nothing(); + e.decSiteVertexInfo = top.decSiteVertexInfo; es.decSiteVertexInfo = top.decSiteVertexInfo; es.alwaysDecorated = top.alwaysDecorated; } @@ -193,7 +193,7 @@ top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs | _, dispatchType(ns) -> just(ns) | _, _ -> error("dispatchApplication: unexpected type") end; - e.decSiteVertexInfo = nothing(); + e.decSiteVertexInfo = top.decSiteVertexInfo; es.decSiteVertexInfo = top.decSiteVertexInfo; es.alwaysDecorated = case e of @@ -226,11 +226,25 @@ top::AppExpr ::= e::Expr end; e.decSiteVertexInfo = case top.decSiteVertexInfo, top.appProd of - | just(parent), just(ns) when isDecorable(e.finalType, top.env) -> -- TODO: Signature sharing??? + | just(parent), just(ns) when isDecorable(e.finalType, top.env) -> just(subtermVertexType(parent, ns.fullName, sigName)) | _, _ -> nothing() end; e.alwaysDecorated = top.alwaysDecorated && e.decSiteVertexInfo.isJust; + + production sigIsShared::Boolean = + case top.appProd of + | just(ns) -> + top.appExprIndex < length(ns.inputNames) && + head(drop(top.appExprIndex, ns.inputElements)).elementShared + | _ -> false + end; + top.flowDefs <- + case top.appProd, e.flowVertexInfo of + | just(ns), just(v) when sigIsShared -> + [sigShareSite(top.frame.fullName, v, ns.fullName, sigName)] + | _, _ -> [] + end; } aspect production noteAttachment diff --git a/grammars/silver/compiler/definition/flow/env/FlowEnv.sv b/grammars/silver/compiler/definition/flow/env/FlowEnv.sv index 7e8f640c7..2c4f3c725 100644 --- a/grammars/silver/compiler/definition/flow/env/FlowEnv.sv +++ b/grammars/silver/compiler/definition/flow/env/FlowEnv.sv @@ -15,7 +15,11 @@ monoid attribute flowDefs :: [FlowDef]; monoid attribute specDefs :: [(String, String, [String], [String])]; -- (nt, attr, [inhs], [referenced flow specs]) monoid attribute refDefs :: [(String, [String])]; -data nonterminal FlowEnv with synTree, inhTree, defTree, fwdTree, prodTree, fwdInhTree, refTree, sharedRefTree, refPossibleDecSiteTree, refDecSiteTree, localInhTree, localTree, nonSuspectTree, hostSynTree, specTree, prodGraphTree; +data nonterminal FlowEnv with + synTree, inhTree, defTree, fwdTree, prodTree, fwdInhTree, refTree, + sharedRefTree, refPossibleDecSiteTree, refDecSiteTree, sigShareTree, + localInhTree, localTree, nonSuspectTree, hostSynTree, specTree, + prodGraphTree; synthesized attribute synTree :: EnvTree; synthesized attribute inhTree :: EnvTree; @@ -27,6 +31,7 @@ synthesized attribute refTree :: EnvTree<[String]>; synthesized attribute sharedRefTree :: EnvTree; synthesized attribute refPossibleDecSiteTree :: EnvTree; synthesized attribute refDecSiteTree :: EnvTree; +synthesized attribute sigShareTree :: EnvTree<(String, VertexType)>; synthesized attribute localInhTree ::EnvTree; synthesized attribute localTree :: EnvTree; synthesized attribute nonSuspectTree :: EnvTree<[String]>; @@ -50,6 +55,7 @@ top::FlowEnv ::= top.sharedRefTree = directBuildTree(sharedRefContribs); top.refPossibleDecSiteTree = directBuildTree(d.refPossibleDecSiteContribs); top.refDecSiteTree = directBuildTree(d.refDecSiteContribs); + top.sigShareTree = directBuildTree(d.sigShareContribs); top.localInhTree = directBuildTree(d.localInhTreeContribs); top.localTree = directBuildTree(d.localTreeContribs); top.nonSuspectTree = directBuildTree(d.nonSuspectContribs); @@ -97,6 +103,10 @@ fun lookupRefPossibleDecSites [VertexType] ::= prod::String v::VertexType e::Flo fun lookupRefDecSite [VertexType] ::= prod::String v::VertexType e::FlowEnv = searchEnvTree(s"${prod}:${v.vertexName}", e.refDecSiteTree); +-- places where this child was decorated in a production forwarding to this one +fun lookupSigShareSites [(String, VertexType)] ::= prod::String sigName::String e::FlowEnv = + searchEnvTree(crossnames(prod, sigName), e.sigShareTree); + {-- - This is a glorified lambda function, to help look for equations. - Literally, we're just checking for null here. From 8b1f57080eec0b19318343382bd9d1a1f1419359 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 26 Mar 2024 11:50:01 -0500 Subject: [PATCH 206/283] Unrelated fix, don't include NativeSerializationException class name in native serialize/deserialize error message --- runtime/java/src/common/Reflection.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/java/src/common/Reflection.java b/runtime/java/src/common/Reflection.java index d8f60b1d3..607435434 100644 --- a/runtime/java/src/common/Reflection.java +++ b/runtime/java/src/common/Reflection.java @@ -459,7 +459,7 @@ public static NEither nativeSerialize(Object x) { return new Pright(arr.toByteArray()); } catch (NativeSerializationException e) { - return new Pleft(new StringCatter("Native serialize failed: " + e.toString())); + return new Pleft(new StringCatter("Native serialize failed: " + e.getMessage())); } catch (Exception e) { String m = "Native serialize failed: Unknown error: " + e.toString(); System.err.println(m); @@ -596,7 +596,7 @@ public static NEither nativeDeserialize(final TypeRep expected, final byte[] arr return new Pright(v); } catch (NativeSerializationException e) { - return new Pleft(new StringCatter("Native deserialize failed: " + e.toString())); + return new Pleft(new StringCatter("Native deserialize failed: " + e.getMessage())); } catch (IOException e) { String m = "Native deserialize failed: Unknown Error: " + e.toString(); System.err.println(m); From 93b3a64bab982626354ff083864782cf0b9d8b8e Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 26 Mar 2024 18:36:50 -0500 Subject: [PATCH 207/283] Finish updating missing inh eq checks to consider sig sharing --- .../compiler/analysis/warnings/flow/Inh.sv | 103 +++++++++++------- .../compiler/definition/flow/env/Expr.sv | 30 ++++- .../compiler/extension/rewriting/Rewriting.sv | 3 + .../primitivepattern/PrimitiveMatch.sv | 8 +- .../primitivepattern/VarBinders.sv | 1 - 5 files changed, 101 insertions(+), 44 deletions(-) diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index 5f0c670ef..36e84f564 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -74,26 +74,6 @@ Boolean ::= sigName::String attrName::String e::Env return null(d) || !isDecorable(ty, e) || contains(attrName, getMinRefSet(ty, e)); } -{-- - - Given the name of a child, return whether it is shared in the production's - - signature, with all productions forwarding to this production supplying the - - inherited attribute to the child. - -} -fun sigAttrViaSharing -Boolean ::= sigName::String attrName::String ns::NamedSignature flowEnv::FlowEnv realEnv::Env = - lookup(sigName, zip(ns.inputNames, ns.inputElements)).fromJust.elementShared && - all(map( - \ s::(String, VertexType) -> !remoteProdMissingInhEq(s.1, s.2, attrName, flowEnv), - lookupSigShareSites(ns.fullName, sigName, flowEnv) ++ - case getValueDcl(ns.fullName, realEnv) of - | v :: _ when v.implementedSignature matches just(sig) -> - lookupSigShareSites( - sig.fullName, - head(drop(positionOf(sigName, ns.inputNames), sig.inputNames)), - flowEnv) - | _ -> [] - end)); - {-- - Used as a stop-gap measure to ensure equations exist. - Given a needed equation (represented by FlowVertex 'v'), @@ -140,7 +120,7 @@ function checkEqDeps | rhsInhVertex(sigName, attrName) -> if !null(lookupInh(prodName, sigName, attrName, flowEnv)) || sigAttrViaReference(sigName, attrName, ns, realEnv) - || sigAttrViaSharing(sigName, attrName, ns, flowEnv, realEnv) + || sigNameIsShared(sigName, ns) && null(sharingSitesLackingSigAttr(sigName, attrName, ns, flowEnv, realEnv)) || !null(lookupRefDecSite(prodName, rhsVertexType(sigName), flowEnv)) || case splitTransAttrInh(attrName) of | just((transAttr, _)) -> @@ -189,7 +169,7 @@ function checkEqDeps -- A dependency on a projected equation in another production. -- Again, SYN are safe. We need to check only for INH. | subtermInhVertex(parent, termProdName, sigName, attrName) -> - if !remoteProdMissingInhEq(termProdName, rhsVertexType(sigName), attrName, flowEnv) + if remoteProdHasInhEq(termProdName, rhsVertexType(sigName), attrName, flowEnv, realEnv) then [] else [mwdaWrnAmbientOrigin(config, s"Equation has transitive dependencies on a missing remote equation.\n\tRemote production: ${termProdName}\n\tChild: ${sigName}\n\tMissing inherited equations for: ${attrName}")] | subtermSynVertex(parent, termProdName, sigName, attrName) -> [] @@ -698,9 +678,17 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur isEquationMissing( lookupInh(top.frame.fullName, lq.lookupValue.fullName, _, top.flowEnv), _), - removeAll(getMinRefSet(lq.lookupValue.typeScheme.typerep, top.env), - set:toList(inhDeps)))) + getMinRefSet(lq.lookupValue.typeScheme.typerep, top.env))) in if null(inhs) then [] + else if sigNameIsShared(lq.lookupValue.fullName, top.frame.signature) + then + flatMap(\ inh::String -> + case sharingSitesLackingSigAttr(lq.lookupValue.fullName, inh, top.frame.signature, top.flowEnv, top.env) of + | [] -> [] + | sites -> [mwdaWrnFromOrigin(top, + s"Access of syn attribute ${q.name} on ${e.unparse} requires missing inherited attribute ${inh} to be supplied in the following places: " ++ + implode(", ", map(\ s::(String, VertexType) -> s"${s.2.vertexName} in production ${s.1}", sites)))] + end, inhs) else [mwdaWrnFromOrigin(top, "Access of syn attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] end else [] @@ -721,8 +709,7 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur isEquationMissing( lookupLocalInh(top.frame.fullName, lq.lookupValue.fullName, _, top.flowEnv), _), - removeAll(getMinRefSet(lq.lookupValue.typeScheme.typerep, top.env), - set:toList(inhDeps)))) + set:toList(inhDeps))) in if null(inhs) then [] else [mwdaWrnFromOrigin(top, "Access of syn attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] end @@ -839,10 +826,18 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur isEquationMissing( lookupInh(top.frame.fullName, lq.lookupValue.fullName, _, top.flowEnv), _), - removeAll(getMinRefSet(lq.lookupValue.typeScheme.typerep, top.env), - set:toList(inhDeps)))) + set:toList(inhDeps))) in if null(inhs) then [] - else [mwdaWrnFromOrigin(top, "Access of syn attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] + else if sigNameIsShared(lq.lookupValue.fullName, top.frame.signature) + then + flatMap(\ inh::String -> + case sharingSitesLackingSigAttr(lq.lookupValue.fullName, inh, top.frame.signature, top.flowEnv, top.env) of + | [] -> [] + | sites -> [mwdaWrnFromOrigin(top, + s"Access of trans attribute ${q.name} on ${e.unparse} requires missing inherited attribute ${inh} to be supplied in the following places: " ++ + implode(", ", map(\ s::(String, VertexType) -> s"${s.2.vertexName} in production ${s.1}", sites)))] + end, inhs) + else [mwdaWrnFromOrigin(top, "Access of trans attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] end else [] | localReference(lq) -> @@ -862,10 +857,9 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur isEquationMissing( lookupLocalInh(top.frame.fullName, lq.lookupValue.fullName, _, top.flowEnv), _), - removeAll(getMinRefSet(lq.lookupValue.typeScheme.typerep, top.env), - set:toList(inhDeps)))) + set:toList(inhDeps))) in if null(inhs) then [] - else [mwdaWrnFromOrigin(top, "Access of syn attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] + else [mwdaWrnFromOrigin(top, "Access of trans attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] end else [] | _ -> [] @@ -946,7 +940,7 @@ top::VarBinder ::= n::Name -- Child: top.bindingName -- Inh: each of requiredInhs local missingInhs :: [String] = - filter(remoteProdMissingInhEq(top.matchingAgainst.fromJust.fullName, rhsVertexType(top.bindingName), _, top.flowEnv), + filter(remoteProdMissingInhEq(top.matchingAgainst.fromJust.fullName, rhsVertexType(top.bindingName), _, top.flowEnv, top.env), removeAll(getMinRefSet(top.bindingType, top.env), requiredInhs)); top.errors <- @@ -958,14 +952,49 @@ top::VarBinder ::= n::Name else []; } --- Is this there an equation for this inh attr on any decoration site for this vertex? +-- Is this child shared in the signature of the production? +fun sigNameIsShared Boolean ::= sigName::String ns::NamedSignature = + lookup(sigName, zip(ns.inputNames, ns.inputElements)).fromJust.elementShared; + +{-- + - Given the name of a child shared in the production's signature, + - return the list of all productions/places this child can be decorated before forwarding to this production, + - where the needed inherited attribute is not supplied. + -} +fun sharingSitesLackingSigAttr +[(String, VertexType)] ::= sigName::String attrName::String ns::NamedSignature flowEnv::FlowEnv realEnv::Env = + filter( + \ s::(String, VertexType) -> !vertexHasInhEq(s.1, s.2, attrName, flowEnv), + lookupSigShareSites(ns.fullName, sigName, flowEnv) ++ + case getValueDcl(ns.fullName, realEnv) of + | v :: _ when v.implementedSignature matches just(sig) -> + lookupSigShareSites( + sig.fullName, + head(drop(positionOf(sigName, ns.inputNames), sig.inputNames)), + flowEnv) + | _ -> [] + end); + +-- Just a helper for filtering, above. fun remoteProdMissingInhEq -Boolean ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv = - !any(unzipWith( +Boolean ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv realEnv::Env = + !remoteProdHasInhEq(prodName, vt, attrName, flowEnv, realEnv); + +-- Is this there an equation for this inh attr on any decoration site for this vertex? +fun remoteProdHasInhEq +Boolean ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv realEnv::Env = + any(unzipWith( vertexHasInhEq(_, _, attrName, flowEnv), - lookupAllDecSites(prodName, vt, flowEnv))); + lookupAllDecSites(prodName, vt, flowEnv))) || + case vt of + | rhsVertexType(sigName) when getValueDcl(prodName, realEnv) matches dcl :: _ -> + sigNameIsShared(sigName, dcl.namedSignature) && + null(sharingSitesLackingSigAttr(sigName, attrName, dcl.namedSignature, flowEnv, realEnv)) + | _ -> false + end; -- Find all decoration sites productions/vertices for this vertex +-- TODO: This doesn't gracefully handle cycles in sharing. fun lookupAllDecSites [(String, VertexType)] ::= prodName::String vt::VertexType flowEnv::FlowEnv = (prodName, vt) :: case vt of diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index 09e03eb54..053478ea6 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -138,7 +138,10 @@ top::Expr ::= @q::QName -- The named signature of the applied production. -- Note that we don't project functions at the moment, since we don't build function flow graphs during inference. inherited attribute appProd::Maybe occurs on AppExprs, AppExpr; -propagate appProd on AppExprs; + +-- The offset of the first supplied signature element, if the production implements a dispatch signautre and has extra children. +inherited attribute appIndexOffset::Integer occurs on AppExprs, AppExpr; +propagate appProd, appIndexOffset on AppExprs; aspect production application top::Expr ::= e::Expr '(' es::AppExprs ',' anns::AnnoAppExprs ')' @@ -154,6 +157,7 @@ top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs es.decSiteVertexInfo = nothing(); es.alwaysDecorated = false; es.appProd = nothing(); + es.appIndexOffset = 0; } aspect production functionInvocation @@ -165,6 +169,14 @@ top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs | productionReference(q) -> just(q.lookupValue.dcl.namedSignature) | _ -> nothing() end; + es.appIndexOffset = + case e of + | productionReference(q) when q.lookupValue.dcl.implementedSignature matches just(dSig) -> + if length(q.lookupValue.dcl.namedSignature.inputElements) > length(dSig.inputElements) + then length(dSig.inputElements) + else 0 + | _ -> 0 + end; e.decSiteVertexInfo = top.decSiteVertexInfo; es.decSiteVertexInfo = top.decSiteVertexInfo; es.alwaysDecorated = top.alwaysDecorated; @@ -178,6 +190,14 @@ top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs | productionReference(q) -> just(q.lookupValue.dcl.namedSignature) | _ -> nothing() end; + es.appIndexOffset = + case e of + | productionReference(q) when q.lookupValue.dcl.implementedSignature matches just(dSig) -> + if length(q.lookupValue.dcl.namedSignature.inputElements) > length(dSig.inputElements) + then length(dSig.inputElements) + else 0 + | _ -> 0 + end; e.decSiteVertexInfo = nothing(); es.decSiteVertexInfo = nothing(); es.alwaysDecorated = false; @@ -193,6 +213,7 @@ top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs | _, dispatchType(ns) -> just(ns) | _, _ -> error("dispatchApplication: unexpected type") end; + es.appIndexOffset = 0; e.decSiteVertexInfo = top.decSiteVertexInfo; es.decSiteVertexInfo = top.decSiteVertexInfo; es.alwaysDecorated = @@ -207,15 +228,17 @@ top::AnnoExpr ::= qn::QName '=' e::AppExpr { e.decSiteVertexInfo = nothing(); e.appProd = nothing(); + e.appIndexOffset = 0; e.alwaysDecorated = false; } aspect production presentAppExpr top::AppExpr ::= e::Expr { + production sigIndex::Integer = top.appExprIndex + top.appIndexOffset; production sigName::String = case top.appProd of - | just(ns) when top.appExprIndex < length(ns.inputNames) -> head(drop(top.appExprIndex, ns.inputNames)) + | just(ns) when sigIndex < length(ns.inputNames) -> head(drop(sigIndex, ns.inputNames)) | _ -> "err" end; top.flowDefs <- @@ -235,8 +258,7 @@ top::AppExpr ::= e::Expr production sigIsShared::Boolean = case top.appProd of | just(ns) -> - top.appExprIndex < length(ns.inputNames) && - head(drop(top.appExprIndex, ns.inputElements)).elementShared + sigIndex < length(ns.inputNames) && head(drop(sigIndex, ns.inputElements)).elementShared | _ -> false end; top.flowDefs <- diff --git a/grammars/silver/compiler/extension/rewriting/Rewriting.sv b/grammars/silver/compiler/extension/rewriting/Rewriting.sv index dd60cf912..78fac1803 100644 --- a/grammars/silver/compiler/extension/rewriting/Rewriting.sv +++ b/grammars/silver/compiler/extension/rewriting/Rewriting.sv @@ -52,6 +52,9 @@ top::Expr ::= 'traverse' n::QName '(' es::AppExprs ',' anns::AnnoAppExprs ')' local annotations::[String] = map(fst, n.lookupValue.typeScheme.typerep.namedTypes); es.appExprTypereps = repeat(nonterminalType("silver:rewrite:Strategy", [], false, false), numChildren); es.appExprApplied = n.unparse; + es.decSiteVertexInfo = nothing(); + es.appProd = nothing(); + es.appIndexOffset = 0; anns.appExprApplied = n.unparse; anns.funcAnnotations = map(pair(fst=_, snd=nonterminalType("silver:rewrite:Strategy", [], false, false)), annotations); diff --git a/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv b/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv index bf904ec42..94d287c87 100644 --- a/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv +++ b/grammars/silver/compiler/modification/primitivepattern/PrimitiveMatch.sv @@ -227,7 +227,9 @@ top::PrimPattern ::= qn::Decorated QName ns::VarBinders e::Expr -- Note that we're going to check prod_type against top.scrutineeType shortly. -- This is where the type variables become unified. - ns.bindingTypes = prod_type.inputTypes; + ns.bindingTypes = zipWith( + \ ie::NamedSignatureElement t::Type -> if ie.elementShared then t.decoratedType else t, + sig.inputElements, prod_type.inputTypes); ns.bindingIndex = 0; ns.bindingNames = if null(qn.lookupValue.dcls) then [] else qn.lookupValue.dcl.namedSignature.inputNames; ns.matchingAgainst = if null(qn.lookupValue.dcls) then nothing() else just(qn.lookupValue.dcl); @@ -312,7 +314,9 @@ top::PrimPattern ::= qn::Decorated QName ns::VarBinders e::Expr production prod_contexts :: [Context] = prod_contexts_type.fst; production prod_type :: Type = prod_contexts_type.snd; - ns.bindingTypes = prod_type.inputTypes; + ns.bindingTypes = zipWith( + \ ie::NamedSignatureElement t::Type -> if ie.elementShared then t.decoratedType else t, + sig.inputElements, prod_type.inputTypes); ns.bindingIndex = 0; ns.bindingNames = if null(qn.lookupValue.dcls) then [] else qn.lookupValue.dcl.namedSignature.inputNames; ns.matchingAgainst = if null(qn.lookupValue.dcls) then nothing() else just(qn.lookupValue.dcl); diff --git a/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv b/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv index b1e64a15a..2c6aff83b 100644 --- a/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv +++ b/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv @@ -158,7 +158,6 @@ top::VarBinder ::= n::Name then map(anonVertexType(fName).inhVertex, fromMaybe([], refSet)) else []; - -- Unique refs are forbidden in the scrutinee. top.defs <- [lexicalLocalDef(top.grammarName, n.nameLoc, fName, ty, vt, deps)]; top.boundNames <- [n.name]; From 6995ab6c9aa5f8caa09317127f92bc5b654407a7 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Sat, 30 Mar 2024 11:27:06 -0500 Subject: [PATCH 208/283] Fix some bugs with looking up sharedness, put it in the childDclInfo --- .../typechecking/core/ProductionDcl.sv | 2 +- .../compiler/analysis/warnings/flow/Inh.sv | 117 +++++------------ .../concrete_syntax/ProductionDcl.sv | 2 +- .../compiler/definition/core/AspectDcl.sv | 2 +- .../compiler/definition/core/DclInfo.sv | 2 +- .../compiler/definition/core/ProductionDcl.sv | 10 +- .../silver/compiler/definition/env/DclInfo.sv | 7 +- .../silver/compiler/definition/env/Defs.sv | 8 +- .../compiler/definition/env/NamedSignature.sv | 12 +- .../definition/flow/driver/ProductionGraph.sv | 1 - .../compiler/definition/flow/env/Expr.sv | 10 +- .../compiler/definition/flow/env/FlowEnv.sv | 60 +++++++++ test/flow/Dispatch.sv | 57 +++++++++ test/flow/RefSiteProj.sv | 40 ++---- test/flow/UniqueDec.sv | 119 ------------------ 15 files changed, 191 insertions(+), 258 deletions(-) create mode 100644 test/flow/Dispatch.sv delete mode 100644 test/flow/UniqueDec.sv diff --git a/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv b/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv index 3376e0b96..cfa06494f 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/ProductionDcl.sv @@ -48,7 +48,7 @@ top::ProductionRHSElem ::= ms::MaybeShared id::Name '::' t::TypeExpr top.errors <- case top.implementedSig of - | just(e) when e.elementShared != ms.elementShared -> + | just(e) when e.elementShared != ms.isShared -> [errFromOrigin(top, s"Child ${id.name} does not match the sharedness from the implemented dispatch signature.")] | _ -> [] end; diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index 36e84f564..3e46b7dfe 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -55,8 +55,8 @@ Either ::= args::[String] function sigAttrViaReference Boolean ::= sigName::String attrName::String ns::NamedSignature e::Env { - local ty :: Type = findNamedSigElemType(sigName, ns.inputElements); - return !isDecorable(ty, e) || contains(attrName, getMinRefSet(ty, e)); + local ty :: Type = lookupSignatureInputElem(sigName, ns).typerep; + return ty.isDecorated && contains(attrName, getMinRefSet(ty, e)); } {-- @@ -66,12 +66,12 @@ Boolean ::= sigName::String attrName::String ns::NamedSignature e::Env - True if nonsensicle. -} function localAttrViaReference -Boolean ::= sigName::String attrName::String e::Env +Boolean ::= fName::String attrName::String e::Env { - local d :: [ValueDclInfo] = getValueDcl(sigName, e); + local d :: [ValueDclInfo] = getValueDcl(fName, e); local ty :: Type = head(d).typeScheme.typerep; - return null(d) || !isDecorable(ty, e) || contains(attrName, getMinRefSet(ty, e)); + return null(d) || ty.isDecorated && contains(attrName, getMinRefSet(ty, e)); } {-- @@ -120,7 +120,9 @@ function checkEqDeps | rhsInhVertex(sigName, attrName) -> if !null(lookupInh(prodName, sigName, attrName, flowEnv)) || sigAttrViaReference(sigName, attrName, ns, realEnv) - || sigNameIsShared(sigName, ns) && null(sharingSitesLackingSigAttr(sigName, attrName, ns, flowEnv, realEnv)) + || lookupSignatureInputElem(sigName, ns).elementShared && + all(unzipWith(remoteProdHasInhEq(_, _, attrName, flowEnv, realEnv), + lookupAllSigShareSites(prodName, sigName, flowEnv, realEnv))) || !null(lookupRefDecSite(prodName, rhsVertexType(sigName), flowEnv)) || case splitTransAttrInh(attrName) of | just((transAttr, _)) -> @@ -665,6 +667,7 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur | childReference(lq) -> if isDecorable(lq.lookupValue.typeScheme.typerep, top.env) && null(lookupRefDecSite(top.frame.fullName, rhsVertexType(lq.lookupValue.fullName), top.flowEnv)) -- Decoration site projection, covered by checkAllEqDeps + || lq.lookupValue.dcl.isShared then let inhs :: [String] = filter(\ attr::String -> @@ -678,16 +681,16 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur isEquationMissing( lookupInh(top.frame.fullName, lq.lookupValue.fullName, _, top.flowEnv), _), - getMinRefSet(lq.lookupValue.typeScheme.typerep, top.env))) + set:toList(inhDeps))) in if null(inhs) then [] - else if sigNameIsShared(lq.lookupValue.fullName, top.frame.signature) + else if lq.lookupValue.dcl.isShared then flatMap(\ inh::String -> - case sharingSitesLackingSigAttr(lq.lookupValue.fullName, inh, top.frame.signature, top.flowEnv, top.env) of + case sharingSitesLackingSigAttr(top.frame.fullName, lq.lookupValue.fullName, inh, top.flowEnv, top.env) of | [] -> [] | sites -> [mwdaWrnFromOrigin(top, - s"Access of syn attribute ${q.name} on ${e.unparse} requires missing inherited attribute ${inh} to be supplied in the following places: " ++ - implode(", ", map(\ s::(String, VertexType) -> s"${s.2.vertexName} in production ${s.1}", sites)))] + s"Access of syn attribute ${q.name} on ${e.unparse} requires missing inherited attribute ${inh} to be supplied in the following places:\n" ++ + implode("\n", map(\ s::(String, VertexType) -> s" ${s.2.vertexName} in production ${s.1}", sites)))] end, inhs) else [mwdaWrnFromOrigin(top, "Access of syn attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] end @@ -813,6 +816,7 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur | childReference(lq) -> if isDecorable(lq.lookupValue.typeScheme.typerep, top.env) && null(lookupRefDecSite(top.frame.fullName, rhsVertexType(lq.lookupValue.fullName), top.flowEnv)) -- Decoration site projection, covered by checkAllEqDeps + || lq.lookupValue.dcl.isShared then let inhs :: [String] = filter(\ attr::String -> @@ -828,14 +832,14 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur _), set:toList(inhDeps))) in if null(inhs) then [] - else if sigNameIsShared(lq.lookupValue.fullName, top.frame.signature) + else if lq.lookupValue.dcl.isShared then flatMap(\ inh::String -> - case sharingSitesLackingSigAttr(lq.lookupValue.fullName, inh, top.frame.signature, top.flowEnv, top.env) of + case sharingSitesLackingSigAttr(top.frame.fullName, lq.lookupValue.fullName, inh, top.flowEnv, top.env) of | [] -> [] | sites -> [mwdaWrnFromOrigin(top, - s"Access of trans attribute ${q.name} on ${e.unparse} requires missing inherited attribute ${inh} to be supplied in the following places: " ++ - implode(", ", map(\ s::(String, VertexType) -> s"${s.2.vertexName} in production ${s.1}", sites)))] + s"Access of trans attribute ${q.name} on ${e.unparse} requires missing inherited attribute ${inh} to be supplied in the following places:\n" ++ + implode("\n", map(\ s::(String, VertexType) -> s" ${s.2.vertexName} in production ${s.1}", sites)))] end, inhs) else [mwdaWrnFromOrigin(top, "Access of trans attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] end @@ -867,6 +871,18 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur else []; } +{-- + - Given the name of a child shared in the production's signature, + - return the list of all productions/places this child can be decorated before forwarding to this production, + - where the needed inherited attribute is not supplied. + -} +fun sharingSitesLackingSigAttr +[(String, VertexType)] ::= prodName::String sigName::String attrName::String flowEnv::FlowEnv realEnv::Env = + filter( + \ s::(String, VertexType) -> !vertexHasInhEq(s.1, s.2, attrName, flowEnv), + lookupAllSigShareSites(prodName, sigName, flowEnv, realEnv)); + + aspect production decorateExprWith top::Expr ::= 'decorate' e::Expr 'with' '{' inh::ExprInhs '}' { @@ -952,77 +968,6 @@ top::VarBinder ::= n::Name else []; } --- Is this child shared in the signature of the production? -fun sigNameIsShared Boolean ::= sigName::String ns::NamedSignature = - lookup(sigName, zip(ns.inputNames, ns.inputElements)).fromJust.elementShared; - -{-- - - Given the name of a child shared in the production's signature, - - return the list of all productions/places this child can be decorated before forwarding to this production, - - where the needed inherited attribute is not supplied. - -} -fun sharingSitesLackingSigAttr -[(String, VertexType)] ::= sigName::String attrName::String ns::NamedSignature flowEnv::FlowEnv realEnv::Env = - filter( - \ s::(String, VertexType) -> !vertexHasInhEq(s.1, s.2, attrName, flowEnv), - lookupSigShareSites(ns.fullName, sigName, flowEnv) ++ - case getValueDcl(ns.fullName, realEnv) of - | v :: _ when v.implementedSignature matches just(sig) -> - lookupSigShareSites( - sig.fullName, - head(drop(positionOf(sigName, ns.inputNames), sig.inputNames)), - flowEnv) - | _ -> [] - end); - --- Just a helper for filtering, above. -fun remoteProdMissingInhEq -Boolean ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv realEnv::Env = - !remoteProdHasInhEq(prodName, vt, attrName, flowEnv, realEnv); - --- Is this there an equation for this inh attr on any decoration site for this vertex? -fun remoteProdHasInhEq -Boolean ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv realEnv::Env = - any(unzipWith( - vertexHasInhEq(_, _, attrName, flowEnv), - lookupAllDecSites(prodName, vt, flowEnv))) || - case vt of - | rhsVertexType(sigName) when getValueDcl(prodName, realEnv) matches dcl :: _ -> - sigNameIsShared(sigName, dcl.namedSignature) && - null(sharingSitesLackingSigAttr(sigName, attrName, dcl.namedSignature, flowEnv, realEnv)) - | _ -> false - end; - --- Find all decoration sites productions/vertices for this vertex --- TODO: This doesn't gracefully handle cycles in sharing. -fun lookupAllDecSites [(String, VertexType)] ::= prodName::String vt::VertexType flowEnv::FlowEnv = - (prodName, vt) :: - case vt of - | subtermVertexType(_, remoteProdName, sigName) -> - lookupAllDecSites(remoteProdName, rhsVertexType(sigName), flowEnv) - | _ -> flatMap(lookupAllDecSites(prodName, _, flowEnv), lookupRefDecSite(prodName, vt, flowEnv)) - end; - -fun vertexHasInhEq Boolean ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv = - case vt of - | rhsVertexType(sigName) -> !null(lookupInh(prodName, sigName, attrName, flowEnv)) - | localVertexType(fName) -> !null(lookupLocalInh(prodName, fName, attrName, flowEnv)) - | transAttrVertexType(rhsVertexType(sigName), transAttr) -> - !null(lookupInh(prodName, sigName, s"${transAttr}.${attrName}", flowEnv)) - | transAttrVertexType(localVertexType(fName), transAttr) -> - !null(lookupLocalInh(prodName, fName, s"${transAttr}.${attrName}", flowEnv)) - | transAttrVertexType(_, _) -> false - | anonVertexType(fName) -> !null(lookupLocalInh(prodName, fName, attrName, flowEnv)) - | subtermVertexType(_, remoteProdName, sigName) -> - vertexHasInhEq(remoteProdName, rhsVertexType(sigName), attrName, flowEnv) - -- This is a tricky case since we don't know what decorated this prod. - -- checkEqDeps can count on missing LHS inh eqs being caught as flow issues elsewhere, - -- but here we are remotely looking for equations that might not be the direct dependency of - -- anything in the prod flow graph. - | lhsVertexType_real() -> false -- Shouldn't ever be directly needed, since the LHS is never the dec site for another vertex. - | forwardVertexType_real() -> false -- Same as LHS, but we can check this if e.g. forwarding to a child. - end; - -- In places where we solve a synthesized attribute occurs-on context, -- check that the actual deps for the attribute do not exceed the one specified for the context. aspect production synOccursContext diff --git a/grammars/silver/compiler/definition/concrete_syntax/ProductionDcl.sv b/grammars/silver/compiler/definition/concrete_syntax/ProductionDcl.sv index 8d7b2ad81..5cfb17bf2 100644 --- a/grammars/silver/compiler/definition/concrete_syntax/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/concrete_syntax/ProductionDcl.sv @@ -145,7 +145,7 @@ top::ProductionRHSElem ::= ms::MaybeShared id::Name '::' t::TypeExpr if t.typerep.permittedInConcreteSyntax then [] else [errFromOrigin(t, t.unparse ++ " is not permitted on concrete productions. Only terminals and nonterminals (without type variables) can appear here")]; top.concreteSyntaxTypeErrors <- - if ms.elementShared then [errFromOrigin(ms, "Sharing is not permitted in concrete productions.")] + if ms.isShared then [errFromOrigin(ms, "Sharing is not permitted in concrete productions.")] else []; } diff --git a/grammars/silver/compiler/definition/core/AspectDcl.sv b/grammars/silver/compiler/definition/core/AspectDcl.sv index ee25dc836..77ed020f0 100644 --- a/grammars/silver/compiler/definition/core/AspectDcl.sv +++ b/grammars/silver/compiler/definition/core/AspectDcl.sv @@ -302,7 +302,7 @@ top::AspectRHSElem ::= shared::Boolean id::Name t::Type top.inputElements = [namedSignatureElement(id.name, t, shared)]; - top.defs := [aliasedChildDef(top.grammarName, id.nameLoc, fName, performSubstitution(t, top.upSubst), id.name)]; + top.defs := [aliasedChildDef(top.grammarName, id.nameLoc, fName, performSubstitution(t, top.upSubst), shared, id.name)]; top.errors <- if length(getValueDclInScope(id.name, top.env)) > 1 then [errFromOrigin(id, "Value '" ++ id.name ++ "' is already bound.")] diff --git a/grammars/silver/compiler/definition/core/DclInfo.sv b/grammars/silver/compiler/definition/core/DclInfo.sv index fc164c09e..8f30a8bcd 100644 --- a/grammars/silver/compiler/definition/core/DclInfo.sv +++ b/grammars/silver/compiler/definition/core/DclInfo.sv @@ -45,7 +45,7 @@ synthesized attribute attributionDispatcher :: AttributionDcl occurs on Attribut -- -- non-interface values aspect production childDcl -top::ValueDclInfo ::= fn::String ty::Type +top::ValueDclInfo ::= fn::String ty::Type _ { top.refDispatcher = childReference; top.defDispatcher = errorValueDef; -- TODO: we should be smarted about error messages, and mention its a child diff --git a/grammars/silver/compiler/definition/core/ProductionDcl.sv b/grammars/silver/compiler/definition/core/ProductionDcl.sv index 0f0061e5a..af88ed37a 100644 --- a/grammars/silver/compiler/definition/core/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/core/ProductionDcl.sv @@ -213,9 +213,9 @@ top::ProductionRHSElem ::= ms::MaybeShared id::Name '::' t::TypeExpr top.unparse = ms.unparse ++ id.unparse ++ "::" ++ t.unparse; propagate env; - top.inputElements = [namedSignatureElement(id.name, t.typerep, ms.elementShared)]; + top.inputElements = [namedSignatureElement(id.name, t.typerep, ms.isShared)]; - top.defs := [childDef(top.grammarName, id.nameLoc, id.name, t.typerep)]; + top.defs := [childDef(top.grammarName, id.nameLoc, id.name, t.typerep, ms.isShared)]; top.errors <- if length(getValueDclInScope(id.name, top.env)) > 1 @@ -233,13 +233,13 @@ top::ProductionRHSElem ::= ms::MaybeShared t::TypeExpr forwards to productionRHSElem(@ms, name("_G_" ++ toString(top.deterministicCount)), '::', @t); } -tracked nonterminal MaybeShared with unparse, elementShared; +tracked nonterminal MaybeShared with unparse, isShared; concrete production elemShared top::MaybeShared ::= '@' -{ top.unparse = "@"; top.elementShared = true; } +{ top.unparse = "@"; top.isShared = true; } concrete production elemNotShared top::MaybeShared ::= -{ top.unparse = ""; top.elementShared = false; } +{ top.unparse = ""; top.isShared = false; } diff --git a/grammars/silver/compiler/definition/env/DclInfo.sv b/grammars/silver/compiler/definition/env/DclInfo.sv index c424a47f4..d350b8d4b 100644 --- a/grammars/silver/compiler/definition/env/DclInfo.sv +++ b/grammars/silver/compiler/definition/env/DclInfo.sv @@ -31,6 +31,7 @@ synthesized attribute definedMembers :: [String]; -- values synthesized attribute namedSignature :: NamedSignature; synthesized attribute implementedSignature :: Maybe; +synthesized attribute isShared :: Boolean; synthesized attribute hasForward :: Boolean; -- occurs @@ -52,7 +53,7 @@ inherited attribute givenSubstitution :: Substitution; closed nonterminal ValueDclInfo with sourceGrammar, sourceLocation, fullName, compareTo, isEqual, - typeScheme, namedSignature, implementedSignature, hasForward, substitutedDclInfo, givenSubstitution; + typeScheme, namedSignature, implementedSignature, isShared, hasForward, substitutedDclInfo, givenSubstitution; propagate isEqual on ValueDclInfo excluding globalValueDcl, classMemberDcl; aspect default production @@ -61,6 +62,7 @@ top::ValueDclInfo ::= -- Values that are not fun/prod have this valid default. top.namedSignature = bogusNamedSignature(); top.implementedSignature = nothing(); + top.isShared = false; top.hasForward = false; top.substitutedDclInfo = error("Internal compiler error: must be defined for all value declarations that are production attributes"); @@ -68,11 +70,12 @@ top::ValueDclInfo ::= -- ValueDclInfos that can NEVER appear in interface files: abstract production childDcl -top::ValueDclInfo ::= fn::String ty::Type +top::ValueDclInfo ::= fn::String ty::Type isShared::Boolean { top.fullName = fn; top.typeScheme = monoType(ty); + top.isShared = isShared; } abstract production lhsDcl top::ValueDclInfo ::= fn::String ty::Type diff --git a/grammars/silver/compiler/definition/env/Defs.sv b/grammars/silver/compiler/definition/env/Defs.sv index d0a86b2c8..0e0bd421a 100644 --- a/grammars/silver/compiler/definition/env/Defs.sv +++ b/grammars/silver/compiler/definition/env/Defs.sv @@ -120,8 +120,8 @@ top::Def ::= d::InstDclInfo top.instList = [d]; } -fun childDef Def ::= sg::String sl::Location fn::String ty::Type = - valueDef(defaultEnvItem(childDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); +fun childDef Def ::= sg::String sl::Location fn::String ty::Type s::Boolean = + valueDef(defaultEnvItem(childDcl(fn,ty,s,sourceGrammar=sg,sourceLocation=sl))); fun lhsDef Def ::= sg::String sl::Location fn::String ty::Type = valueDef(defaultEnvItem(lhsDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); fun localDef Def ::= sg::String sl::Location fn::String ty::Type isForward::Boolean = @@ -166,8 +166,8 @@ fun forwardDef Def ::= sg::String sl::Location ty::Type = -- These aliased functions are used for aspects. fun aliasedLhsDef Def ::= sg::String sl::Location fn::String ty::Type alias::String = valueDef(onlyRenamedEnvItem(alias, lhsDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); -fun aliasedChildDef Def ::= sg::String sl::Location fn::String ty::Type alias::String = - valueDef(onlyRenamedEnvItem(alias, childDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); +fun aliasedChildDef Def ::= sg::String sl::Location fn::String ty::Type s::Boolean alias::String = + valueDef(onlyRenamedEnvItem(alias, childDcl(fn,ty,s,sourceGrammar=sg,sourceLocation=sl))); fun annoDef Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type = attrDef(defaultEnvItem(annoDcl(fn,bound,ty,sourceGrammar=sg,sourceLocation=sl))); fun classDef diff --git a/grammars/silver/compiler/definition/env/NamedSignature.sv b/grammars/silver/compiler/definition/env/NamedSignature.sv index 5a31a891d..bbc7f0e72 100644 --- a/grammars/silver/compiler/definition/env/NamedSignature.sv +++ b/grammars/silver/compiler/definition/env/NamedSignature.sv @@ -187,12 +187,12 @@ Integer ::= s::String l::[NamedSignatureElement] z::Integer = else if s == head(l).elementName then z else findNamedSigElem(s, tail(l), z+1); -function findNamedSigElemType -Type ::= n::String l::[NamedSignatureElement] -{ - local elems::NamedSignatureElements = foldNamedSignatureElements(l); - return fromMaybe(errorType(), lookup(n, zip(elems.elementNames, elems.elementTypes))); -} +fun lookupSignatureInputElem +NamedSignatureElement ::= s::String ns::NamedSignature = + case lookup(s, zip(ns.inputNames, ns.inputElements)) of + | just(e) -> e + | nothing() -> bogusNamedSignatureElement() + end; -------------- diff --git a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv index 145b0666c..2448ba5a0 100644 --- a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv @@ -1,7 +1,6 @@ grammar silver:compiler:definition:flow:driver; import silver:compiler:definition:type only isNonterminal, typerep; -import silver:compiler:analysis:warnings:flow only sigAttrViaReference, localAttrViaReference; data nonterminal ProductionGraph with stitchedGraph, prod, lhsNt, transitiveClosure, edgeMap, suspectEdgeMap, cullSuspect, flowTypeVertexes; diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index 053478ea6..5abe7c710 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -255,6 +255,12 @@ top::AppExpr ::= e::Expr end; e.alwaysDecorated = top.alwaysDecorated && e.decSiteVertexInfo.isJust; + production inputSigIsShared::Boolean = + case e.flowVertexInfo of + | just(rhsVertexType(sigName)) + when getValueDcl(sigName, top.env) matches dcl :: _ -> dcl.isShared + | _ -> false + end; production sigIsShared::Boolean = case top.appProd of | just(ns) -> @@ -263,7 +269,7 @@ top::AppExpr ::= e::Expr end; top.flowDefs <- case top.appProd, e.flowVertexInfo of - | just(ns), just(v) when sigIsShared -> + | just(ns), just(v) when sigIsShared && !inputSigIsShared -> [sigShareSite(top.frame.fullName, v, ns.fullName, sigName)] | _, _ -> [] end; @@ -437,6 +443,8 @@ aspect production decorationSiteExpr top::Expr ::= '@' e::Expr { top.flowVertexInfo = e.flowVertexInfo; + e.decSiteVertexInfo = nothing(); + e.alwaysDecorated = false; top.flowDefs <- case e.flowVertexInfo, top.decSiteVertexInfo of diff --git a/grammars/silver/compiler/definition/flow/env/FlowEnv.sv b/grammars/silver/compiler/definition/flow/env/FlowEnv.sv index 2c4f3c725..6e6196f2e 100644 --- a/grammars/silver/compiler/definition/flow/env/FlowEnv.sv +++ b/grammars/silver/compiler/definition/flow/env/FlowEnv.sv @@ -107,6 +107,66 @@ fun lookupRefDecSite [VertexType] ::= prod::String v::VertexType e::FlowEnv = fun lookupSigShareSites [(String, VertexType)] ::= prod::String sigName::String e::FlowEnv = searchEnvTree(crossnames(prod, sigName), e.sigShareTree); +-- places where this child was decorated in a production forwarding to this one, +-- or in a dispatch signature that this production implements +fun lookupAllSigShareSites [(String, VertexType)] ::= prod::String sigName::String e::FlowEnv realEnv::Env = + lookupSigShareSites(prod, sigName, e) ++ + case getValueDcl(prod, realEnv) of + | dcl :: _ when dcl.implementedSignature matches just(sig) -> + lookupSigShareSites( + sig.fullName, + head(drop(positionOf(sigName, dcl.namedSignature.inputNames), sig.inputNames)), + e) + | _ -> [] + end; + +-- Just a helper for filtering. +fun remoteProdMissingInhEq +Boolean ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv realEnv::Env = + !remoteProdHasInhEq(prodName, vt, attrName, flowEnv, realEnv); + +-- Is this there an equation for this inh attr on any decoration site for this vertex? +fun remoteProdHasInhEq +Boolean ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv realEnv::Env = + any(unzipWith(vertexHasInhEq(_, _, attrName, flowEnv), lookupAllDecSites(prodName, vt, flowEnv))) || + case vt of + | rhsVertexType(sigName) when getValueDcl(sigName, realEnv) matches dcl :: _ -> + dcl.isShared && + all(unzipWith(vertexHasInhEq(_, _, attrName, flowEnv), + lookupAllSigShareSites(prodName, sigName, flowEnv, realEnv))) + | _ -> false + end; + +-- Find all decoration sites productions/vertices for this vertex +-- TODO: This doesn't gracefully handle cycles in sharing. +fun lookupAllDecSites [(String, VertexType)] ::= prodName::String vt::VertexType flowEnv::FlowEnv = + (prodName, vt) :: + case vt of + | subtermVertexType(_, remoteProdName, sigName) -> + lookupAllDecSites(remoteProdName, rhsVertexType(sigName), flowEnv) + | _ -> flatMap(lookupAllDecSites(prodName, _, flowEnv), lookupRefDecSite(prodName, vt, flowEnv)) + end; + +fun vertexHasInhEq Boolean ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv = + case vt of + | rhsVertexType(sigName) -> !null(lookupInh(prodName, sigName, attrName, flowEnv)) + | localVertexType(fName) -> !null(lookupLocalInh(prodName, fName, attrName, flowEnv)) + | transAttrVertexType(rhsVertexType(sigName), transAttr) -> + !null(lookupInh(prodName, sigName, s"${transAttr}.${attrName}", flowEnv)) + | transAttrVertexType(localVertexType(fName), transAttr) -> + !null(lookupLocalInh(prodName, fName, s"${transAttr}.${attrName}", flowEnv)) + | transAttrVertexType(_, _) -> false + | anonVertexType(fName) -> !null(lookupLocalInh(prodName, fName, attrName, flowEnv)) + | subtermVertexType(_, remoteProdName, sigName) -> + vertexHasInhEq(remoteProdName, rhsVertexType(sigName), attrName, flowEnv) + -- This is a tricky case since we don't know what decorated this prod. + -- checkEqDeps can count on missing LHS inh eqs being caught as flow issues elsewhere, + -- but here we are remotely looking for equations that might not be the direct dependency of + -- anything in the prod flow graph. + | lhsVertexType_real() -> false -- Shouldn't ever be directly needed, since the LHS is never the dec site for another vertex. + | forwardVertexType_real() -> false -- Same as LHS, but we can check this if e.g. forwarding to a child. + end; + {-- - This is a glorified lambda function, to help look for equations. - Literally, we're just checking for null here. diff --git a/test/flow/Dispatch.sv b/test/flow/Dispatch.sv new file mode 100644 index 000000000..de6c4715f --- /dev/null +++ b/test/flow/Dispatch.sv @@ -0,0 +1,57 @@ +grammar flow; + +synthesized attribute errors1::Boolean; +synthesized attribute errors2::Boolean; + +nonterminal UDExpr with env1, env2, errors1, errors2; + +production overloadThing +top::UDExpr ::= e::UDExpr +{ + e.env1 = top.env1; + e.env2 = []; + forwards to dispatchThing(e); +} + +production dispatchThing +top::UDExpr ::= @e::UDExpr +{ + top.errors1 = e.errors1; + top.errors2 = !null(e.env1); +} + +wrongFlowCode "Tree e in production flow:overloadThing2 is shared in multiple places" { +production overloadThing2 +top::UDExpr ::= e::UDExpr +{ + local otherRef::UDExpr = @e; + e.env1 = top.env1; + forwards to dispatchThing(e); +} +} + +wrongFlowCode "Tree e in production flow:dispatchThing is shared in multiple places" { +aspect production dispatchThing +top::UDExpr ::= @e::UDExpr +{ + local otherRef::UDExpr = @e; + local otherRef2::UDExpr = @e; +} +} + +warnCode "Duplicate equation for env2 on e in production flow:alreadyDec" { +production alreadyDec +top::UDExpr ::= @e::UDExpr +{ + e.env2 = []; +} +} + +wrongFlowCode "Unique reference to flow:uniqueReturn:e taken outside of a unique context. The return of flow:uniqueReturn is not a unique context as this function has no unique parameters." { +function uniqueReturn +UDExpr ::= e::UDExpr +{ + e.env1 = []; + return dispatchThing(e); +} +} diff --git a/test/flow/RefSiteProj.sv b/test/flow/RefSiteProj.sv index 677ed5094..7d7796c48 100644 --- a/test/flow/RefSiteProj.sv +++ b/test/flow/RefSiteProj.sv @@ -131,22 +131,13 @@ production incrementalDec top::RSExpr ::= e::RSExpr { e.env1 = top.env1; - local e1::Decorated! RSExpr with {env1} = e; + local e1::Expr = @e; e1.env2 = top.env2; top.errors1 = e1.errors1; top.errors2 = e.errors2; } -production implProd -top::RSExpr ::= e::Decorated! RSExpr with {env1} -{ - undecorates to e; - e.env2 = top.env2; - top.errors1 = e.errors1; - top.errors2 = e.errors2; -} - warnCode "equation errors1 exceeds flow type with dependencies on flow:env2" { production remoteExceeds top::RSExpr ::= e::RSExpr @@ -238,36 +229,27 @@ top::RSExpr ::= e::RSExpr if top.env1 == [] then copy12From2(@e) else base(); } -production overrideInRefSet -top::RSExpr ::= e::RSExpr -{ - e.env1 = top.env1; - e.env2 = top.env1; - local e1::Decorated! RSExpr with {env1} = e; - e1.env2 = []; - top.errors1 = e1.errors1; - top.errors2 = e1.errors2; -} - warnCode "override equation may exceed a flow type with hidden transitive dependencies" { production overrideNotInRefSet top::RSExpr ::= e::RSExpr { e.env1 = top.env1; e.env2 = top.env2; - local e1::Decorated! RSExpr with {env1} = e; + local e1::Expr = @e; e1.env2 = []; top.errors1 = e1.errors1; top.errors2 = e1.errors2; } } -production dispatchGood -top::RSExpr ::= e::RSExpr +dispatch UnaryOp = RSExpr ::= @e::RSExpr; + +production implProd implements UnaryOp +top::RSExpr ::= @e::RSExpr { - e.env1 = top.env1; - local implProdRef::(RSExpr ::= Decorated! RSExpr with {env1}) = implProd; - forwards to implProdRef(e); + e.env2 = top.env2; + top.errors1 = e.errors1; + top.errors2 = e.errors2; } production dispatchOverrideKnownProd @@ -278,16 +260,14 @@ top::RSExpr ::= e::RSExpr forwards to implProd(e); } -warnCode "override equation may exceed a flow type with hidden transitive dependencies" { production dispatchOverrideUnknownProd top::RSExpr ::= e::RSExpr { e.env1 = top.env1; e.env2 = top.env2; - local implProdRef::(RSExpr ::= Decorated! RSExpr with {env1}) = implProd; + local implProdRef::UnaryOp = implProd; forwards to implProdRef(e); } -} warnCode "Access of syn attribute errors2 on e requires missing inherited attributes flow:env2 to be supplied" { production anonDecSuppliedMissing diff --git a/test/flow/UniqueDec.sv b/test/flow/UniqueDec.sv deleted file mode 100644 index 50de76f12..000000000 --- a/test/flow/UniqueDec.sv +++ /dev/null @@ -1,119 +0,0 @@ -grammar flow; - -synthesized attribute errors1::Boolean; -synthesized attribute errors2::Boolean; - -nonterminal UDExpr with env1, env2, errors1, errors2; - -production overloadThing -top::UDExpr ::= e::UDExpr -{ - e.env1 = top.env1; - forwards to dispatchThing(e); -} - -production dispatchThing -top::UDExpr ::= e::Decorated! UDExpr with {env1} -{ - undecorates to overloadThing(e); - -- Accesses on unique decorated children should not give flow errors - top.errors1 = e.errors1; - top.errors2 = !null(e.env1); -} - -wrongFlowCode "Production 'dispatchThing2' has a unique reference in its signature but no 'undecorates to'." { -production dispatchThing2 -top::UDExpr ::= e::Decorated! UDExpr with {env1} -{ - top.errors1 = e.errors1; - top.errors2 = !null(e.env1); -} -} - -function getEnv2FromUniqueRef -[String] ::= e::Expr -{ - e.env2 = []; - -- Accesses on unique decorated local should not give flow errors - local e2::Decorated! Expr with {env2} = e; - return e2.env2; -} - -wrongFlowCode "Multiple unique references taken to e in production flow:overloadThing2 (reference has type Decorated! flow:UDExpr with {flow:env1})." { -production overloadThing2 -top::UDExpr ::= e::UDExpr -{ - local otherRef::Decorated! UDExpr with {env1} = e; - e.env1 = top.env1; - forwards to dispatchThing(e); -} -} - --- Defining attributes not in the reference set taken is permitted -aspect production overloadThing -top::UDExpr ::= e::UDExpr -{ - e.env2 = []; -} - -wrongFlowCode "Multiple unique references taken to e2 in production flow:overloadThing (reference has type Decorated! flow:UDExpr with {flow:env1})." { -aspect production overloadThing -top::UDExpr ::= e::UDExpr -{ - local e2::UDExpr = e; - e2.env1 = []; - e2.env2 = []; - local ref1::Decorated! UDExpr with {env1} = e2; - local ref2::Decorated! UDExpr with {env1, env2} = e2; -} -} - -wrongFlowCode "Multiple unique references taken to e in production flow:dispatchThing (reference has type Decorated! flow:UDExpr with {})." { -aspect production dispatchThing -top::UDExpr ::= e::Decorated! UDExpr with {env1} -{ - local otherRef::Decorated! UDExpr with {} = e; - local otherRef2::Decorated! UDExpr with {} = e; -} -} - -function thingWithBoundedRefArg -{env1, env2} subset i, i subset {env1} => -- Uninhabited, but shouldn't give an error -Decorated! UDExpr with {env1} ::= e::Decorated! UDExpr with i -{ - return e; -} - --- Taking a unique reference with an unbounded reference set is permitted -function thingWithUnboundedRefArg -{env1, env2} subset i => Decorated! UDExpr with {env1} ::= e::Decorated! UDExpr with i -{ - return e; -} - -warnCode "Duplicate equation for env2 on e in production flow:alreadyDec" { -function alreadyDec -() ::= e::Decorated! UDExpr with {env2} -{ - e.env2 = []; - return (); -} -} - --- Defining attributes not in the reference set taken is permitted -function eqnNotInRef -Decorated! UDExpr with {env2} ::= e::UDExpr extra::Decorated! UDExpr -{ - e.env1 = []; - e.env2 = []; - return e; -} - -wrongFlowCode "Unique reference to flow:uniqueReturn:e taken outside of a unique context. The return of flow:uniqueReturn is not a unique context as this function has no unique parameters." { -function uniqueReturn -UDExpr ::= e::UDExpr -{ - e.env1 = []; - return dispatchThing(e); -} -} From 68c5c8f4d34964d042f2dfaf491398d4fe71ee13 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 1 Apr 2024 14:08:11 -0500 Subject: [PATCH 209/283] Move mDownSubst eqs to access/accessBouncer --- .../extension/implicit_monads/Expr.sv | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index 6ccf55d39..2403d483f 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -478,6 +478,18 @@ top::Expr ::= e::Expr '.' 'forward' top.monadRewritten = forwardAccess(ne.monadRewritten, '.', 'forward'); } +aspect production access +top::Expr ::= e::Expr '.' q::QNameAttrOccur +{ + propagate mDownSubst, mUpSubst; +} + +aspect production accessBouncer +top::Expr ::= e::Expr @q::QNameAttrOccur target::Access +{ + propagate mDownSubst, mUpSubst; +} + aspect production errorAccessHandler top::Expr ::= @e::Expr @q::QNameAttrOccur { @@ -486,7 +498,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur then [access(e, '.', q)] ++ e.monadicNames else e.monadicNames; - propagate mDownSubst, mUpSubst; top.merrors := []; top.merrors <- case q.attrDcl of | restrictedSynDcl(_, _, _) -> [] @@ -556,7 +567,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur aspect production annoAccessHandler top::Expr ::= @e::Expr @q::QNameAttrOccur { - e.mDownSubst = top.mDownSubst; e.monadicallyUsed = false; --this needs to change when we decorate monadic trees top.monadicNames = if top.monadicallyUsed then [access(e, '.', q)] ++ e.monadicNames @@ -615,7 +625,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur aspect production synDataAccessHandler top::Expr ::= @e::Expr @q::QNameAttrOccur { - e.mDownSubst = top.mDownSubst; e.monadicallyUsed = false; --this needs to change when we decorate monadic trees top.monadicNames = if top.monadicallyUsed then [access(e, '.', q)] ++ e.monadicNames @@ -688,7 +697,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur aspect production terminalAccessHandler top::Expr ::= @e::Expr @q::QNameAttrOccur { - e.mDownSubst = top.mDownSubst; top.merrors := e.merrors; top.mUpSubst = top.mDownSubst; @@ -736,7 +744,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur aspect production synDecoratedAccessHandler top::Expr ::= @e::Expr @q::QNameAttrOccur { - e.mDownSubst = top.mDownSubst; e.monadicallyUsed = false; --this needs to change when we decorate monadic trees top.monadicNames = if top.monadicallyUsed then [access(e, '.', q)] ++ e.monadicNames @@ -809,7 +816,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur aspect production inhDecoratedAccessHandler top::Expr ::= @e::Expr @q::QNameAttrOccur { - e.mDownSubst = top.mDownSubst; e.monadicallyUsed = false; --this needs to change when we decorate monadic trees top.monadicNames = if top.monadicallyUsed then [access(e, '.', q)] ++ e.monadicNames @@ -938,8 +944,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur aspect production unknownDclAccessHandler top::Expr ::= @e::Expr @q::QNameAttrOccur { - e.mDownSubst = top.mDownSubst; - top.monadicNames = []; --Why do we rewrite here, in an error production? We can get here from the basic access From 9ee081e7942c4fc831f5a90a41973e94ae506c25 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 1 Apr 2024 14:18:53 -0500 Subject: [PATCH 210/283] Add stitch points for signautre sharing --- .../silver/compiler/definition/flow/ast/Flow.sv | 6 +++--- .../definition/flow/driver/ProductionGraph.sv | 15 ++++++++++++++- .../silver/compiler/definition/flow/env/Expr.sv | 2 +- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/grammars/silver/compiler/definition/flow/ast/Flow.sv b/grammars/silver/compiler/definition/flow/ast/Flow.sv index f2e792770..f8a09d2a3 100644 --- a/grammars/silver/compiler/definition/flow/ast/Flow.sv +++ b/grammars/silver/compiler/definition/flow/ast/Flow.sv @@ -441,11 +441,11 @@ top::FlowDef ::= prod::String nt::String ref::VertexType decSite::VertexType } abstract production sigShareSite -top::FlowDef ::= sourceProd::String source::VertexType targetProd::String target::String +top::FlowDef ::= prod::String sigName::String sourceProd::String source::VertexType { - top.prodGraphContribs := []; + top.prodGraphContribs := [(prod, top)]; top.flowEdges = []; - top.sigShareContribs := [(crossnames(targetProd, target), sourceProd, source)]; + top.sigShareContribs := [(crossnames(prod, sigName), sourceProd, source)]; } -- diff --git a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv index 2448ba5a0..a98247fc6 100644 --- a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv @@ -184,7 +184,8 @@ ProductionGraph ::= dcl::ValueDclInfo defs::[FlowDef] flowEnv::FlowEnv realEn flatMap(rhsStitchPoints(realEnv, _), dcl.namedSignature.inputElements) ++ localStitchPoints(realEnv, nt, defs) ++ patternStitchPoints(realEnv, defs) ++ - subtermDecSiteStitchPoints(flowEnv, realEnv, defs); + subtermDecSiteStitchPoints(flowEnv, realEnv, defs) ++ + sigSharingStitchPoints(flowEnv, realEnv, defs); local flowTypeVertexesOverall :: [FlowVertex] = (if nonForwarding then [] else [forwardEqVertex()]) ++ @@ -488,6 +489,18 @@ fun subtermDecSiteStitchPoints [StitchPoint] ::= flowEnv::FlowEnv realEnv::Env | _ -> [] end, defs); +fun sigSharingStitchPoints [StitchPoint] ::= flowEnv::FlowEnv realEnv::Env defs::[FlowDef] = + flatMap(\ d::FlowDef -> + case d of + | sigShareSite(_, sigName, sourceProd, vt) -> + map(\ prodDcl::ValueDclInfo -> + projectionStitchPoint( + sourceProd, rhsVertexType(sigName), lhsVertexType, vt, + getInhAndInhOnTransAttrsOn(prodDcl.namedSignature.outputElement.typerep.typeName, realEnv)), + getValueDcl(sourceProd, realEnv)) + | _ -> [] + end, + defs); ---- End helpers for figuring our stitch points -------------------------------- diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index 5abe7c710..5beb6fd25 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -270,7 +270,7 @@ top::AppExpr ::= e::Expr top.flowDefs <- case top.appProd, e.flowVertexInfo of | just(ns), just(v) when sigIsShared && !inputSigIsShared -> - [sigShareSite(top.frame.fullName, v, ns.fullName, sigName)] + [sigShareSite(ns.fullName, sigName, top.frame.fullName, v)] | _, _ -> [] end; } From a2b61b69596e23cbb0aea5a603ff1711bd2f5e41 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 1 Apr 2024 15:10:30 -0500 Subject: [PATCH 211/283] Fix file name --- .../analysis/warnings/flow/{SIgSharing.sv => SigSharing.sv} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename grammars/silver/compiler/analysis/warnings/flow/{SIgSharing.sv => SigSharing.sv} (100%) diff --git a/grammars/silver/compiler/analysis/warnings/flow/SIgSharing.sv b/grammars/silver/compiler/analysis/warnings/flow/SigSharing.sv similarity index 100% rename from grammars/silver/compiler/analysis/warnings/flow/SIgSharing.sv rename to grammars/silver/compiler/analysis/warnings/flow/SigSharing.sv From 365361b6bb970b805eb07dc2adbf3177d75c9f43 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 1 Apr 2024 16:33:44 -0500 Subject: [PATCH 212/283] Remove originRules from forward and errors flowtypes --- .../silver/compiler/definition/core/Expr.sv | 17 ++++++++-- .../definition/core/ProductionBody.sv | 11 ++++--- .../compiler/extension/autoattr/Monoid.sv | 1 - .../extension/implicit_monads/Case.sv | 33 +++++++------------ .../extension/implicit_monads/Expr.sv | 14 ++++---- .../compiler/extension/implicit_monads/Let.sv | 1 - .../implicit_monads/PrimitiveMatch.sv | 1 - .../implicit_monads/ProductionBody.sv | 16 ++++----- .../compiler/extension/rewriting/Expr.sv | 2 -- .../compiler/extension/rewriting/Rewriting.sv | 2 +- .../silver/compiler/extension/tuple/Tuple.sv | 2 +- 11 files changed, 49 insertions(+), 51 deletions(-) diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index 52625cb30..f4dc3d455 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -18,15 +18,18 @@ tracked nonterminal ExprLHSExpr with flowtype unparse {} on Expr, Exprs, ExprInhs, ExprInh, ExprLHSExpr; flowtype freeVars {frame} on Expr, Exprs, ExprInhs, ExprInh, ExprLHSExpr; flowtype Expr = - forward {grammarName, env, flowEnv, downSubst, finalSubst, frame, isRoot, originRules, compiledGrammars, config}, - decorate {forward, alwaysDecorated}; + forward {grammarName, env, flowEnv, downSubst, finalSubst, frame, isRoot, compiledGrammars, config}, + decorate {forward, alwaysDecorated, originRules}, + errors {forward, alwaysDecorated}; flowtype decorate {grammarName, env, flowEnv, downSubst, finalSubst, frame, originRules, compiledGrammars, config} on Exprs; flowtype decorate {grammarName, env, flowEnv, downSubst, finalSubst, frame, originRules, compiledGrammars, config, decoratingnt, allSuppliedInhs} on ExprInhs, ExprInh; flowtype decorate {grammarName, env, frame, originRules, config, decoratingnt, allSuppliedInhs} on ExprLHSExpr; flowtype forward {} on Exprs, ExprInhs, ExprInh, ExprLHSExpr; -flowtype errors {decorate} on Exprs, ExprInhs, ExprInh, ExprLHSExpr; +flowtype errors {grammarName, env, flowEnv, downSubst, finalSubst, frame, compiledGrammars, config} on Exprs; +flowtype errors {grammarName, env, flowEnv, downSubst, finalSubst, frame, compiledGrammars, config, decoratingnt, allSuppliedInhs} on ExprInhs, ExprInh; +flowtype errors {grammarName, env, frame, config, decoratingnt, allSuppliedInhs} on ExprLHSExpr; propagate errors on Expr, Exprs, ExprInhs, ExprInh, ExprLHSExpr excluding terminalAccessHandler; @@ -935,6 +938,10 @@ flowtype AppExprs = decorate { config, grammarName, env, frame, compiledGrammars, appExprTypereps, appExprApplied, originRules, downSubst, finalSubst, flowEnv + }, + errors { + config, grammarName, env, frame, compiledGrammars, appExprTypereps, appExprApplied, + downSubst, finalSubst, flowEnv }; tracked nonterminal AppExpr with @@ -1052,6 +1059,10 @@ flowtype decorate { grammarName, env, flowEnv, downSubst, finalSubst, frame, originRules, compiledGrammars, config, appExprApplied, remainingFuncAnnotations, funcAnnotations } on AnnoAppExprs, AnnoExpr; +flowtype errors { + grammarName, env, flowEnv, downSubst, finalSubst, frame, compiledGrammars, config, + appExprApplied, remainingFuncAnnotations, funcAnnotations + } on AnnoAppExprs, AnnoExpr; propagate config, grammarName, env, errors, freeVars, frame, compiledGrammars, exprs, funcAnnotations, appExprApplied, originRules on AnnoAppExprs, AnnoExpr; diff --git a/grammars/silver/compiler/definition/core/ProductionBody.sv b/grammars/silver/compiler/definition/core/ProductionBody.sv index 0f26990b6..e297274f1 100644 --- a/grammars/silver/compiler/definition/core/ProductionBody.sv +++ b/grammars/silver/compiler/definition/core/ProductionBody.sv @@ -10,13 +10,14 @@ tracked nonterminal ProductionStmt with config, grammarName, env, unparse, errors, defs, frame, compiledGrammars, productionAttributes, forwardExpr, returnExpr, originRules; -flowtype decorate {frame, grammarName, compiledGrammars, config, env, flowEnv, downSubst} +flowtype forward {frame, grammarName, compiledGrammars, config, env, flowEnv, downSubst} on ProductionBody; -flowtype decorate {frame, grammarName, compiledGrammars, config, env, flowEnv, downSubst, originRules} +flowtype forward {frame, grammarName, compiledGrammars, config, env, flowEnv, downSubst} on ProductionStmts; -flowtype decorate {frame, grammarName, compiledGrammars, config, env, flowEnv, downSubst, finalSubst, originRules} +flowtype forward {frame, grammarName, compiledGrammars, config, env, flowEnv, downSubst, finalSubst} on ProductionStmt; -flowtype forward {decorate} on ProductionBody, ProductionStmts, ProductionStmt; +flowtype decorate {forward} on ProductionBody; +flowtype decorate {forward, originRules} on ProductionStmts, ProductionStmt; tracked nonterminal DefLHS with config, grammarName, env, unparse, errors, frame, compiledGrammars, name, typerep, defLHSattr, found, originRules; @@ -306,7 +307,7 @@ abstract production errorAttributeDef top::ProductionStmt ::= msg::[Message] @dl::DefLHS @attr::QNameAttrOccur e::Expr { top.unparse = "\t" ++ dl.unparse ++ "." ++ attr.unparse ++ " = " ++ e.unparse ++ ";"; - propagate grammarName, config, env, frame, compiledGrammars, originRules; + propagate grammarName, config, env, frame, compiledGrammars; e.isRoot = true; forwards to errorProductionStmt(msg ++ e.errors); diff --git a/grammars/silver/compiler/extension/autoattr/Monoid.sv b/grammars/silver/compiler/extension/autoattr/Monoid.sv index 668abd576..b1e789bf3 100644 --- a/grammars/silver/compiler/extension/autoattr/Monoid.sv +++ b/grammars/silver/compiler/extension/autoattr/Monoid.sv @@ -53,7 +53,6 @@ top::AGDcl ::= 'monoid' 'attribute' a::Name tl::BracketedOptTypeExprs '::' te::T e.frame = globalExprContext(fName, nilContext(), te.typerep, myFlowGraph, sourceGrammar=top.grammarName); e.isRoot = false; - e.originRules = []; e.decSiteVertexInfo = nothing(); e.alwaysDecorated = false; diff --git a/grammars/silver/compiler/extension/implicit_monads/Case.sv b/grammars/silver/compiler/extension/implicit_monads/Case.sv index 833bdb26c..e87e38cd6 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Case.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Case.sv @@ -19,7 +19,7 @@ top::Expr ::= 'case' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' local monadInExprs::Boolean = monadicallyUsedExpr(es.rawExprs, top.env, ml.mUpSubst, top.frame, top.grammarName, top.compiledGrammars, top.config, top.flowEnv, - top.expectedMonad, false, top.originRules); + top.expectedMonad, false); local monadInClauses::Boolean = foldl((\b::Boolean a::AbstractMatchRule -> b || @@ -78,7 +78,6 @@ top::Expr ::= 'case' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' redeces.config = top.config; redeces.flowEnv = top.flowEnv; redeces.expectedMonad = top.expectedMonad; - redeces.originRules = top.originRules; {- We rewrite by pulling the monad-typed expressions on which we are matching @@ -105,7 +104,6 @@ top::Expr ::= 'case' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' monadLocal.finalSubst = top.finalSubst; monadLocal.expectedMonad = top.expectedMonad; monadLocal.alwaysDecorated = false; - monadLocal.originRules = top.originRules; monadLocal.isRoot = false; top.monadRewritten = monadLocal.monadRewritten; top.mtyperep = monadLocal.mtyperep; @@ -120,14 +118,14 @@ top::Expr ::= 'case' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' frame=top.frame; grammarName=top.grammarName; downSubst=top.mDownSubst; finalSubst=top.mDownSubst; compiledGrammars=top.compiledGrammars; config=top.config; alwaysDecorated = false; flowEnv=top.flowEnv;expectedMonad=top.expectedMonad; - isRoot=top.isRoot; originRules=top.originRules;} + isRoot=top.isRoot;} in if isMonad(a.mtyperep, top.env) && monadsMatch(a.mtyperep, top.expectedMonad, top.mDownSubst).fst && !isMonad(performSubstitution(x.snd, top.mDownSubst), top.env) then decorate x.fst with {env=top.env; mDownSubst=top.mDownSubst; frame=top.frame; grammarName=top.grammarName; downSubst=top.mDownSubst; finalSubst=top.mDownSubst; compiledGrammars=top.compiledGrammars; config=top.config; flowEnv=top.flowEnv; monadicallyUsed=true; - expectedMonad=top.expectedMonad; alwaysDecorated = false; isRoot=top.isRoot; originRules=top.originRules;}.monadicNames + expectedMonad=top.expectedMonad; alwaysDecorated = false; isRoot=top.isRoot;}.monadicNames else [] end ++ l, monadLocal.monadicNames, zipWith(\x::Expr y::Type -> (x,y), es.rawExprs, ml.patternTypeList)); @@ -137,16 +135,16 @@ top::Expr ::= 'case' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' fun monadicallyUsedExpr Boolean ::= elst::[Expr] env::Env sub::Substitution f::BlockContext gn::String cg::EnvTree c::Decorated CmdArgs fe::FlowEnv em::Type - iR::Boolean oR::[Decorated Expr] = + iR::Boolean = case elst of | [] -> false | e::etl -> let etyp::Type = decorate e with {env=env; mDownSubst=sub; frame=f; grammarName=gn; downSubst=sub; finalSubst=sub; compiledGrammars=cg; config=c; alwaysDecorated = false; flowEnv=fe; - expectedMonad=em; isRoot=iR; originRules=oR;}.mtyperep + expectedMonad=em; isRoot=iR;}.mtyperep in - fst(monadsMatch(etyp, em, sub)) || monadicallyUsedExpr(etl, env, sub, f, gn, cg, c, fe, em, iR, oR) + fst(monadsMatch(etyp, em, sub)) || monadicallyUsedExpr(etl, env, sub, f, gn, cg, c, fe, em, iR) end end; --make a list of the expression types, rewritten expressions and names for @@ -374,7 +372,7 @@ top::Expr ::= 'case_any' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' local monadInExprs::Boolean = monadicallyUsedExpr(es.rawExprs, top.env, ml.mUpSubst, top.frame, top.grammarName, top.compiledGrammars, top.config, top.flowEnv, - top.expectedMonad, false, top.originRules); + top.expectedMonad, false); local mplus::Expr = monadPlus(); local mzero::Expr = monadZero(); @@ -411,7 +409,6 @@ top::Expr ::= 'case_any' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' expectedMonad = top.expectedMonad; alwaysDecorated = false; isRoot = top.isRoot; - originRules = top.originRules; }.monadRewritten, caseExprs); --Take the rewritten functions and apply them to the names to get expressions of a monad type @@ -425,7 +422,7 @@ top::Expr ::= 'case_any' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' {flowEnv = top.flowEnv; env = top.env; config=top.config; compiledGrammars=top.compiledGrammars; grammarName=top.grammarName; frame=top.frame; downSubst=top.mDownSubst; finalSubst=top.mDownSubst; - isRoot=top.isRoot; originRules=top.originRules; + isRoot=top.isRoot; }.typerep in if isMonad(ty, top.env) && monadsMatch(ty, top.expectedMonad, top.mDownSubst).fst @@ -444,7 +441,7 @@ top::Expr ::= 'case_any' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' mcaseBindsApps(es.rawExprs, newNames, mplused, top.env, ml.mUpSubst, top.frame, top.grammarName, top.compiledGrammars, top.config, top.flowEnv, - top.expectedMonad, top.isRoot, top.originRules); + top.expectedMonad, top.isRoot); top.monadRewritten = applied; top.mUpSubst = ml.mUpSubst; @@ -465,11 +462,11 @@ function mcaseBindsApps Expr ::= exprs::[Expr] names::[String] base::Expr env::Env sub::Substitution f::BlockContext gn::String cg::EnvTree c::Decorated CmdArgs - fe::FlowEnv em::Type iR::Boolean oR::[Decorated Expr] + fe::FlowEnv em::Type iR::Boolean { local subcall::Expr = mcaseBindsApps(tail(exprs), tail(names), base, - env, sub, f, gn, cg, c, fe, em, iR, oR); + env, sub, f, gn, cg, c, fe, em, iR); return if null(exprs) then base @@ -477,7 +474,7 @@ Expr ::= exprs::[Expr] names::[String] base::Expr {env=env; mDownSubst=sub; frame=f; grammarName=gn; downSubst=sub; finalSubst=sub; compiledGrammars=cg; config=c; flowEnv=fe; - expectedMonad=em; originRules = oR; + expectedMonad=em; isRoot = iR; alwaysDecorated = false; }.mtyperep in if isMonad(ety, env) && fst(monadsMatch(ety, em, sub)) @@ -583,7 +580,6 @@ top::MatchRule ::= pt::PatternList arr::Arrow_kwd e::Expr ne.finalSubst = top.mDownSubst; ne.downSubst = top.mDownSubst; ne.alwaysDecorated = false; - ne.originRules = []; ne.isRoot = false; top.patternTypeList = pt.patternTypeList; @@ -604,7 +600,6 @@ top::MatchRule ::= pt::PatternList 'when' cond::Expr arr::Arrow_kwd e::Expr ncond.finalSubst = top.mDownSubst; ncond.downSubst = top.mDownSubst; ncond.alwaysDecorated = false; - ncond.originRules = []; ncond.isRoot = false; local ne::Expr = e; ne.flowEnv = top.temp_flowEnv; @@ -616,7 +611,6 @@ top::MatchRule ::= pt::PatternList 'when' cond::Expr arr::Arrow_kwd e::Expr ne.finalSubst = top.mDownSubst; ne.downSubst = top.mDownSubst; ne.alwaysDecorated = false; - ne.originRules = []; ne.isRoot = false; top.patternTypeList = pt.patternTypeList; @@ -637,7 +631,6 @@ top::MatchRule ::= pt::PatternList 'when' cond::Expr 'matches' p::Pattern arr::A ncond.finalSubst = top.mDownSubst; ncond.downSubst = top.mDownSubst; ncond.alwaysDecorated = false; - ncond.originRules = []; ncond.isRoot = false; local ne::Expr = e; ne.flowEnv = top.temp_flowEnv; @@ -649,7 +642,6 @@ top::MatchRule ::= pt::PatternList 'when' cond::Expr 'matches' p::Pattern arr::A ne.finalSubst = top.mDownSubst; ne.downSubst = top.mDownSubst; ne.alwaysDecorated = false; - ne.originRules = []; ne.isRoot = false; top.patternTypeList = pt.patternTypeList; @@ -700,7 +692,6 @@ top::AbstractMatchRule ::= pl::[Decorated Pattern] cond::Maybe<(Expr, Maybe Date: Mon, 1 Apr 2024 17:35:59 -0500 Subject: [PATCH 213/283] Fix bugs with adding deps for sharing in flow graph construction --- .../silver/compiler/definition/flow/ast/Flow.sv | 1 + .../definition/flow/driver/ProductionGraph.sv | 17 ++++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/grammars/silver/compiler/definition/flow/ast/Flow.sv b/grammars/silver/compiler/definition/flow/ast/Flow.sv index f8a09d2a3..f7ff1246e 100644 --- a/grammars/silver/compiler/definition/flow/ast/Flow.sv +++ b/grammars/silver/compiler/definition/flow/ast/Flow.sv @@ -427,6 +427,7 @@ top::FlowDef ::= prod::String parent::VertexType termProd::String sigName::St - A tree that is elsewhere decorated with additional inherited attributes. - - @param prod the full name of the production + - @param nt the full name of the nonterminal - @param ref the vertex type of the shared tree - @param decSite the vertex type that is supplying the attributes - @param alwaysDec is this decoration uncondtional (as opposed to e.g. a unique reference appearing in an if/else branch) diff --git a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv index a98247fc6..4a2dae275 100644 --- a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv @@ -167,7 +167,7 @@ ProductionGraph ::= dcl::ValueDclInfo defs::[FlowDef] flowEnv::FlowEnv realEn addFwdSynEqs(prod, synsBySuspicion.fst, flowEnv) ++ addFwdInhEqs(prod, inhs, flowEnv)) ++ flatMap(addFwdProdAttrInhEqs(prod, _, inhs, flowEnv), allFwdProdAttrs(defs)) ++ - flatMap(addSharingEqs(realEnv, _), defs); + flatMap(addSharingEqs(flowEnv, realEnv, _), defs); -- (safe, suspect) local synsBySuspicion :: Pair<[String] [String]> = @@ -224,7 +224,7 @@ ProductionGraph ::= ns::NamedSignature flowEnv::FlowEnv realEnv::Env prodEnv: local fixedEdges :: [(FlowVertex, FlowVertex)] = normalEdges ++ - flatMap(addSharingEqs(realEnv, _), defs); + flatMap(addSharingEqs(flowEnv, realEnv, _), defs); -- In functions, this is just `<-` contributions to local collections from aspects. local suspectEdges :: [(FlowVertex, FlowVertex)] = @@ -408,15 +408,18 @@ fun addDefEqs {-- - Introduce edges for inherited attributes on shared references to their decoration sites. -} - fun addSharingEqs [(FlowVertex, FlowVertex)] ::= realEnv::Env d::FlowDef = + fun addSharingEqs [(FlowVertex, FlowVertex)] ::= flowEnv::FlowEnv realEnv::Env d::FlowDef = case d of - | refDecSiteEq(_, nt, ref, decSite, _) when + | refDecSiteEq(prod, nt, ref, decSite, _) when case ref of | localVertexType(fName) -> !isForwardProdAttr(fName, realEnv) - | _ -> false + | _ -> true end -> - map( - \ attr::String -> (ref.inhVertex(attr), decSite.inhVertex(attr)), + filterMap( + \ attr::String -> + if vertexHasInhEq(prod, ref, attr, flowEnv) + then nothing() -- There is an override equation, so the attribute isn't supplied through sharing + else just((ref.inhVertex(attr), decSite.inhVertex(attr))), getInhAndInhOnTransAttrsOn(nt, realEnv)) | _ -> [] end; From 859c2a94cede4bdc07715cbbb948bc4ff92d2279 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 2 Apr 2024 13:34:34 -0500 Subject: [PATCH 214/283] Fix a few more flow errors --- grammars/silver/compiler/definition/core/Expr.sv | 8 ++++---- .../silver/compiler/definition/core/ProductionBody.sv | 2 +- grammars/silver/compiler/definition/flow/env/Expr.sv | 2 +- .../silver/compiler/definition/flow/env/ProductionBody.sv | 2 ++ .../silver/compiler/extension/implicit_monads/Expr.sv | 3 +++ .../silver/compiler/extension/implicit_monads/Util.sv | 2 +- grammars/silver/compiler/extension/rewriting/Rewriting.sv | 2 +- 7 files changed, 13 insertions(+), 8 deletions(-) diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index f4dc3d455..d7f088fcc 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -19,8 +19,8 @@ flowtype unparse {} on Expr, Exprs, ExprInhs, ExprInh, ExprLHSExpr; flowtype freeVars {frame} on Expr, Exprs, ExprInhs, ExprInh, ExprLHSExpr; flowtype Expr = forward {grammarName, env, flowEnv, downSubst, finalSubst, frame, isRoot, compiledGrammars, config}, - decorate {forward, alwaysDecorated, originRules}, - errors {forward, alwaysDecorated}; + decorate {forward, decSiteVertexInfo, alwaysDecorated, originRules}, + errors {forward, decSiteVertexInfo}; flowtype decorate {grammarName, env, flowEnv, downSubst, finalSubst, frame, originRules, compiledGrammars, config} on Exprs; flowtype decorate {grammarName, env, flowEnv, downSubst, finalSubst, frame, originRules, compiledGrammars, config, decoratingnt, allSuppliedInhs} on ExprInhs, ExprInh; @@ -937,11 +937,11 @@ tracked nonterminal AppExprs with flowtype AppExprs = decorate { config, grammarName, env, frame, compiledGrammars, appExprTypereps, appExprApplied, originRules, - downSubst, finalSubst, flowEnv + downSubst, finalSubst, flowEnv, appIndexOffset }, errors { config, grammarName, env, frame, compiledGrammars, appExprTypereps, appExprApplied, - downSubst, finalSubst, flowEnv + downSubst, finalSubst, flowEnv, decSiteVertexInfo, appProd, appIndexOffset }; tracked nonterminal AppExpr with diff --git a/grammars/silver/compiler/definition/core/ProductionBody.sv b/grammars/silver/compiler/definition/core/ProductionBody.sv index e297274f1..1c707e281 100644 --- a/grammars/silver/compiler/definition/core/ProductionBody.sv +++ b/grammars/silver/compiler/definition/core/ProductionBody.sv @@ -320,7 +320,7 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr { forwards to errorAttributeDef( [errFromOrigin(attr, attr.name ++ " is an annotation, which are supplied to productions as arguments, not defined as equations.")], - dl, attr, e); + dl, attr, @e); } abstract production synthesizedAttributeDef implements AttributeDef diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index 5beb6fd25..68b65c7ea 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -139,7 +139,7 @@ top::Expr ::= @q::QName -- Note that we don't project functions at the moment, since we don't build function flow graphs during inference. inherited attribute appProd::Maybe occurs on AppExprs, AppExpr; --- The offset of the first supplied signature element, if the production implements a dispatch signautre and has extra children. +-- The offset of the first supplied signature element, if the production implements a dispatch signature and has extra children. inherited attribute appIndexOffset::Integer occurs on AppExprs, AppExpr; propagate appProd, appIndexOffset on AppExprs; diff --git a/grammars/silver/compiler/definition/flow/env/ProductionBody.sv b/grammars/silver/compiler/definition/flow/env/ProductionBody.sv index 6a0f77d9b..b4066a5c0 100644 --- a/grammars/silver/compiler/definition/flow/env/ProductionBody.sv +++ b/grammars/silver/compiler/definition/flow/env/ProductionBody.sv @@ -88,6 +88,8 @@ aspect production errorAttributeDef top::ProductionStmt ::= msg::[Message] @dl::DefLHS @attr::QNameAttrOccur e::Expr { propagate flowEnv; + e.decSiteVertexInfo = nothing(); + e.alwaysDecorated = false; } aspect production synthesizedAttributeDef top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index 61d30f6c5..19ba50063 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -193,6 +193,7 @@ top::Expr ::= e::Expr '(' es::AppExprs ',' anns::AnnoAppExprs ')' nes.alwaysDecorated = false; nes.decSiteVertexInfo = nothing(); nes.appProd = nothing(); + nes.appIndexOffset = 0; nes.appExprTypereps = reverse(performSubstitution(ne.mtyperep, ne.mUpSubst).inputTypes); nes.appExprApplied = ne.unparse; nes.monadArgumentsAllowed = acceptableMonadFunction(e); @@ -453,6 +454,7 @@ top::Expr ::= e::Expr '.' 'forward' ne.config = top.config; ne.env = top.env; ne.flowEnv = top.flowEnv; + ne.decSiteVertexInfo = nothing(); ne.alwaysDecorated = false; ne.isRoot = false; ne.monadicallyUsed = false; --this needs to change when we decorated monadic trees @@ -552,6 +554,7 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur then q.typerep else monadOfType(top.expectedMonad, q.typerep) else q.typerep; + top.mUpSubst = top.mDownSubst; top.notExplicitAttributes <- e.notExplicitAttributes ++ if q.found diff --git a/grammars/silver/compiler/extension/implicit_monads/Util.sv b/grammars/silver/compiler/extension/implicit_monads/Util.sv index 9a3c38010..f7c3fab01 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Util.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Util.sv @@ -77,7 +77,7 @@ fun monadsMatch Pair ::= ty1::Type ty2::Type subst::Substi We also need to use this because we occasionally need to use new to drop the decoration from the type of things we're passing into binds.-} -fun acceptableMonadFunction Boolean ::= f::Decorated Expr = +fun acceptableMonadFunction Boolean ::= f::Decorated Expr with {forward} = case f of | functionReference(qNameId(name)) -> name.name == "silver:core:alt" diff --git a/grammars/silver/compiler/extension/rewriting/Rewriting.sv b/grammars/silver/compiler/extension/rewriting/Rewriting.sv index 39ace378b..9614e1741 100644 --- a/grammars/silver/compiler/extension/rewriting/Rewriting.sv +++ b/grammars/silver/compiler/extension/rewriting/Rewriting.sv @@ -227,7 +227,7 @@ top::Expr ::= 'rule' 'on' ty::TypeExpr 'of' Opt_Vbar_t ml::MRuleList 'end' checkExpr.alwaysDecorated = false; checkExpr.decSiteVertexInfo = nothing(); checkExpr.isRoot = false; - checkExpr.originRules = top.originRules; + checkExpr.originRules = []; ml.env = top.env; ml.matchRulePatternSize = 1; From bb5d3b7bb5cdec077f882931a9356df7e23f837b Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 2 Apr 2024 18:11:06 -0500 Subject: [PATCH 215/283] Better pp for flow vertex names in error messages --- grammars/silver/compiler/analysis/uniqueness/Expr.sv | 4 ++-- grammars/silver/compiler/analysis/warnings/flow/Inh.sv | 8 ++++---- .../silver/compiler/definition/flow/ast/VertexType.sv | 10 +++++++++- grammars/silver/compiler/translation/java/core/Expr.sv | 4 ++-- .../compiler/translation/java/core/NamedSignature.sv | 2 +- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/grammars/silver/compiler/analysis/uniqueness/Expr.sv b/grammars/silver/compiler/analysis/uniqueness/Expr.sv index d1531b870..d61e3e166 100644 --- a/grammars/silver/compiler/analysis/uniqueness/Expr.sv +++ b/grammars/silver/compiler/analysis/uniqueness/Expr.sv @@ -46,7 +46,7 @@ top::Expr ::= '@' e::Expr | just(v) -> -- Check that we are exported by the decoration site. if !isExportedBy(top.grammarName, vertexGrammars, top.compiledGrammars) - then [errFromOrigin(top, s"Orphaned sharing of ${v.vertexName} in production ${top.frame.fullName}.")] + then [errFromOrigin(top, s"Orphaned sharing of ${v.vertexPP} in production ${top.frame.fullName}.")] -- Check that there is at most one unique reference taken to this decoration site. else case lookupSharedRefs(top.frame.fullName, v, top.flowEnv) of @@ -63,7 +63,7 @@ top::Expr ::= '@' e::Expr case e.flowVertexInfo of | just(transAttrVertexType(v, transAttr)) when lookupSharedRefs(top.frame.fullName, v, top.flowEnv) matches sr :: _ -> - [errFromOrigin(e, s"Cannot share ${v.vertexName}.${transAttr} in production ${top.frame.fullName}, because ${v.vertexName} is also shared (at ${sr.sourceGrammar}:${sr.sourceLocation.unparse}).")] + [errFromOrigin(e, s"Cannot share ${v.vertexName}.${transAttr} in production ${top.frame.fullName}, because ${v.vertexPP} is also shared (at ${sr.sourceGrammar}:${sr.sourceLocation.unparse}).")] | _ -> [] end; } diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index 3e46b7dfe..29604ce5b 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -332,7 +332,7 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr then [mwdaWrnFromOrigin(top, s"Inherited override equation may exceed a flow type with hidden transitive dependencies on ${implode(", ", lhsInhExceedsRefDecSiteDeps)}; " ++ - s"${attr.attrDcl.fullName} on some reference to ${dl.defLHSVertex.vertexName} may be expected to depend only on ${implode(", ", set:toList(refDecSiteInhDepsLhsInh.fromJust))}")] + s"${attr.attrDcl.fullName} on some reference to ${dl.defLHSVertex.vertexPP} may be expected to depend only on ${implode(", ", set:toList(refDecSiteInhDepsLhsInh.fromJust))}")] else []; top.errors <- case dl.defLHSVertex of @@ -340,7 +340,7 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr when top.config.warnMissingInh && !null(lhsInhExceedsTransBaseRefDecSiteDeps) -> [mwdaWrnFromOrigin(top, s"Inherited override equation may exceed a flow type with hidden transitive dependencies on ${implode(", ", lhsInhExceedsTransBaseRefDecSiteDeps)}; " ++ - s"${transAttr}.${attr.attrDcl.fullName} on some reference to ${v.vertexName} may be expected to depend only on ${implode(", ", set:toList(transBaseRefDecSiteInhDepsLhsInh.fromJust))}")] + s"${transAttr}.${attr.attrDcl.fullName} on some reference to ${v.vertexPP} may be expected to depend only on ${implode(", ", set:toList(transBaseRefDecSiteInhDepsLhsInh.fromJust))}")] | _ -> [] end; } @@ -690,7 +690,7 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur | [] -> [] | sites -> [mwdaWrnFromOrigin(top, s"Access of syn attribute ${q.name} on ${e.unparse} requires missing inherited attribute ${inh} to be supplied in the following places:\n" ++ - implode("\n", map(\ s::(String, VertexType) -> s" ${s.2.vertexName} in production ${s.1}", sites)))] + implode("\n", map(\ s::(String, VertexType) -> s" ${s.2.vertexPP} in production ${s.1}", sites)))] end, inhs) else [mwdaWrnFromOrigin(top, "Access of syn attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] end @@ -839,7 +839,7 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur | [] -> [] | sites -> [mwdaWrnFromOrigin(top, s"Access of trans attribute ${q.name} on ${e.unparse} requires missing inherited attribute ${inh} to be supplied in the following places:\n" ++ - implode("\n", map(\ s::(String, VertexType) -> s" ${s.2.vertexName} in production ${s.1}", sites)))] + implode("\n", map(\ s::(String, VertexType) -> s" ${s.2.vertexPP} in production ${s.1}", sites)))] end, inhs) else [mwdaWrnFromOrigin(top, "Access of trans attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] end diff --git a/grammars/silver/compiler/definition/flow/ast/VertexType.sv b/grammars/silver/compiler/definition/flow/ast/VertexType.sv index 213a3e95c..224c8e864 100644 --- a/grammars/silver/compiler/definition/flow/ast/VertexType.sv +++ b/grammars/silver/compiler/definition/flow/ast/VertexType.sv @@ -8,11 +8,12 @@ grammar silver:compiler:definition:flow:ast; - forwardVertexType, anonVertexType(x) -} data nonterminal VertexType with - vertexName, + vertexName, vertexPP, synVertex, inhVertex, fwdVertex, eqVertex; derive Eq, Ord on VertexType; synthesized attribute vertexName::String; +synthesized attribute vertexPP::String; {-- FlowVertex for a synthesized attribute for this FlowVertex -} synthesized attribute synVertex :: (FlowVertex ::= String); @@ -39,6 +40,7 @@ abstract production lhsVertexType_real top::VertexType ::= { top.vertexName = "top"; + top.vertexPP = "left-hand side"; top.synVertex = lhsSynVertex; top.inhVertex = lhsInhVertex; top.fwdVertex = forwardEqVertex_singleton; @@ -52,6 +54,7 @@ abstract production rhsVertexType top::VertexType ::= sigName::String { top.vertexName = sigName; + top.vertexPP = "child " ++ sigName; top.synVertex = rhsSynVertex(sigName, _); top.inhVertex = rhsInhVertex(sigName, _); top.fwdVertex = rhsSynVertex(sigName, "forward"); @@ -65,6 +68,7 @@ abstract production localVertexType top::VertexType ::= fName::String { top.vertexName = fName; + top.vertexPP = "local " ++ fName; top.synVertex = localSynVertex(fName, _); top.inhVertex = localInhVertex(fName, _); top.fwdVertex = localSynVertex(fName, "forward"); @@ -78,6 +82,7 @@ abstract production transAttrVertexType top::VertexType ::= v::VertexType transAttr::String { top.vertexName = s"${v.vertexName}.${transAttr}"; + top.vertexPP = s"translation attribute ${transAttr} of ${v.vertexPP}"; top.synVertex = \ attr::String -> v.synVertex(s"${transAttr}.${attr}"); top.inhVertex = \ attr::String -> v.inhVertex(s"${transAttr}.${attr}"); top.fwdVertex = v.synVertex(s"${transAttr}.forward"); @@ -91,6 +96,7 @@ abstract production forwardVertexType_real top::VertexType ::= { top.vertexName = "forward"; + top.vertexPP = "forward"; top.synVertex = forwardSynVertex; top.inhVertex = forwardInhVertex; top.fwdVertex = forwardSynVertex("forward"); @@ -104,6 +110,7 @@ abstract production anonVertexType top::VertexType ::= x::String { top.vertexName = x; + top.vertexPP = s"anonymous decoration site ${x}"; top.synVertex = anonSynVertex(x, _); top.inhVertex = anonInhVertex(x, _); top.fwdVertex = anonSynVertex(x, "forward"); @@ -117,6 +124,7 @@ abstract production subtermVertexType top::VertexType ::= parent::VertexType prodName::String sigName::String { top.vertexName = s"${parent.vertexName}[${prodName}:${sigName}]"; + top.vertexPP = top.vertexName; -- Shouldn't appear in error messages? Gets too long to spell out anyway. top.synVertex = subtermSynVertex(parent, prodName, sigName, _); top.inhVertex = subtermInhVertex(parent, prodName, sigName, _); top.fwdVertex = subtermSynVertex(parent, prodName, sigName, "forward"); diff --git a/grammars/silver/compiler/translation/java/core/Expr.sv b/grammars/silver/compiler/translation/java/core/Expr.sv index 778edc8a9..64b161c22 100644 --- a/grammars/silver/compiler/translation/java/core/Expr.sv +++ b/grammars/silver/compiler/translation/java/core/Expr.sv @@ -516,7 +516,7 @@ top::Expr ::= '@' e::Expr | just(transAttrVertexType(rhsVertexType(sigName), transAttr)) -> case lookup(sigName, zip(top.frame.signature.inputNames, top.frame.signature.inputTypes)) of | just(ty) when getOccursDcl(transAttr, ty.typeName, top.env) matches occDcl :: _ -> - s"\t\t// Decoration site for ${e.flowVertexInfo.fromJust.vertexName}: ${decSite.vertexName}\n" ++ + s"\t\t// Decoration site for ${e.flowVertexInfo.fromJust.vertexPP}: ${decSite.vertexPP}\n" ++ s"\t\t${top.frame.className}.childInheritedAttributes[${top.frame.className}.i_${sigName}][${occDcl.attrOccursInitIndex}_dec_site] = " ++ s"(context) -> ${refAccessTranslation(top.env, top.flowEnv, top.frame.lhsNtName, decSite)};\n" | _ -> error("Couldn't find occurs dcl for " ++ transAttr ++ " on " ++ sigName) @@ -524,7 +524,7 @@ top::Expr ::= '@' e::Expr | just(transAttrVertexType(localVertexType(fName), transAttr)) -> case getValueDcl(fName, top.env) of | dcl :: _ when getOccursDcl(transAttr, dcl.typeScheme.typeName, top.env) matches occDcl :: _ -> - s"\t\t// Decoration site for ${e.flowVertexInfo.fromJust.vertexName}: ${decSite.vertexName}\n" ++ + s"\t\t// Decoration site for ${e.flowVertexInfo.fromJust.vertexPP}: ${decSite.vertexPP}\n" ++ s"\t\t${top.frame.className}.localInheritedAttributes[${dcl.attrOccursIndex}][${occDcl.attrOccursInitIndex}_dec_site] = " ++ s"(context) -> ${refAccessTranslation(top.env, top.flowEnv, top.frame.lhsNtName, decSite)};\n" | _ -> error("Couldn't find occurs dcl for " ++ transAttr ++ " on " ++ fName) diff --git a/grammars/silver/compiler/translation/java/core/NamedSignature.sv b/grammars/silver/compiler/translation/java/core/NamedSignature.sv index 7ae023bb4..d89f56c6e 100644 --- a/grammars/silver/compiler/translation/java/core/NamedSignature.sv +++ b/grammars/silver/compiler/translation/java/core/NamedSignature.sv @@ -378,7 +378,7 @@ fun sharedRefTranslation String ::= env::Env frame::BlockContext v::VertexType = s"context.localDecorated(${dcl.attrOccursIndex}).evalTrans(${occDcl.attrOccursIndex}, ${occDcl.attrOccursIndex}_inhs)" | _ -> error("Couldn't find occurs dcl for " ++ transAttr ++ " on " ++ fName) end - | _ -> error("Sharing for invalid sort of tree " ++ v.vertexName) + | _ -> error("Sharing for invalid sort of tree " ++ v.vertexPP) end; From 7de19379581ba62e1e881916e2f101849b7d4a59 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 3 Apr 2024 14:19:12 -0500 Subject: [PATCH 216/283] Allow specifying whether to propagate on shared children --- .../definition/core/ProductionBody.sv | 6 +++ .../compiler/definition/flow/ast/Flow.sv | 7 +++ .../compiler/extension/autoattr/BiEquality.sv | 4 +- .../compiler/extension/autoattr/Destruct.sv | 10 +++-- .../compiler/extension/autoattr/Equality.sv | 4 +- .../compiler/extension/autoattr/Functor.sv | 4 +- .../compiler/extension/autoattr/Inherited.sv | 20 +++------ .../compiler/extension/autoattr/Monoid.sv | 4 +- .../compiler/extension/autoattr/Ordering.sv | 8 ++-- .../compiler/extension/autoattr/Project.sv | 1 + .../compiler/extension/autoattr/Propagate.sv | 45 ++++++++++++------- .../compiler/extension/autoattr/Threaded.sv | 34 +++++--------- .../extension/strategyattr/Strategy.sv | 6 +-- .../compiler/extension/treegen/Arbitrary.sv | 2 +- .../compiler/langserver/ReferenceLocations.sv | 17 ++++--- .../translation/java/core/ProductionBody.sv | 6 +++ 16 files changed, 102 insertions(+), 76 deletions(-) diff --git a/grammars/silver/compiler/definition/core/ProductionBody.sv b/grammars/silver/compiler/definition/core/ProductionBody.sv index 1c707e281..f4f168fc8 100644 --- a/grammars/silver/compiler/definition/core/ProductionBody.sv +++ b/grammars/silver/compiler/definition/core/ProductionBody.sv @@ -107,6 +107,12 @@ top::ProductionStmt ::= e::[Message] top.errors <- e; } +abstract production emptyProductionStmt +top::ProductionStmt ::= +{ + top.unparse = ""; +} + -------------------------------------------------------------------------------- aspect default production diff --git a/grammars/silver/compiler/definition/flow/ast/Flow.sv b/grammars/silver/compiler/definition/flow/ast/Flow.sv index f7ff1246e..a76dda86e 100644 --- a/grammars/silver/compiler/definition/flow/ast/Flow.sv +++ b/grammars/silver/compiler/definition/flow/ast/Flow.sv @@ -449,6 +449,13 @@ top::FlowDef ::= prod::String sigName::String sourceProd::String source::VertexT top.sigShareContribs := [(crossnames(prod, sigName), sourceProd, source)]; } +abstract production emptyFlowDef +top::FlowDef ::= +{ + top.prodGraphContribs := []; + top.flowEdges = []; +} + -- fun crossnames String ::= a::String b::String = a ++ " @ " ++ b; diff --git a/grammars/silver/compiler/extension/autoattr/BiEquality.sv b/grammars/silver/compiler/extension/autoattr/BiEquality.sv index 663f2b190..138fd01be 100644 --- a/grammars/silver/compiler/extension/autoattr/BiEquality.sv +++ b/grammars/silver/compiler/extension/autoattr/BiEquality.sv @@ -60,7 +60,7 @@ top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedO } abstract production propagateBiequalitySynPartial implements Propagate -top::ProductionStmt ::= @synPartial::QName inh::String syn::String +top::ProductionStmt ::= includeShared::Boolean @synPartial::QName inh::String syn::String { top.unparse = s"propagate ${synPartial.unparse};"; @@ -95,7 +95,7 @@ top::ProductionStmt ::= @synPartial::QName inh::String syn::String } abstract production propagateBiequalitySyn implements Propagate -top::ProductionStmt ::= @syn::QName inh::String synPartial::String +top::ProductionStmt ::= propagateShared::Boolean @syn::QName inh::String synPartial::String { top.unparse = s"propagate ${syn.unparse};"; diff --git a/grammars/silver/compiler/extension/autoattr/Destruct.sv b/grammars/silver/compiler/extension/autoattr/Destruct.sv index f9e5d3921..90de3b33f 100644 --- a/grammars/silver/compiler/extension/autoattr/Destruct.sv +++ b/grammars/silver/compiler/extension/autoattr/Destruct.sv @@ -71,15 +71,15 @@ top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedO - @param attr The name of the attribute to propagate -} abstract production propagateDestruct implements Propagate -top::ProductionStmt ::= @attr::QName +top::ProductionStmt ::= includeShared::Boolean @attr::QName { - top.unparse = s"propagate ${attr.unparse};"; + top.unparse = s"propagate ${if includeShared then "@" else ""}${attr.unparse};"; local numChildren::Integer = length(top.frame.signature.inputElements); forwards to foldr( productionStmtAppend(_, _), - errorProductionStmt([]), -- No emptyProductionStmt? + emptyProductionStmt(), map( \ ie::Pair -> Silver_ProductionStmt { @@ -106,7 +106,9 @@ top::ProductionStmt ::= @attr::QName }, filter( \ ie::Pair -> - !null(getOccursDcl(attr.lookupAttribute.dcl.fullName, ie.snd.typerep.typeName, top.env)), + isDecorable(ie.2.elementDclType, top.env) && + !null(getOccursDcl(attr.lookupAttribute.dcl.fullName, ie.snd.typerep.typeName, top.env)) && + (includeShared || !ie.2.elementShared), zip(range(0, numChildren), top.frame.signature.inputElements)))); } diff --git a/grammars/silver/compiler/extension/autoattr/Equality.sv b/grammars/silver/compiler/extension/autoattr/Equality.sv index fe83b369c..cd9d7c63f 100644 --- a/grammars/silver/compiler/extension/autoattr/Equality.sv +++ b/grammars/silver/compiler/extension/autoattr/Equality.sv @@ -28,9 +28,9 @@ top::AGDcl ::= 'equality' 'attribute' syn::Name 'with' inh::QName ';' - @param attr The name of the attribute to propagate -} abstract production propagateEquality implements Propagate -top::ProductionStmt ::= @syn::QName inh::String +top::ProductionStmt ::= includeShared::Boolean @syn::QName inh::String { - top.unparse = s"propagate ${syn.unparse};"; + top.unparse = s"propagate ${if includeShared then "@" else ""}${syn.unparse};"; forwards to Silver_ProductionStmt { diff --git a/grammars/silver/compiler/extension/autoattr/Functor.sv b/grammars/silver/compiler/extension/autoattr/Functor.sv index 54ea3d492..8da87e76b 100644 --- a/grammars/silver/compiler/extension/autoattr/Functor.sv +++ b/grammars/silver/compiler/extension/autoattr/Functor.sv @@ -53,9 +53,9 @@ top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedO - @param attr The name of the attribute to propagate -} abstract production propagateFunctor implements Propagate -top::ProductionStmt ::= @attr::QName +top::ProductionStmt ::= includeShared::Boolean @attr::QName { - top.unparse = s"propagate ${attr.unparse};"; + top.unparse = s"propagate ${if includeShared then "@" else ""}{attr.unparse};"; -- No explicit errors, for now. The only conceivable issue is the attribute not -- occuring on the LHS but this should be caught by the forward errors. diff --git a/grammars/silver/compiler/extension/autoattr/Inherited.sv b/grammars/silver/compiler/extension/autoattr/Inherited.sv index 52f787a69..57d4ae041 100644 --- a/grammars/silver/compiler/extension/autoattr/Inherited.sv +++ b/grammars/silver/compiler/extension/autoattr/Inherited.sv @@ -1,29 +1,23 @@ grammar silver:compiler:extension:autoattr; abstract production propagateInh implements Propagate -top::ProductionStmt ::= @attr::QName +top::ProductionStmt ::= includeShared::Boolean @attr::QName { - top.unparse = s"propagate ${attr.unparse};"; + top.unparse = s"propagate ${if includeShared then "@" else ""}${attr.unparse};"; local attrFullName::String = attr.lookupAttribute.dcl.fullName; local inputsWithAttr::[NamedSignatureElement] = filter( \ input::NamedSignatureElement -> - ((isDecorable(input.typerep, top.env) && - -- Only propagate for unique decorated children that don't have the attribute - case getMaxRefSet(input.typerep, top.env) of - | just(inhs) -> !contains(attrFullName, inhs) - | nothing() -> false - end) || - -- TODO: Check that the attribute is not already defined. - -- This may require consulting the flowEnv, but shouldn't require inferring flow types. - input.elementShared) && - !null(getOccursDcl(attrFullName, input.typerep.typeName, top.env)), + isDecorable(input.elementDclType, top.env) && + !null(getOccursDcl(attrFullName, input.typerep.typeName, top.env)) && + (includeShared || !input.elementShared), top.frame.signature.inputElements); + forwards to foldr( productionStmtAppend(_, _), - errorProductionStmt([]), -- No emptyProductionStmt? + emptyProductionStmt(), map( \ ie::NamedSignatureElement -> attributeDef( diff --git a/grammars/silver/compiler/extension/autoattr/Monoid.sv b/grammars/silver/compiler/extension/autoattr/Monoid.sv index b1e789bf3..61a762216 100644 --- a/grammars/silver/compiler/extension/autoattr/Monoid.sv +++ b/grammars/silver/compiler/extension/autoattr/Monoid.sv @@ -115,9 +115,9 @@ top::Operation ::= - @param attr The name of the attribute to propagate -} abstract production propagateMonoid implements Propagate -top::ProductionStmt ::= @attr::QName +top::ProductionStmt ::= includeShared::Boolean @attr::QName { - top.unparse = s"propagate ${attr.unparse};"; + top.unparse = s"propagate ${if includeShared then "@" else ""}${attr.unparse};"; -- No explicit errors, for now. The only conceivable issue is the attribute not -- occuring on the LHS but this should be caught by the forward errors. diff --git a/grammars/silver/compiler/extension/autoattr/Ordering.sv b/grammars/silver/compiler/extension/autoattr/Ordering.sv index 2ca544d43..db10954c4 100644 --- a/grammars/silver/compiler/extension/autoattr/Ordering.sv +++ b/grammars/silver/compiler/extension/autoattr/Ordering.sv @@ -35,9 +35,9 @@ top::AGDcl ::= 'ordering' 'attribute' keySyn::Name ',' syn::Name 'with' inh::QNa - Propagate a ordering key synthesized attribute on the enclosing production -} abstract production propagateOrderingKey implements Propagate -top::ProductionStmt ::= @syn::QName +top::ProductionStmt ::= includeShared::Boolean @syn::QName { - top.unparse = s"propagate ${syn.unparse};"; + top.unparse = s"propagate ${if includeShared then "@" else ""}${syn.unparse};"; forwards to Silver_ProductionStmt { @@ -50,9 +50,9 @@ top::ProductionStmt ::= @syn::QName - Propagate a ordering synthesized attribute on the enclosing production -} abstract production propagateOrdering implements Propagate -top::ProductionStmt ::= @syn::QName inh::String keySyn::String +top::ProductionStmt ::= includeShared::Boolean @syn::QName inh::String keySyn::String { - top.unparse = s"propagate ${syn.unparse};"; + top.unparse = s"propagate ${if includeShared then "@" else ""}${syn.unparse};"; local topName::String = top.frame.signature.outputElement.elementName; forwards to diff --git a/grammars/silver/compiler/extension/autoattr/Project.sv b/grammars/silver/compiler/extension/autoattr/Project.sv index 8e1c08511..572839999 100644 --- a/grammars/silver/compiler/extension/autoattr/Project.sv +++ b/grammars/silver/compiler/extension/autoattr/Project.sv @@ -4,6 +4,7 @@ imports silver:compiler:definition:core; imports silver:compiler:definition:env; imports silver:compiler:definition:type; imports silver:compiler:definition:type:syntax; +imports silver:compiler:definition:flow:ast; imports silver:compiler:definition:flow:env; imports silver:compiler:analysis:typechecking:core; imports silver:compiler:modification:collection; diff --git a/grammars/silver/compiler/extension/autoattr/Propagate.sv b/grammars/silver/compiler/extension/autoattr/Propagate.sv index d3c80a360..477fc74f9 100644 --- a/grammars/silver/compiler/extension/autoattr/Propagate.sv +++ b/grammars/silver/compiler/extension/autoattr/Propagate.sv @@ -1,7 +1,7 @@ grammar silver:compiler:extension:autoattr; concrete production propagateOnNTListExcludingDcl_c -top::AGDcl ::= 'propagate' attrs::NameList 'on' nts::NameList 'excluding' ps::ProdNameList ';' +top::AGDcl ::= 'propagate' attrs::AttrNameList 'on' nts::NameList 'excluding' ps::ProdNameList ';' { top.unparse = s"propagate ${attrs.unparse} on ${nts.unparse} excluding ${ps.unparse};"; propagate env; @@ -11,7 +11,7 @@ top::AGDcl ::= 'propagate' attrs::NameList 'on' nts::NameList 'excluding' ps::Pr } concrete production propagateOnNTListDcl_c -top::AGDcl ::= 'propagate' attrs::NameList 'on' nts::NameList ';' +top::AGDcl ::= 'propagate' attrs::AttrNameList 'on' nts::NameList ';' { top.unparse = s"propagate ${attrs.unparse} on ${nts.unparse};"; @@ -20,7 +20,7 @@ top::AGDcl ::= 'propagate' attrs::NameList 'on' nts::NameList ';' } abstract production propagateOnNTListDcl -top::AGDcl ::= attrs::NameList nts::NameList ps::ProdNameList +top::AGDcl ::= attrs::AttrNameList nts::NameList ps::ProdNameList { top.unparse = s"propagate ${attrs.unparse} on ${nts.unparse} excluding ${ps.unparse};"; @@ -39,7 +39,7 @@ top::AGDcl ::= attrs::NameList nts::NameList ps::ProdNameList -- always the case (see options and closed nonterminals.) -- For such productions the attribute must still be explicitly propagated. abstract production propagateOnOneNTDcl -top::AGDcl ::= attrs::NameList nt::QName ps::ProdNameList +top::AGDcl ::= attrs::AttrNameList nt::QName ps::ProdNameList { top.unparse = s"propagate ${attrs.unparse} on ${nt.unparse} excluding ${ps.unparse};"; propagate env; @@ -67,7 +67,7 @@ top::AGDcl ::= attrs::NameList nt::QName ps::ProdNameList } abstract production propagateAspectDcl -top::AGDcl ::= d::ValueDclInfo attrs::NameList +top::AGDcl ::= d::ValueDclInfo attrs::AttrNameList { top.errors := if null(forward.errors) @@ -104,7 +104,7 @@ top::AGDcl ::= d::ValueDclInfo attrs::NameList } concrete production propagateAttrList -top::ProductionStmt ::= 'propagate' ns::NameList ';' +top::ProductionStmt ::= 'propagate' ns::AttrNameList ';' { top.unparse = s"propagate ${ns.unparse};"; @@ -112,18 +112,18 @@ top::ProductionStmt ::= 'propagate' ns::NameList ';' -- and propagateAttrDcl containing the remaining names forwards to case ns of - | nameListOne(n) -> propagateOneAttr(n) - | nameListCons(n, _, rest) -> + | attrNameListOne(ms, n) -> propagateOneAttr(ms, n) + | attrNameListCons(ms, n, _, rest) -> productionStmtAppend( - propagateOneAttr(n), + propagateOneAttr(ms, n), propagateAttrList($1, rest, $3)) end; } abstract production propagateOneAttr -top::ProductionStmt ::= attr::QName +top::ProductionStmt ::= ms::MaybeShared attr::QName { - top.unparse = s"propagate ${attr.unparse};"; + top.unparse = s"propagate ${ms.unparse}${attr.unparse};"; propagate env; -- We make an exception to permit propagated equations in places that would otherwise be orphaned. @@ -140,21 +140,36 @@ top::ProductionStmt ::= attr::QName forwards to if !null(attr.lookupAttribute.errors) then errorProductionStmt(attr.lookupAttribute.errors) - else attr.lookupAttribute.dcl.propagateDispatcher(attr); + else attr.lookupAttribute.dcl.propagateDispatcher(ms.isShared, attr); } -dispatch Propagate = ProductionStmt ::= @attr::QName; +dispatch Propagate = ProductionStmt ::= includeShared::Boolean @attr::QName; abstract production propagateError implements Propagate -top::ProductionStmt ::= @attr::QName +top::ProductionStmt ::= includeShared::Boolean @attr::QName { forwards to errorProductionStmt( [errFromOrigin(attr, s"Attribute ${attr.name} cannot be propagated")]); } +tracked nonterminal AttrNameList with config, grammarName, unparse, errors, env; +propagate config, grammarName, env, errors on AttrNameList; + +concrete production attrNameListOne +top::AttrNameList ::= ms::MaybeShared n::QName +{ + top.unparse = ms.unparse ++ n.unparse; + top.errors <- n.lookupAttribute.errors; +} + +concrete production attrNameListCons +top::AttrNameList ::= ms::MaybeShared h::QName ',' t::AttrNameList +{ + top.unparse = ms.unparse ++ h.unparse ++ ", " ++ t.unparse; + top.errors <- h.lookupAttribute.errors; +} --- Need a seperate nonterminal since this can be empty and needs env to check errors tracked nonterminal ProdNameList with config, grammarName, env, unparse, names, errors; propagate config, grammarName, env, errors on ProdNameList; diff --git a/grammars/silver/compiler/extension/autoattr/Threaded.sv b/grammars/silver/compiler/extension/autoattr/Threaded.sv index 64ea3ab3b..32615ca88 100644 --- a/grammars/silver/compiler/extension/autoattr/Threaded.sv +++ b/grammars/silver/compiler/extension/autoattr/Threaded.sv @@ -97,9 +97,9 @@ concrete productions top::Direction top.reversed = true; } abstract production propagateThreadedInh implements Propagate -top::ProductionStmt ::= @inh::QName isCol::Boolean rev::Boolean syn::String +top::ProductionStmt ::= includeShared::Boolean @inh::QName isCol::Boolean rev::Boolean syn::String { - top.unparse = s"propagate ${inh.unparse};"; + top.unparse = s"propagate ${if includeShared then "@" else ""}${inh.unparse};"; local lhsName::String = top.frame.signature.outputElement.elementName; local occursChildren::[String] = @@ -108,14 +108,9 @@ top::ProductionStmt ::= @inh::QName isCol::Boolean rev::Boolean syn::String filter( \ ie::NamedSignatureElement -> isDecorable(ie.typerep, top.env) && - -- Only propagate for unique decorated children that don't have the inh attribute - -- TODO: Handle dispatch signatures - case getMaxRefSet(ie.typerep, top.env) of - | just(inhs) -> !contains(inh.lookupAttribute.fullName, inhs) - | nothing() -> false - end && !null(getOccursDcl(inh.lookupAttribute.fullName, ie.typerep.typeName, top.env)) && - !null(getOccursDcl(syn, ie.typerep.typeName, top.env)), + !null(getOccursDcl(syn, ie.typerep.typeName, top.env)) && + (includeShared || !ie.elementShared), if null(getOccursDcl(syn, top.frame.lhsNtName, top.env)) && !null(top.frame.signature.inputElements) then init(top.frame.signature.inputElements) else top.frame.signature.inputElements)); @@ -133,9 +128,9 @@ top::ProductionStmt ::= @inh::QName isCol::Boolean rev::Boolean syn::String } abstract production propagateThreadedSyn implements Propagate -top::ProductionStmt ::= @syn::QName isCol::Boolean rev::Boolean inh::String +top::ProductionStmt ::= includeShared::Boolean @syn::QName isCol::Boolean rev::Boolean inh::String { - top.unparse = s"propagate ${syn.unparse};"; + top.unparse = s"propagate ${if includeShared then "@" else ""}${syn.unparse};"; local lhsName::String = top.frame.signature.outputElement.elementName; local occursChildren::[String] = @@ -144,14 +139,9 @@ top::ProductionStmt ::= @syn::QName isCol::Boolean rev::Boolean inh::String filter( \ ie::NamedSignatureElement -> isDecorable(ie.typerep, top.env) && - -- Only propagate for unique decorated children that don't have the inh attribute - -- TODO: Handle dispatch signatures - case getMaxRefSet(ie.typerep, top.env) of - | just(inhs) -> !contains(inh, inhs) - | nothing() -> false - end && !null(getOccursDcl(inh, ie.typerep.typeName, top.env)) && - !null(getOccursDcl(syn.lookupAttribute.fullName, ie.typerep.typeName, top.env)), + !null(getOccursDcl(syn.lookupAttribute.fullName, ie.typerep.typeName, top.env)) && + (includeShared || !ie.elementShared), top.frame.signature.inputElements)); forwards to threadSynDcl( @@ -195,7 +185,7 @@ top::ProductionStmt ::= isCol::Boolean inh::String syn::String children::[Name] forwards to foldr( productionStmtAppend(_, _), - errorProductionStmt([]), -- No emptyProductionStmt? + emptyProductionStmt(), zipWith( \ c1::Name c2::Name -> if c1.name != lhsName @@ -206,7 +196,7 @@ top::ProductionStmt ::= isCol::Boolean inh::String syn::String children::[Name] access( baseExpr(qNameId(c2)), '.', qNameAttrOccur(qName(if c2.name == lhsName then inh else syn)))) - else errorProductionStmt([]), + else emptyProductionStmt(), tail(children), children)); } @@ -223,7 +213,7 @@ top::ProductionStmt ::= isCol::Boolean inh::String syn::String children::[Name] forwards to foldr( productionStmtAppend(_, _), - errorProductionStmt([]), -- No emptyProductionStmt? + emptyProductionStmt(), zipWith( \ c1::Name c2::Name -> if c1.name == lhsName @@ -234,7 +224,7 @@ top::ProductionStmt ::= isCol::Boolean inh::String syn::String children::[Name] access( baseExpr(qNameId(c2)), '.', qNameAttrOccur(qName(if c2.name == lhsName then inh else syn)))) - else errorProductionStmt([]), + else emptyProductionStmt(), tail(children), children)); } diff --git a/grammars/silver/compiler/extension/strategyattr/Strategy.sv b/grammars/silver/compiler/extension/strategyattr/Strategy.sv index 35e2d2a23..afdc0ab11 100644 --- a/grammars/silver/compiler/extension/strategyattr/Strategy.sv +++ b/grammars/silver/compiler/extension/strategyattr/Strategy.sv @@ -117,9 +117,9 @@ top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedO - @param attr The name of the attribute to propagate -} abstract production propagateStrategy implements Propagate -top::ProductionStmt ::= @attr::QName +top::ProductionStmt ::= includeShared::Boolean @attr::QName { - top.unparse = s"propagate ${attr.unparse}"; + top.unparse = s"propagate ${if includeShared then "@" else ""}${attr.unparse}"; production isTotal::Boolean = attr.lookupAttribute.dcl.isTotal; production e::StrategyExpr = attr.lookupAttribute.dcl.strategyExpr; @@ -169,7 +169,7 @@ top::ProductionStmt ::= @attr::QName if isTotal then e2.totalTranslation else e2.partialTranslation, ';'), map( - \ n::String -> propagateOneAttr(qName(n)), + \ n::String -> propagateOneAttr(if includeShared then elemShared('@') else elemNotShared(), qName(n)), attr.lookupAttribute.dcl.liftedStrategyNames)); -- Uncomment for debugging diff --git a/grammars/silver/compiler/extension/treegen/Arbitrary.sv b/grammars/silver/compiler/extension/treegen/Arbitrary.sv index 7909d2e51..2a2af48f2 100644 --- a/grammars/silver/compiler/extension/treegen/Arbitrary.sv +++ b/grammars/silver/compiler/extension/treegen/Arbitrary.sv @@ -73,7 +73,7 @@ top::AGDcl ::= 'generator' n::Name '::' t::TypeExpr '{' grammars::GeneratorCompo $ProductionStmt{ foldr( productionStmtAppend(_, _), - errorProductionStmt([]), -- TODO: No nullProductionStmt? + emptyProductionStmt(), map(genNtLocalDecl(forward.env, specEnv, _), map((.fullName), syntax.allNonterminals)) ++ map(genTermLocalDecl(forward.env, specEnv, syntax.dominatingTerminals, _), map((.fullName), syntax.allTerminals)))} return $Expr{genForType(forward.env, specEnv, Silver_Expr { 0 }, t.typerep)}; diff --git a/grammars/silver/compiler/langserver/ReferenceLocations.sv b/grammars/silver/compiler/langserver/ReferenceLocations.sv index 2f7c2ccfb..637f852e4 100644 --- a/grammars/silver/compiler/langserver/ReferenceLocations.sv +++ b/grammars/silver/compiler/langserver/ReferenceLocations.sv @@ -13,7 +13,7 @@ attribute valueRefLocs, typeRefLocs, attributeRefLocs occurs on ProductionBody, ProductionStmts, ProductionStmt, DefLHS, ClassBody, ClassBodyItem, InstanceBody, InstanceBodyItem, Expr, Exprs, ExprInhs, ExprInh, ExprLHSExpr, AppExprs, AppExpr, AnnoAppExprs, AnnoExpr, - PrimPatterns, PrimPattern, ProdNameList; + PrimPatterns, PrimPattern, AttrNameList, ProdNameList; propagate valueRefLocs, typeRefLocs, attributeRefLocs on RootSpec, Grammar, Root, NameList, AGDcls, AGDcl, @@ -24,7 +24,7 @@ propagate valueRefLocs, typeRefLocs, attributeRefLocs on ProductionBody, ProductionStmts, ProductionStmt, DefLHS, ClassBody, ClassBodyItem, InstanceBody, InstanceBodyItem, Expr, Exprs, ExprInhs, ExprInh, ExprLHSExpr, AppExprs, AppExpr, AnnoAppExprs, AnnoExpr, - PrimPatterns, PrimPattern, ProdNameList; + PrimPatterns, PrimPattern, AttrNameList, ProdNameList; aspect valueRefLocs on NameList using <- of | nameListCons(q, _, _) -> if q.lookupValue.found then [(q.nameLoc, q.lookupValue.dcl)] else [] @@ -83,7 +83,7 @@ aspect attributeRefLocs on AGDcl using := of end; aspect production propagateOnNTListDcl -top::AGDcl ::= attrs::NameList nts::NameList ps::ProdNameList +top::AGDcl ::= attrs::AttrNameList nts::NameList ps::ProdNameList { propagate grammarName, env, flowEnv; } @@ -107,15 +107,15 @@ aspect valueRefLocs on top::ProductionStmt using <- of end; aspect valueRefLocs on ProductionStmt using := of -| propagateOneAttr(_) -> [] +| propagateOneAttr(_, _) -> [] end; aspect attributeRefLocs on ProductionStmt using := of -| propagateOneAttr(at) -> if at.lookupAttribute.found then [(at.nameLoc, at.lookupAttribute.dcl)] else [] +| propagateOneAttr(_, at) -> if at.lookupAttribute.found then [(at.nameLoc, at.lookupAttribute.dcl)] else [] end; aspect typeRefLocs on ProductionStmt using := of -| propagateOneAttr(_) -> [] +| propagateOneAttr(_, _) -> [] end; aspect valueRefLocs on DefLHS using <- of @@ -154,6 +154,11 @@ aspect valueRefLocs on PrimPattern using <- of | prodPatternGadt(q, _, _) -> if q.lookupValue.found then [(q.nameLoc, q.lookupValue.dcl)] else [] end; +aspect attributeRefLocs on AttrNameList using <- of +| attrNameListCons(_, q, _, _) -> if q.lookupAttribute.found then [(q.nameLoc, q.lookupAttribute.dcl)] else [] +| attrNameListOne(_, q) -> if q.lookupAttribute.found then [(q.nameLoc, q.lookupAttribute.dcl)] else [] +end; + aspect valueRefLocs on ProdNameList using <- of | prodNameListCons(q, _, _) -> if q.lookupValue.found then [(q.nameLoc, q.lookupValue.dcl)] else [] | prodNameListOne(q) -> if q.lookupValue.found then [(q.nameLoc, q.lookupValue.dcl)] else [] diff --git a/grammars/silver/compiler/translation/java/core/ProductionBody.sv b/grammars/silver/compiler/translation/java/core/ProductionBody.sv index d0d8d6d78..b43fd6de0 100644 --- a/grammars/silver/compiler/translation/java/core/ProductionBody.sv +++ b/grammars/silver/compiler/translation/java/core/ProductionBody.sv @@ -45,6 +45,12 @@ top::ProductionStmt ::= e::[Message] top.translation = ""; } +aspect production emptyProductionStmt +top::ProductionStmt ::= +{ + top.translation = ""; +} + -------------------------------------------------------------------------------- aspect default production From 8ff8b8b04140fcc7ef1d373b3e36a403d33fe2c4 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 3 Apr 2024 14:29:48 -0500 Subject: [PATCH 217/283] Fix flow errors caused by change to propagate behavior on shared children --- grammars/silver/compiler/extension/implicit_monads/Expr.sv | 4 ++-- grammars/silver/compiler/extension/rewriting/Expr.sv | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index 19ba50063..39108f3ae 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -483,13 +483,13 @@ top::Expr ::= e::Expr '.' 'forward' aspect production access top::Expr ::= e::Expr '.' q::QNameAttrOccur { - propagate mDownSubst, mUpSubst; + propagate mDownSubst, mUpSubst, expectedMonad; } aspect production accessBouncer top::Expr ::= e::Expr @q::QNameAttrOccur target::Access { - propagate mDownSubst, mUpSubst; + propagate mDownSubst, mUpSubst, expectedMonad; } aspect production errorAccessHandler diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index c7eebc1f5..69585e7c5 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -3,7 +3,7 @@ grammar silver:compiler:extension:rewriting; -- Environment mapping variables that were defined on the rule LHS to Booleans indicating whether -- the variable was explicitly (i.e. not implicitly) decorated in the pattern. inherited attribute boundVars::[Pair] occurs on Expr, Exprs, ExprInhs, ExprInh, AppExprs, AppExpr, AnnoAppExprs, AnnoExpr, AssignExpr, PrimPatterns, PrimPattern; -propagate boundVars on Expr, Exprs, ExprInhs, ExprInh, AppExprs, AppExpr, AnnoAppExprs, AnnoExpr, AssignExpr, PrimPatterns, PrimPattern +propagate @boundVars on Expr, Exprs, ExprInhs, ExprInh, AppExprs, AppExpr, AnnoAppExprs, AnnoExpr, AssignExpr, PrimPatterns, PrimPattern excluding letp, prodPatternNormal, prodPatternGadt; attribute transform occurs on Expr; From 00dc686b8c6b1855eab7ab2afcdaabbf83e9f848 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 3 Apr 2024 14:55:37 -0500 Subject: [PATCH 218/283] Remove production that wasn't actually needed --- grammars/silver/compiler/definition/flow/ast/Flow.sv | 7 ------- grammars/silver/compiler/extension/autoattr/BiEquality.sv | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/grammars/silver/compiler/definition/flow/ast/Flow.sv b/grammars/silver/compiler/definition/flow/ast/Flow.sv index a76dda86e..f7ff1246e 100644 --- a/grammars/silver/compiler/definition/flow/ast/Flow.sv +++ b/grammars/silver/compiler/definition/flow/ast/Flow.sv @@ -449,13 +449,6 @@ top::FlowDef ::= prod::String sigName::String sourceProd::String source::VertexT top.sigShareContribs := [(crossnames(prod, sigName), sourceProd, source)]; } -abstract production emptyFlowDef -top::FlowDef ::= -{ - top.prodGraphContribs := []; - top.flowEdges = []; -} - -- fun crossnames String ::= a::String b::String = a ++ " @ " ++ b; diff --git a/grammars/silver/compiler/extension/autoattr/BiEquality.sv b/grammars/silver/compiler/extension/autoattr/BiEquality.sv index 138fd01be..4dd90ebb5 100644 --- a/grammars/silver/compiler/extension/autoattr/BiEquality.sv +++ b/grammars/silver/compiler/extension/autoattr/BiEquality.sv @@ -95,7 +95,7 @@ top::ProductionStmt ::= includeShared::Boolean @synPartial::QName inh::String sy } abstract production propagateBiequalitySyn implements Propagate -top::ProductionStmt ::= propagateShared::Boolean @syn::QName inh::String synPartial::String +top::ProductionStmt ::= includeShared::Boolean @syn::QName inh::String synPartial::String { top.unparse = s"propagate ${syn.unparse};"; From 75a387f857050ceeb2ead2eaca66e7abfef19d95 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 3 Apr 2024 15:38:14 -0500 Subject: [PATCH 219/283] Fix crash in flow analysis --- .../compiler/definition/flow/driver/FlowGraph.sv | 13 +++++-------- .../silver/compiler/definition/flow/env/Expr.sv | 9 ++++++++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/grammars/silver/compiler/definition/flow/driver/FlowGraph.sv b/grammars/silver/compiler/definition/flow/driver/FlowGraph.sv index 39c960e55..c6ea46b21 100644 --- a/grammars/silver/compiler/definition/flow/driver/FlowGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/FlowGraph.sv @@ -9,14 +9,11 @@ FlowType ::= prod::String e::EnvTree return if null(lookup) then g:empty() else head(lookup); } -function findProductionGraph -ProductionGraph ::= n::String l::EnvTree -{ - local lookup :: [ProductionGraph] = searchEnvTree(n, l); - - -- TODO: so apparently this should never fail? - return head(lookup); -} +fun findProductionGraph ProductionGraph ::= n::String l::EnvTree = + case searchEnvTree(n, l) of + | g :: _ -> g + | _ -> error("Failed to find graph for " ++ n) + end; -- These two functions are used by Inh.sv: function expandGraph diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index 68b65c7ea..97c40ddc9 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -267,9 +267,16 @@ top::AppExpr ::= e::Expr sigIndex < length(ns.inputNames) && head(drop(sigIndex, ns.inputElements)).elementShared | _ -> false end; + production isForwardParam::Boolean = + -- Don't try to share if someone uses an implementation prod somewhere invalid. + case top.decSiteVertexInfo of + | just(forwardVertexType_real()) -> true + | just(localVertexType(fName)) when isForwardProdAttr(fName, top.env) -> true + | _ -> false + end; top.flowDefs <- case top.appProd, e.flowVertexInfo of - | just(ns), just(v) when sigIsShared && !inputSigIsShared -> + | just(ns), just(v) when sigIsShared && !inputSigIsShared && isForwardParam -> [sigShareSite(ns.fullName, sigName, top.frame.fullName, v)] | _, _ -> [] end; From cc3bbd1537ba7c2018450e0bbd8f0a2d1d9a0bb4 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 4 Apr 2024 13:22:08 -0500 Subject: [PATCH 220/283] Fix bug with constructing equation locations --- grammars/silver/compiler/translation/java/core/Expr.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/compiler/translation/java/core/Expr.sv b/grammars/silver/compiler/translation/java/core/Expr.sv index 3f3fe5208..6f728e6ab 100644 --- a/grammars/silver/compiler/translation/java/core/Expr.sv +++ b/grammars/silver/compiler/translation/java/core/Expr.sv @@ -677,6 +677,6 @@ String ::= e::Decorated Expr | r :: _ -> r.grammarSource | [] -> "" end ++ loc.filename; - local sourceLocationTrans::String = s"new silver.core.Ploc(\"${fileName}\", ${toString(loc.line)}, ${toString(loc.column)}, ${toString(loc.endLine)}, ${toString(loc.endColumn)}, ${toString(loc.index)}, ${toString(loc.endIndex)})"; + local sourceLocationTrans::String = s"new silver.core.Ploc(new common.StringCatter(\"${fileName}\"), ${toString(loc.line)}, ${toString(loc.column)}, ${toString(loc.endLine)}, ${toString(loc.endColumn)}, ${toString(loc.index)}, ${toString(loc.endIndex)})"; return s"new common.Lazy() { public final Object eval(final common.DecoratedNode context) { ${swizzleOrigins} return ${e.translation}; } public final silver.core.NLocation getSourceLocation() { return ${sourceLocationTrans}; } }"; } From 087d5422b6993ae672ec38c4b01e5ecaa1881c8b Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 11 Apr 2024 11:37:09 -0500 Subject: [PATCH 221/283] Overhaul inh completeness checks in flow analysis, allow flow projections through dispatch application. Dispatch translation currently broken. --- .../compiler/analysis/warnings/flow/Inh.sv | 223 +++--------------- .../compiler/definition/core/DispatchDcl.sv | 2 + .../definition/core/ProductionBody.sv | 2 +- .../compiler/definition/flow/ast/Flow.sv | 13 +- .../definition/flow/driver/ProductionGraph.sv | 25 +- .../compiler/definition/flow/env/DecSites.sv | 147 ++++++++++++ .../compiler/definition/flow/env/Expr.sv | 12 +- .../compiler/definition/flow/env/FlowEnv.sv | 52 +--- .../silver/compiler/driver/util/FlowTypes.sv | 5 +- .../primitivepattern/VarBinders.sv | 2 +- .../translation/java/core/DispatchDcl.sv | 20 ++ .../translation/java/core/NamedSignature.sv | 4 +- runtime/java/src/common/DecoratedNode.java | 2 +- 13 files changed, 253 insertions(+), 256 deletions(-) create mode 100644 grammars/silver/compiler/definition/flow/env/DecSites.sv create mode 100644 grammars/silver/compiler/translation/java/core/DispatchDcl.sv diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index 29604ce5b..c6b4df8f8 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -46,34 +46,6 @@ Either ::= args::[String] -------------------------------------------------------------------------------- -{-- - - Given a name of a child, return whether it has a decorated nonterminal - - type (covered by the more specific checks on accesses from references) - - decorated with the attr. - - True if nonsensicle. - -} -function sigAttrViaReference -Boolean ::= sigName::String attrName::String ns::NamedSignature e::Env -{ - local ty :: Type = lookupSignatureInputElem(sigName, ns).typerep; - return ty.isDecorated && contains(attrName, getMinRefSet(ty, e)); -} - -{-- - - Given a name of a local, return whether it has a decorated nonterminal - - type (covered by the more specific checks on accesses from references) - - decorated with the attr. - - True if nonsensicle. - -} -function localAttrViaReference -Boolean ::= fName::String attrName::String e::Env -{ - local d :: [ValueDclInfo] = getValueDcl(fName, e); - local ty :: Type = head(d).typeScheme.typerep; - - return null(d) || ty.isDecorated && contains(attrName, getMinRefSet(ty, e)); -} - {-- - Used as a stop-gap measure to ensure equations exist. - Given a needed equation (represented by FlowVertex 'v'), @@ -116,40 +88,15 @@ function checkEqDeps -- All productions must have all SYN equations, so those errors are raised elsewhere. | lhsSynVertex(attrName) -> [] -- A dependency on an RHS.ATTR. SYN are always present, so we only care about INH here. - -- Filter missing equations for RHS that are references or supplied through another decoration site. | rhsInhVertex(sigName, attrName) -> - if !null(lookupInh(prodName, sigName, attrName, flowEnv)) - || sigAttrViaReference(sigName, attrName, ns, realEnv) - || lookupSignatureInputElem(sigName, ns).elementShared && - all(unzipWith(remoteProdHasInhEq(_, _, attrName, flowEnv, realEnv), - lookupAllSigShareSites(prodName, sigName, flowEnv, realEnv))) - || !null(lookupRefDecSite(prodName, rhsVertexType(sigName), flowEnv)) - || case splitTransAttrInh(attrName) of - | just((transAttr, _)) -> - !null(lookupRefDecSite(prodName, transAttrVertexType(rhsVertexType(sigName), transAttr), flowEnv)) - | nothing() -> false - end - then [] - else [mwdaWrnAmbientOrigin(config, "Equation has transitive dependency on child " ++ sigName ++ "'s inherited attribute for " ++ attrName ++ " but this equation appears to be missing.")] + checkInhEq(prodName, rhsVertexType(sigName), attrName, config, flowEnv, realEnv) | rhsSynVertex(sigName, attrName) -> [] -- A dependency on a LOCAL. Technically, local equations may not exist! -- But let's just assume they do, since `local name :: type = expr;` is the prefered syntax. | localEqVertex(fName) -> [] -- A dependency on a LOCAL.ATTR. SYN always exist again, so we only care about INH here. - -- Ignore the FORWARD (a special case of LOCAL), which always has both SYN/INH. - -- And again ignore references and additional decoration sites. | localInhVertex(fName, attrName) -> - if !null(lookupLocalInh(prodName, fName, attrName, flowEnv)) - || fName == "forward" - || localAttrViaReference(fName, attrName, realEnv) - || !null(lookupRefDecSite(prodName, localVertexType(fName), flowEnv)) - || case splitTransAttrInh(attrName) of - | just((transAttr, _)) -> - !null(lookupRefDecSite(prodName, transAttrVertexType(localVertexType(fName), transAttr), flowEnv)) - | nothing() -> isForwardProdAttr(fName, realEnv) -- Inh on trans are not copied with forwarding - end - then [] - else [mwdaWrnAmbientOrigin(config, "Equation has transitive dependency on local " ++ fName ++ "'s inherited attribute for " ++ attrName ++ " but this equation appears to be missing.")] + checkInhEq(prodName, localVertexType(fName), attrName, config, flowEnv, realEnv) | localSynVertex(fName, attrName) -> [] -- A dependency on a ANON. This do always exist (`decorate expr with..` always has expr.) | anonEqVertex(fName) -> [] @@ -168,12 +115,10 @@ function checkEqDeps else [] -- If it's not in the list, then it's a transitive dep from a DIFFERENT equation (and thus reported there) end | anonSynVertex(fName, attrName) -> [] - -- A dependency on a projected equation in another production. - -- Again, SYN are safe. We need to check only for INH. - | subtermInhVertex(parent, termProdName, sigName, attrName) -> - if remoteProdHasInhEq(termProdName, rhsVertexType(sigName), attrName, flowEnv, realEnv) - then [] - else [mwdaWrnAmbientOrigin(config, s"Equation has transitive dependencies on a missing remote equation.\n\tRemote production: ${termProdName}\n\tChild: ${sigName}\n\tMissing inherited equations for: ${attrName}")] + -- It's only possible to depend on a subterm inh vertex through sharing, + -- and we always check for missing inh on the remote prod if it's needed there. + -- No need to also report the error here. + | subtermInhVertex(parent, termProdName, sigName, attrName) -> [] | subtermSynVertex(parent, termProdName, sigName, attrName) -> [] end; } @@ -181,6 +126,16 @@ fun checkAllEqDeps [Message] ::= v::[FlowVertex] config::Decorated CmdArgs prodName::String flowEnv::FlowEnv realEnv::Env anonResolve::[Pair] = flatMap(checkEqDeps(_, config, prodName, flowEnv, realEnv, anonResolve), v); +function checkInhEq +[Message] ::= prodName::String vt::VertexType attrName::String config::Decorated CmdArgs flowEnv::FlowEnv realEnv::Env +{ + local decSites::[DecSite] = findDecSites(prodName, vt, [], flowEnv, realEnv); + return + if decSitesMissingInhEq(attrName, decSites, flowEnv) + then [mwdaWrnAmbientOrigin(config, s"Equation requires inherited attribute ${attrName} be supplied to ${prettyDecSites(decSites)}")] + else []; +} + {-- - Look up flow types, either from the flow environment (for a nonterminal) or the occurs-on contexts (for a type var). - @param syn A synthesized attribute's full name @@ -663,62 +618,16 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur top.errors <- if null(e.errors) && top.config.warnMissingInh then - case e of - | childReference(lq) -> - if isDecorable(lq.lookupValue.typeScheme.typerep, top.env) && - null(lookupRefDecSite(top.frame.fullName, rhsVertexType(lq.lookupValue.fullName), top.flowEnv)) -- Decoration site projection, covered by checkAllEqDeps - || lq.lookupValue.dcl.isShared - then - let inhs :: [String] = - filter(\ attr::String -> - case splitTransAttrInh(attr) of - -- If the dep is for an inh on a trans attribute, check for a decoration site projection for the trans attribute - | just((transAttr, _)) -> - null(lookupRefDecSite(top.frame.fullName, transAttrVertexType(rhsVertexType(lq.lookupValue.fullName), transAttr), top.flowEnv)) - | _ -> true - end, - filter( - isEquationMissing( - lookupInh(top.frame.fullName, lq.lookupValue.fullName, _, top.flowEnv), - _), - set:toList(inhDeps))) - in if null(inhs) then [] - else if lq.lookupValue.dcl.isShared - then - flatMap(\ inh::String -> - case sharingSitesLackingSigAttr(top.frame.fullName, lq.lookupValue.fullName, inh, top.flowEnv, top.env) of - | [] -> [] - | sites -> [mwdaWrnFromOrigin(top, - s"Access of syn attribute ${q.name} on ${e.unparse} requires missing inherited attribute ${inh} to be supplied in the following places:\n" ++ - implode("\n", map(\ s::(String, VertexType) -> s" ${s.2.vertexPP} in production ${s.1}", sites)))] - end, inhs) - else [mwdaWrnFromOrigin(top, "Access of syn attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] - end - else [] - | localReference(lq) -> - if isDecorable(lq.lookupValue.typeScheme.typerep, top.env) && - null(lookupRefDecSite(top.frame.fullName, localVertexType(lq.lookupValue.fullName), top.flowEnv)) -- Decoration site projection, covered by checkAllEqDeps - then - let inhs :: [String] = - filter(\ attr::String -> - case splitTransAttrInh(attr) of - -- If the dep is for an inh on a trans attribute, check for a decoration site projection for the trans attribute - | just((transAttr, _)) -> - null(lookupRefDecSite(top.frame.fullName, transAttrVertexType(localVertexType(lq.lookupValue.fullName), transAttr), top.flowEnv)) - -- If the dep is for a normal inh attribute, ignore if the local is a forward production attribute - | nothing() -> !lq.lookupValue.dcl.hasForward - end, - filter( - isEquationMissing( - lookupLocalInh(top.frame.fullName, lq.lookupValue.fullName, _, top.flowEnv), - _), - set:toList(inhDeps))) - in if null(inhs) then [] - else [mwdaWrnFromOrigin(top, "Access of syn attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] + case e.flowVertexInfo of + | just(vt) -> + let decSites::[DecSite] = findDecSites(top.frame.fullName, vt, [], top.flowEnv, top.env) in + case filter(decSitesMissingInhEq(_, decSites, top.flowEnv), set:toList(inhDeps)) of + | [] -> [] + | inhs -> [mwdaWrnFromOrigin(top, "Access of syn attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied to " ++ prettyDecSites(decSites))] end - else [] - | _ -> [] - end + end + | nothing() -> [] + end else []; } @@ -812,76 +721,19 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur top.errors <- if null(e.errors) && top.config.warnMissingInh then - case e of - | childReference(lq) -> - if isDecorable(lq.lookupValue.typeScheme.typerep, top.env) && - null(lookupRefDecSite(top.frame.fullName, rhsVertexType(lq.lookupValue.fullName), top.flowEnv)) -- Decoration site projection, covered by checkAllEqDeps - || lq.lookupValue.dcl.isShared - then - let inhs :: [String] = - filter(\ attr::String -> - case splitTransAttrInh(attr) of - -- If the dep is for an inh on a trans attribute, check for a decoration site projection for the trans attribute - | just((transAttr, _)) -> - null(lookupRefDecSite(top.frame.fullName, transAttrVertexType(rhsVertexType(lq.lookupValue.fullName), transAttr), top.flowEnv)) - | _ -> true - end, - filter( - isEquationMissing( - lookupInh(top.frame.fullName, lq.lookupValue.fullName, _, top.flowEnv), - _), - set:toList(inhDeps))) - in if null(inhs) then [] - else if lq.lookupValue.dcl.isShared - then - flatMap(\ inh::String -> - case sharingSitesLackingSigAttr(top.frame.fullName, lq.lookupValue.fullName, inh, top.flowEnv, top.env) of - | [] -> [] - | sites -> [mwdaWrnFromOrigin(top, - s"Access of trans attribute ${q.name} on ${e.unparse} requires missing inherited attribute ${inh} to be supplied in the following places:\n" ++ - implode("\n", map(\ s::(String, VertexType) -> s" ${s.2.vertexPP} in production ${s.1}", sites)))] - end, inhs) - else [mwdaWrnFromOrigin(top, "Access of trans attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] - end - else [] - | localReference(lq) -> - if isDecorable(lq.lookupValue.typeScheme.typerep, top.env) && - null(lookupRefDecSite(top.frame.fullName, localVertexType(lq.lookupValue.fullName), top.flowEnv)) -- Decoration site projection, covered by checkAllEqDeps - then - let inhs :: [String] = - filter(\ attr::String -> - case splitTransAttrInh(attr) of - -- If the dep is for an inh on a trans attribute, check for a decoration site projection for the trans attribute - | just((transAttr, _)) -> - null(lookupRefDecSite(top.frame.fullName, transAttrVertexType(localVertexType(lq.lookupValue.fullName), transAttr), top.flowEnv)) - -- If the dep is for a normal inh attribute, ignore if the local is a forward production attribute - | nothing() -> !lq.lookupValue.dcl.hasForward - end, - filter( - isEquationMissing( - lookupLocalInh(top.frame.fullName, lq.lookupValue.fullName, _, top.flowEnv), - _), - set:toList(inhDeps))) - in if null(inhs) then [] - else [mwdaWrnFromOrigin(top, "Access of trans attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied")] + case e.flowVertexInfo of + | just(vt) -> + let decSites::[DecSite] = findDecSites(top.frame.fullName, vt, [], top.flowEnv, top.env) in + case filter(decSitesMissingInhEq(_, decSites, top.flowEnv), set:toList(inhDeps)) of + | [] -> [] + | inhs -> [mwdaWrnFromOrigin(top, "Access of trans attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied to " ++ prettyDecSites(decSites))] end - else [] - | _ -> [] - end + end + | nothing() -> [] + end else []; } -{-- - - Given the name of a child shared in the production's signature, - - return the list of all productions/places this child can be decorated before forwarding to this production, - - where the needed inherited attribute is not supplied. - -} -fun sharingSitesLackingSigAttr -[(String, VertexType)] ::= prodName::String sigName::String attrName::String flowEnv::FlowEnv realEnv::Env = - filter( - \ s::(String, VertexType) -> !vertexHasInhEq(s.1, s.2, attrName, flowEnv), - lookupAllSigShareSites(prodName, sigName, flowEnv, realEnv)); - aspect production decorateExprWith top::Expr ::= 'decorate' e::Expr 'with' '{' inh::ExprInhs '}' @@ -951,12 +803,15 @@ top::VarBinder ::= n::Name -- fName is our invented vertex name for the pattern variable local requiredInhs :: [String] = toAnonInhs(top.receivedDeps, fName); + local remoteDecSites :: [DecSite] = + findDecSites(top.matchingAgainst.fromJust.fullName, rhsVertexType(top.bindingName), [], top.flowEnv, top.env); + -- Check for equation's existence: -- Prod: top.matchingAgainst.fromJust.fullName -- Child: top.bindingName -- Inh: each of requiredInhs local missingInhs :: [String] = - filter(remoteProdMissingInhEq(top.matchingAgainst.fromJust.fullName, rhsVertexType(top.bindingName), _, top.flowEnv, top.env), + filter(decSitesMissingInhEq(_, remoteDecSites, top.flowEnv), removeAll(getMinRefSet(top.bindingType, top.env), requiredInhs)); top.errors <- @@ -964,7 +819,7 @@ top::VarBinder ::= n::Name && isDecorable(top.bindingType, top.env) && top.matchingAgainst.isJust && !null(missingInhs) - then [mwdaWrnFromOrigin(top, s"Pattern variable '${n.name}' has transitive dependencies with missing remote equations.\n\tRemote production: ${top.matchingAgainst.fromJust.fullName}\n\tChild: ${top.bindingName}\n\tMissing inherited equations for: ${implode(", ", missingInhs)}")] + then [mwdaWrnFromOrigin(top, s"Pattern variable '${n.name}' has transitive dependencies with missing remote equations for ${implode(", ", missingInhs)}. These attributes must be supplied to ${prettyDecSites(remoteDecSites)}\n")] else []; } diff --git a/grammars/silver/compiler/definition/core/DispatchDcl.sv b/grammars/silver/compiler/definition/core/DispatchDcl.sv index d6b04d4b9..293089f11 100644 --- a/grammars/silver/compiler/definition/core/DispatchDcl.sv +++ b/grammars/silver/compiler/definition/core/DispatchDcl.sv @@ -12,6 +12,8 @@ top::AGDcl ::= 'dispatch' id::Name '=' sig::ProductionSignature ';' sig.implementedSig = nothing(); sig.env = newScopeEnv(sig.defs, top.env); + production namedSig :: NamedSignature = sig.namedSignature; + top.errors <- if length(getTypeDclAll(fName, top.env)) > 1 then [errFromOrigin(id, "Type '" ++ fName ++ "' is already bound.")] diff --git a/grammars/silver/compiler/definition/core/ProductionBody.sv b/grammars/silver/compiler/definition/core/ProductionBody.sv index f4f168fc8..146b893eb 100644 --- a/grammars/silver/compiler/definition/core/ProductionBody.sv +++ b/grammars/silver/compiler/definition/core/ProductionBody.sv @@ -379,7 +379,7 @@ top::DefLHS ::= q::QName forwards to if null(q.lookupValue.dcls) then errorDefLHS(q) - else q.lookupValue.dcl.defLHSDispatcher(q); + else q.lookupValue.dcl.defLHSDispatcher(q); } action { if (contains(q.name, sigNames)) { insert semantic token IdSigName_t at q.nameLoc; diff --git a/grammars/silver/compiler/definition/flow/ast/Flow.sv b/grammars/silver/compiler/definition/flow/ast/Flow.sv index f7ff1246e..aec5bb0f5 100644 --- a/grammars/silver/compiler/definition/flow/ast/Flow.sv +++ b/grammars/silver/compiler/definition/flow/ast/Flow.sv @@ -413,7 +413,7 @@ data PatternVarProjection - - @param prod the full name of the production - @param parent the flow vertex of the enclosing production call - - @param termProd the applied production + - @param termProd the applied production (or dispatch signature) - @param sigName the name of the child under which this term appears -} abstract production subtermDecEq @@ -441,8 +441,17 @@ top::FlowDef ::= prod::String nt::String ref::VertexType decSite::VertexType top.refDecSiteContribs := if alwaysDec then top.refPossibleDecSiteContribs else []; } +{-- + - A tree that is shared in the application of a production/dispatch signature + - + - @param prod the full name of the production/dispatch signature + - @param sigName the name of the shared child in prod + - @param sourceProd the full name of the (dispatching) production that forwarded to prod + - @param source the vertex type of the shared tree supplied by sourceProd as the shared child + - @param parent the vertex type of where prod is decorated in sourceProd - should always be forward or a forward prod attr. + -} abstract production sigShareSite -top::FlowDef ::= prod::String sigName::String sourceProd::String source::VertexType +top::FlowDef ::= prod::String sigName::String sourceProd::String source::VertexType parent::VertexType { top.prodGraphContribs := [(prod, top)]; top.flowEdges = []; diff --git a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv index 4a2dae275..83a68d864 100644 --- a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv @@ -96,10 +96,10 @@ ProductionGraph ::= -- construct a production graph for each production fun computeAllProductionGraphs -[ProductionGraph] ::= prods::[ValueDclInfo] prodTree::EnvTree flowEnv::FlowEnv realEnv::Env = +[ProductionGraph] ::= prods::[ValueDclInfo] flowEnv::FlowEnv realEnv::Env = if null(prods) then [] - else constructProductionGraph(head(prods), searchEnvTree(head(prods).fullName, prodTree), flowEnv, realEnv) :: - computeAllProductionGraphs(tail(prods), prodTree, flowEnv, realEnv); + else constructProductionGraph(head(prods), flowEnv, realEnv) :: + computeAllProductionGraphs(tail(prods), flowEnv, realEnv); -------------------------------------------------------------------------------- @@ -140,10 +140,17 @@ fun computeAllProductionGraphs - @return A fixed up graph. -} function constructProductionGraph -ProductionGraph ::= dcl::ValueDclInfo defs::[FlowDef] flowEnv::FlowEnv realEnv::Env +ProductionGraph ::= dcl::ValueDclInfo flowEnv::FlowEnv realEnv::Env { -- The name of this production local prod :: String = dcl.fullName; + -- The flow defs for this production + local defs :: [FlowDef] = + getGraphContribsFor(prod, flowEnv) ++ + case dcl.implementedSignature of + | just(sig) -> getGraphContribsFor(sig.fullName, flowEnv) + | nothing() -> [] + end; -- The LHS nonterminal full name local nt :: NtName = dcl.namedSignature.outputElement.typerep.typeName; -- Just synthesized attributes. @@ -487,7 +494,9 @@ fun subtermDecSiteStitchPoints [StitchPoint] ::= flowEnv::FlowEnv realEnv::Env map(\ prodDcl::ValueDclInfo -> projectionStitchPoint( termProdName, subtermVertexType(parent, termProdName, sigName), parent, rhsVertexType(sigName), - getInhAndInhOnTransAttrsOn(prodDcl.namedSignature.outputElement.typerep.typeName, realEnv)), + getInhAndInhOnTransAttrsOn( + lookupSignatureInputElem(sigName, prodDcl.namedSignature).typerep.typeName, + realEnv)), getValueDcl(termProdName, realEnv)) | _ -> [] end, @@ -495,11 +504,13 @@ fun subtermDecSiteStitchPoints [StitchPoint] ::= flowEnv::FlowEnv realEnv::Env fun sigSharingStitchPoints [StitchPoint] ::= flowEnv::FlowEnv realEnv::Env defs::[FlowDef] = flatMap(\ d::FlowDef -> case d of - | sigShareSite(_, sigName, sourceProd, vt) -> + | sigShareSite(_, sigName, sourceProd, vt, parent) -> map(\ prodDcl::ValueDclInfo -> projectionStitchPoint( sourceProd, rhsVertexType(sigName), lhsVertexType, vt, - getInhAndInhOnTransAttrsOn(prodDcl.namedSignature.outputElement.typerep.typeName, realEnv)), + getInhAndInhOnTransAttrsOn( + lookupSignatureInputElem(sigName, prodDcl.namedSignature).typerep.typeName, + realEnv)), getValueDcl(sourceProd, realEnv)) | _ -> [] end, diff --git a/grammars/silver/compiler/definition/flow/env/DecSites.sv b/grammars/silver/compiler/definition/flow/env/DecSites.sv new file mode 100644 index 000000000..731802c5d --- /dev/null +++ b/grammars/silver/compiler/definition/flow/env/DecSites.sv @@ -0,0 +1,147 @@ +grammar silver:compiler:definition:flow:env; + +import silver:util:treeset as set; + +-- places where this child was decorated in a production forwarding to this one, +-- or in a dispatch signature that this production implements +fun lookupAllSigShareSites [(String, VertexType)] ::= prod::String sigName::String e::FlowEnv realEnv::Env = + lookupSigShareSites(prod, sigName, e) ++ + case getValueDcl(prod, realEnv) of + | dcl :: _ when dcl.implementedSignature matches just(sig) -> + lookupSigShareSites( + sig.fullName, + head(drop(positionOf(sigName, dcl.namedSignature.inputNames), sig.inputNames)), + e) + | _ -> [] + end; + +{-- + - Represents a tree of decoration sites where an equation might need to be supplied + - to ensure an inherited attribute is always present on some tree. + -} +data nonterminal DecSite with decSitePP; + +synthesized attribute decSitePP::String; + +{-- + - An attribute is present if it is supplied by any of these sites. + -} +production anyDecSite +top::DecSite ::= ds::[DecSite] +{ + top.decSitePP = implode(" | ", map((.decSitePP), ds)); +} + +{-- + - An attribute is present if it is supplied by all of these sites. + -} +production allDecSite +top::DecSite ::= ds::[DecSite] +{ + top.decSitePP = s"{${implode(", ", map((.decSitePP), ds))}}"; +} + +production directDecSite +top::DecSite ::= prodName::String vt::VertexType +{ + -- TODO: What if vt is an anonVertexType? + top.decSitePP = s"${vt.vertexPP} of production ${prodName}"; +} + +production forwardDecSite +top::DecSite ::= +{ + top.decSitePP = "via forwarding"; +} + +production transAttrDecSite +top::DecSite ::= attrName::String d::DecSite +{ + top.decSitePP = s"via translation attribute ${attrName}: ${d.decSitePP}"; +} + +fun foldAnyDecSite DecSite ::= ds::[DecSite] = + case ds of + | [d] -> d + | _ -> anyDecSite(flatMap(\ d -> case d of anyDecSite(ds1) -> ds1 | _ -> [d] end, ds)) + end; + +fun foldAllDecSite DecSite ::= ds::[DecSite] = + case ds of + | [d] -> d + | _ -> allDecSite(flatMap(\ d -> case d of allDecSite(ds1) -> ds1 | _ -> [d] end, ds)) + end; + +fun prettyDecSites String ::= ds::[DecSite] = + case ds of + | [d] -> d.decSitePP + | _ -> "any of\n\t" ++ implode("\n\t", map((.decSitePP), ds)) + end; + +function findDecSites +[DecSite] ::= prodName::String vt::VertexType seen::[(String, VertexType)] flowEnv::FlowEnv realEnv::Env +{ + local prodDcl :: [ValueDclInfo] = getValueDcl(prodName, realEnv); + local ns :: NamedSignature = + case prodDcl of + | d :: _ -> d.namedSignature + | [] -> bogusNamedSignature() + end; + local ntName::String = + case vt of + | forwardVertexType_real() -> ns.outputElement.typerep.typeName + | localVertexType(fName) when getValueDcl(fName, realEnv) matches dcl :: _ -> dcl.typeScheme.typeName + | rhsVertexType(sigName) -> lookupSignatureInputElem(sigName, ns).typerep.typeName + | _ -> "" + end; + + local recurse::([DecSite] ::= String VertexType) = + findDecSites(_, _, (prodName, vt) :: seen, flowEnv, realEnv); + + return + if contains((prodName, vt), seen) + then [] + else + directDecSite(prodName, vt) :: + case vt of + | forwardVertexType_real() -> [forwardDecSite()] + | localVertexType("forward") -> [forwardDecSite()] -- TODO: Not sure if this is actually possible? + | localVertexType(fName) when isForwardProdAttr(fName, realEnv) -> [forwardDecSite()] + | _ -> [] + end ++ + flatMap(recurse(prodName, _), lookupRefDecSite(prodName, vt, flowEnv)) ++ + case vt of + | rhsVertexType(sigName) when lookupSignatureInputElem(sigName, ns).elementShared -> + [foldAllDecSite(map(foldAnyDecSite, unzipWith(recurse, lookupAllSigShareSites(prodName, sigName, flowEnv, realEnv))))] + | _ -> [] + end ++ + filterMap( + \ attrName -> + case getAttrDcl(attrName, realEnv) of + | dcl :: _ when dcl.isTranslation -> + just(transAttrDecSite(attrName, foldAnyDecSite(recurse(prodName, transAttrVertexType(vt, attrName))))) + | _ -> nothing() + end, + getHostSynsFor(ntName, flowEnv)); +} + +function decSiteHasInhEq +Boolean ::= d::DecSite attrName::String flowEnv::FlowEnv +{ + local transInh::Maybe<(String, String)> = splitTransAttrInh(attrName); + return + case d of + | anyDecSite(ds) -> any(map(decSiteHasInhEq(_, attrName, flowEnv), ds)) + | allDecSite(ds) -> all(map(decSiteHasInhEq(_, attrName, flowEnv), ds)) + | directDecSite(prodName, vt) -> vertexHasInhEq(prodName, vt, attrName, flowEnv) + | forwardDecSite() -> !transInh.isJust + | transAttrDecSite(attrName, d) when transInh matches just((transAttr, inhAttr)) -> + decSiteHasInhEq(d, inhAttr, flowEnv) + | _ -> false + end; +} + +-- Helper for filtering +fun decSitesMissingInhEq +Boolean ::= attrName::String decSites::[DecSite] flowEnv::FlowEnv = + !any(map(decSiteHasInhEq(_, attrName, flowEnv), decSites)); diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index 97c40ddc9..e95a03d24 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -275,10 +275,14 @@ top::AppExpr ::= e::Expr | _ -> false end; top.flowDefs <- - case top.appProd, e.flowVertexInfo of - | just(ns), just(v) when sigIsShared && !inputSigIsShared && isForwardParam -> - [sigShareSite(ns.fullName, sigName, top.frame.fullName, v)] - | _, _ -> [] + case top.decSiteVertexInfo, top.appProd, e.flowVertexInfo of + | just(parent), just(ns), just(v) when sigIsShared && isForwardParam -> + refDecSiteEq( + top.frame.fullName, e.typerep.typeName, v, + subtermVertexType(parent, ns.fullName, sigName), true) :: + if inputSigIsShared then [] + else [sigShareSite(ns.fullName, sigName, top.frame.fullName, v, parent)] + | _, _, _ -> [] end; } diff --git a/grammars/silver/compiler/definition/flow/env/FlowEnv.sv b/grammars/silver/compiler/definition/flow/env/FlowEnv.sv index 6e6196f2e..51ac799fe 100644 --- a/grammars/silver/compiler/definition/flow/env/FlowEnv.sv +++ b/grammars/silver/compiler/definition/flow/env/FlowEnv.sv @@ -3,6 +3,7 @@ grammar silver:compiler:definition:flow:env; imports silver:compiler:definition:flow:ast; imports silver:compiler:definition:env; imports silver:compiler:definition:core; +imports silver:compiler:definition:type only typerep; imports silver:compiler:analysis:uniqueness; import silver:compiler:definition:type; @@ -107,46 +108,7 @@ fun lookupRefDecSite [VertexType] ::= prod::String v::VertexType e::FlowEnv = fun lookupSigShareSites [(String, VertexType)] ::= prod::String sigName::String e::FlowEnv = searchEnvTree(crossnames(prod, sigName), e.sigShareTree); --- places where this child was decorated in a production forwarding to this one, --- or in a dispatch signature that this production implements -fun lookupAllSigShareSites [(String, VertexType)] ::= prod::String sigName::String e::FlowEnv realEnv::Env = - lookupSigShareSites(prod, sigName, e) ++ - case getValueDcl(prod, realEnv) of - | dcl :: _ when dcl.implementedSignature matches just(sig) -> - lookupSigShareSites( - sig.fullName, - head(drop(positionOf(sigName, dcl.namedSignature.inputNames), sig.inputNames)), - e) - | _ -> [] - end; - --- Just a helper for filtering. -fun remoteProdMissingInhEq -Boolean ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv realEnv::Env = - !remoteProdHasInhEq(prodName, vt, attrName, flowEnv, realEnv); - --- Is this there an equation for this inh attr on any decoration site for this vertex? -fun remoteProdHasInhEq -Boolean ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv realEnv::Env = - any(unzipWith(vertexHasInhEq(_, _, attrName, flowEnv), lookupAllDecSites(prodName, vt, flowEnv))) || - case vt of - | rhsVertexType(sigName) when getValueDcl(sigName, realEnv) matches dcl :: _ -> - dcl.isShared && - all(unzipWith(vertexHasInhEq(_, _, attrName, flowEnv), - lookupAllSigShareSites(prodName, sigName, flowEnv, realEnv))) - | _ -> false - end; - --- Find all decoration sites productions/vertices for this vertex --- TODO: This doesn't gracefully handle cycles in sharing. -fun lookupAllDecSites [(String, VertexType)] ::= prodName::String vt::VertexType flowEnv::FlowEnv = - (prodName, vt) :: - case vt of - | subtermVertexType(_, remoteProdName, sigName) -> - lookupAllDecSites(remoteProdName, rhsVertexType(sigName), flowEnv) - | _ -> flatMap(lookupAllDecSites(prodName, _, flowEnv), lookupRefDecSite(prodName, vt, flowEnv)) - end; - +-- inherited equation for some arbitrary vertex type fun vertexHasInhEq Boolean ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv = case vt of | rhsVertexType(sigName) -> !null(lookupInh(prodName, sigName, attrName, flowEnv)) @@ -167,16 +129,6 @@ fun vertexHasInhEq Boolean ::= prodName::String vt::VertexType attrName::Strin | forwardVertexType_real() -> false -- Same as LHS, but we can check this if e.g. forwarding to a child. end; -{-- - - This is a glorified lambda function, to help look for equations. - - Literally, we're just checking for null here. - - - - @param f The lookup function for the appropriate type of equation - - e.g. `lookupInh(prod, rhs, _, env)` - - @param attr The attribute to look up. - -} -fun isEquationMissing Boolean ::= f::([FlowDef] ::= String) attr::String = null(f(attr)); - -- default set of inherited attributes required/assumed to exist for references fun getInhsForNtRef [[String]] ::= nt::String e::FlowEnv = searchEnvTree(nt, e.refTree); diff --git a/grammars/silver/compiler/driver/util/FlowTypes.sv b/grammars/silver/compiler/driver/util/FlowTypes.sv index 914c2b4c7..716749983 100644 --- a/grammars/silver/compiler/driver/util/FlowTypes.sv +++ b/grammars/silver/compiler/driver/util/FlowTypes.sv @@ -19,9 +19,6 @@ top::Compilation ::= g::Grammars r::Grammars buildGrammars::[String] benv::Bu local allSharedRefs :: [(String, SharedRefSite)] = flatMap((.sharedRefs), allLatestGrammars); local allFlowEnv :: FlowEnv = flowEnv(allSpecDefs, allRefDefs, allSharedRefs, allFlowDefs); - -- Look up tree for production info - local prodTree :: EnvTree = directBuildTree(allFlowDefs.prodGraphContribs); - -- We need to know about all attributes and occurences on nonterminals. -- It's possible (likely) we could do better than using the overall env here. local allRealDefs :: [Def] = flatMap((.defs), allLatestGrammars); @@ -34,7 +31,7 @@ top::Compilation ::= g::Grammars r::Grammars buildGrammars::[String] benv::Bu -- Construct production graphs. production prodGraph :: [ProductionGraph] = - computeAllProductionGraphs(allProds, prodTree, allFlowEnv, allRealEnv) ++ + computeAllProductionGraphs(allProds, allFlowEnv, allRealEnv) ++ -- Add in phantom graphs map(constructPhantomProductionGraph(_, allFlowEnv, allRealEnv), allNts); diff --git a/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv b/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv index 2c6aff83b..bef4dd288 100644 --- a/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv +++ b/grammars/silver/compiler/modification/primitivepattern/VarBinders.sv @@ -148,7 +148,7 @@ top::VarBinder ::= n::Name -- Recall that we emit (vertex, [reference set]) for expressions with a vertex. -- and the correct value is computed based on how this gets used. - -- (e.g. if 'new' + -- TODO: Could this be simplified by using subtermVertexType instead of an anon vertex here? local vt :: Maybe = if isDecorable(top.bindingType, top.env) then just(anonVertexType(fName)) diff --git a/grammars/silver/compiler/translation/java/core/DispatchDcl.sv b/grammars/silver/compiler/translation/java/core/DispatchDcl.sv new file mode 100644 index 000000000..fd741221e --- /dev/null +++ b/grammars/silver/compiler/translation/java/core/DispatchDcl.sv @@ -0,0 +1,20 @@ +grammar silver:compiler:translation:java:core; + +aspect production dispatchSigDcl +top::AGDcl ::= 'dispatch' id::Name '=' sig::ProductionSignature ';' +{ + local className :: String = "P" ++ id.name; + + -- Currently, implementation prods directly extend the nonterminal class. + -- This just exists as a place to store the child indices. + top.genFiles := [(className ++ ".java", s""" +package ${makeName(top.grammarName)}; + +// ${sig.unparse} +public final class ${className} { + +${makeIndexDcls(0, namedSig.inputElements)} + +} +""")]; +} diff --git a/grammars/silver/compiler/translation/java/core/NamedSignature.sv b/grammars/silver/compiler/translation/java/core/NamedSignature.sv index d89f56c6e..11b2fad2b 100644 --- a/grammars/silver/compiler/translation/java/core/NamedSignature.sv +++ b/grammars/silver/compiler/translation/java/core/NamedSignature.sv @@ -331,7 +331,7 @@ String ::= env::Env flowEnv::FlowEnv lhsNtName::String prodName::String n::Named end; } --- Translation of accessing the a tree that is shared in a position corresponding to some flow vertex type. +-- Translation of accessing a tree that is shared in a position corresponding to some flow vertex type. fun refAccessTranslation String ::= env::Env flowEnv::FlowEnv lhsNtName::String v::VertexType = case v of | lhsVertexType_real() -> error("lhs can't be a ref decoration site") @@ -353,6 +353,7 @@ fun refAccessTranslation String ::= env::Env flowEnv::FlowEnv lhsNtName::String | forwardVertexType_real() -> s"context.forward()" | anonVertexType(_) -> error("dec site projection shouldn't happen with anon decorate") | subtermVertexType(parent, prodName, sigName) -> + -- prodName is either a production or dispatch signature name s"${refAccessTranslation(env, flowEnv, lhsNtName, parent)}.childDecorated(${makeProdName(prodName)}.i_${sigName})" end; @@ -380,7 +381,6 @@ fun sharedRefTranslation String ::= env::Env frame::BlockContext v::VertexType = end | _ -> error("Sharing for invalid sort of tree " ++ v.vertexPP) end; - function makeAnnoAssign String ::= n::NamedSignatureElement diff --git a/runtime/java/src/common/DecoratedNode.java b/runtime/java/src/common/DecoratedNode.java index 6fcf7d72b..966fcbed9 100644 --- a/runtime/java/src/common/DecoratedNode.java +++ b/runtime/java/src/common/DecoratedNode.java @@ -220,7 +220,7 @@ public final Node undecorate() { } /** - * Decorate this (unique decorated) node with additional inherited attributes. + * Decorate this (decorated) node with additional inherited attributes. * This has no effect if the node already has a forward parent. * * @param parent The DecoratedNode extra-decorating this one. (Whether this is a child or a local (or other) of that node.) From 36e14dfe24525e15f692fb259506c674e5fcd163 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 11 Apr 2024 18:43:00 -0500 Subject: [PATCH 222/283] Change tree sharing translation to only demand decoration site when a missing inh attr is accessed --- .../definition/flow/env/FunctionDcl.sv | 1 - .../compiler/translation/java/core/Expr.sv | 20 +-- .../translation/java/core/NamedSignature.sv | 25 --- .../translation/java/core/NonTerminalDcl.sv | 4 +- .../.settings/org.eclipse.jdt.core.prefs | 2 +- runtime/java/src/common/DataNode.java | 6 +- runtime/java/src/common/Decorable.java | 5 +- runtime/java/src/common/DecoratedNode.java | 146 ++++++------------ runtime/java/src/common/Node.java | 11 +- runtime/java/src/common/TopNode.java | 4 +- 10 files changed, 74 insertions(+), 150 deletions(-) diff --git a/grammars/silver/compiler/definition/flow/env/FunctionDcl.sv b/grammars/silver/compiler/definition/flow/env/FunctionDcl.sv index b62714f4b..2bf1a1675 100644 --- a/grammars/silver/compiler/definition/flow/env/FunctionDcl.sv +++ b/grammars/silver/compiler/definition/flow/env/FunctionDcl.sv @@ -1,6 +1,5 @@ grammar silver:compiler:definition:flow:env; -import silver:compiler:definition:type only typerep; import silver:compiler:definition:flow:driver only ProductionGraph, FlowType, constructFunctionGraph, constructAnonymousGraph; import silver:compiler:driver:util only RootSpec; -- actually we just want the occurrences import silver:compiler:definition:type:syntax; -- actually we just want the occurrences diff --git a/grammars/silver/compiler/translation/java/core/Expr.sv b/grammars/silver/compiler/translation/java/core/Expr.sv index 64b161c22..489185ca2 100644 --- a/grammars/silver/compiler/translation/java/core/Expr.sv +++ b/grammars/silver/compiler/translation/java/core/Expr.sv @@ -430,9 +430,15 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur aspect production decorateExprWith top::Expr ::= 'decorate' e::Expr 'with' '{' inh::ExprInhs '}' { + local decSite::String = + case top.decSiteVertexInfo of + | just(decSite) when top.alwaysDecorated -> + s"(context) -> ${refAccessTranslation(top.env, top.flowEnv, top.frame.lhsNtName, decSite)}" + | _ -> "(common.Lazy)null" + end; top.translation = s"((common.Decorable)${e.translation})" ++ case inh of - | exprInhsEmpty() -> ".decorate(context, (common.Lazy[])null)" + | exprInhsEmpty() -> s".decorate(context, (common.Lazy[])null, ${decSite})" -- Note: we don't NEED to pass context here, but it's good for error messages! -- When the user forgets to provide inherited attributes -- (especially important because we're implicitly inserted when accessing attributes @@ -445,7 +451,8 @@ top::Expr ::= 'decorate' e::Expr 'with' '{' inh::ExprInhs '}' | t -> s"${makeNTName(t.typeName)}.num_inh_attrs" end ++ ", " ++ s"new int[]{${implode(", ", inh.nameTrans)}}, " ++ - s"new common.Lazy[]{${implode(", ", inh.valueTrans)}}))" + s"new common.Lazy[]{${implode(", ", inh.valueTrans)}}), " ++ + s"${decSite})" end; top.lazyTranslation = wrapThunk(top.translation, top.frame.lazyApplication); @@ -499,14 +506,7 @@ top::Expr ::= '@' e::Expr top.translation = s"new ${top.finalType.transType}.DecorationSiteWrapper(${ if top.finalType.isTracked then makeOriginContextRef(top) ++ ".makeNewConstructionOrigin(true), " else ""}${ - if top.alwaysDecorated - -- This production may depend on additional inherited attributes supplied through this tree - -- through its shared decoration site, so e.translation will access the tree through its decoration site. - -- We need the raw tree here to avoid a circularity. - -- This is not cached, as the uniqueness analysis gurantees it will only be demanded once. - then sharedRefTranslation(top.env, top.frame, e.flowVertexInfo.fromJust) - -- We won't depend on any attributes later supplied to the tree, just demand it the normal way here. - else e.translation})"; + e.translation})"; top.lazyTranslation = wrapThunk(top.translation, top.frame.lazyApplication); top.initTransDecSites <- diff --git a/grammars/silver/compiler/translation/java/core/NamedSignature.sv b/grammars/silver/compiler/translation/java/core/NamedSignature.sv index 11b2fad2b..f3a79a659 100644 --- a/grammars/silver/compiler/translation/java/core/NamedSignature.sv +++ b/grammars/silver/compiler/translation/java/core/NamedSignature.sv @@ -357,31 +357,6 @@ fun refAccessTranslation String ::= env::Env flowEnv::FlowEnv lhsNtName::String s"${refAccessTranslation(env, flowEnv, lhsNtName, parent)}.childDecorated(${makeProdName(prodName)}.i_${sigName})" end; --- Translation of demanding the tree corresponding to a flow vertex type, to be shared. --- Note that this is not cached; uniqueness analysis guarantees that it should only be demanded once. -fun sharedRefTranslation String ::= env::Env frame::BlockContext v::VertexType = - case v of - | rhsVertexType(sigName) -> s"context.createDecoratedChild(${frame.className}.i_${sigName})" - | localVertexType(fName) -> - case getValueDcl(fName, env) of - | dcl :: _ -> s"context.evalLocalDecorated(${dcl.attrOccursIndex})" - | _ -> error("Couldn't find decl for local " ++ fName) - end - | transAttrVertexType(rhsVertexType(sigName), transAttr) -> - case lookup(sigName, zip(frame.signature.inputNames, frame.signature.inputTypes)) of - | just(ty) when getOccursDcl(transAttr, ty.typeName, env) matches occDcl :: _ -> - s"context.childDecorated(${frame.className}.i_${sigName}).evalTrans(${occDcl.attrOccursIndex}, ${occDcl.attrOccursIndex}_inhs)" - | _ -> error("Couldn't find occurs dcl for " ++ transAttr ++ " on " ++ sigName) - end - | transAttrVertexType(localVertexType(fName), transAttr) -> - case getValueDcl(fName, env) of - | dcl :: _ when getOccursDcl(transAttr, dcl.typeScheme.typeName, env) matches occDcl :: _ -> - s"context.localDecorated(${dcl.attrOccursIndex}).evalTrans(${occDcl.attrOccursIndex}, ${occDcl.attrOccursIndex}_inhs)" - | _ -> error("Couldn't find occurs dcl for " ++ transAttr ++ " on " ++ fName) - end - | _ -> error("Sharing for invalid sort of tree " ++ v.vertexPP) - end; - function makeAnnoAssign String ::= n::NamedSignatureElement { diff --git a/grammars/silver/compiler/translation/java/core/NonTerminalDcl.sv b/grammars/silver/compiler/translation/java/core/NonTerminalDcl.sv index 127dfd8f4..bb09b1fe9 100644 --- a/grammars/silver/compiler/translation/java/core/NonTerminalDcl.sv +++ b/grammars/silver/compiler/translation/java/core/NonTerminalDcl.sv @@ -106,8 +106,8 @@ ${if quals.data then "" else s""" } @Override - public common.DecoratedNode decorate(final common.DecoratedNode parent, final common.Lazy[] inhs) { - return ref.decorate(parent, inhs); + public common.DecoratedNode decorate(final common.DecoratedNode parent, final common.Lazy[] inhs, final common.Lazy decSite) { + return ref.decorate(parent, inhs, decSite); } @Override diff --git a/language-server/launcher/.settings/org.eclipse.jdt.core.prefs b/language-server/launcher/.settings/org.eclipse.jdt.core.prefs index 6bf842e11..43781029c 100644 --- a/language-server/launcher/.settings/org.eclipse.jdt.core.prefs +++ b/language-server/launcher/.settings/org.eclipse.jdt.core.prefs @@ -110,7 +110,7 @@ org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=wa org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=warning org.eclipse.jdt.core.compiler.problem.nullReference=warning org.eclipse.jdt.core.compiler.problem.nullSpecViolation=warning -org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning +org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=ignore org.eclipse.jdt.core.compiler.problem.overridingMethodWithoutSuperInvocation=ignore org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore diff --git a/runtime/java/src/common/DataNode.java b/runtime/java/src/common/DataNode.java index 3d95f1121..95daabe9f 100644 --- a/runtime/java/src/common/DataNode.java +++ b/runtime/java/src/common/DataNode.java @@ -57,8 +57,8 @@ public DecoratedNode childDecorated(final int child) { * @return The "decorated" form of this DataNode. */ @Override - public final DecoratedNode decorate(final DecoratedNode parent, final Lazy[] inhs) { - if (inhs != null) { + public final DecoratedNode decorate(final DecoratedNode parent, final Lazy[] inhs, final Lazy decSite) { + if (inhs != null || decSite != null) { throw new SilverInternalError("Data nonterminals cannot be decorated with inherited attributes!"); } if (context == null) { @@ -70,7 +70,7 @@ public final DecoratedNode decorate(final DecoratedNode parent, final Lazy[] inh private DecoratedNode createContext() { return new DecoratedNode( getNumberOfChildren(), 0, getNumberOfSynAttrs(), getNumberOfLocalAttrs(), - this, TopNode.singleton, null, null, false); + this, TopNode.singleton, null, null, false, null); } // These methods have implementations here since we never forward or supply inherited attributes: diff --git a/runtime/java/src/common/Decorable.java b/runtime/java/src/common/Decorable.java index f6f170a63..30e156c63 100644 --- a/runtime/java/src/common/Decorable.java +++ b/runtime/java/src/common/Decorable.java @@ -14,9 +14,10 @@ public interface Decorable { * @param parent The DecoratedNode creating this one. (Whether this is a child or a local (or other) of that node.) * @param inhs A map from inh attribute indexes to Lazys that define them. * These Lazys will be supplied with 'parent' as their context for evaluation. + * @param decSite An accessor for where this DecoratedNode will be supplied with additional inherited attributes. * @return A DecoratedNode with the attributes supplied. */ - public DecoratedNode decorate(final DecoratedNode parent, final Lazy[] inhs); + public DecoratedNode decorate(final DecoratedNode parent, final Lazy[] inhs, final Lazy decSite); /** * Decorate this node with a forward parent. @@ -42,6 +43,6 @@ public DecoratedNode decorate( * @return A node decorated with no inherited attributes, without a parent. */ public default DecoratedNode decorate() { - return decorate(TopNode.singleton, null); + return decorate(TopNode.singleton, null, null); } } diff --git a/runtime/java/src/common/DecoratedNode.java b/runtime/java/src/common/DecoratedNode.java index 966fcbed9..038fdd5fc 100644 --- a/runtime/java/src/common/DecoratedNode.java +++ b/runtime/java/src/common/DecoratedNode.java @@ -44,7 +44,7 @@ public class DecoratedNode implements Decorable, Typed { protected final Node self; /** * The node that forwards to this one. (May be null) - * Not final, because we may set this when forwarding to a decorated tree via a unique reference. + * Not final, because we may set this when forwarding to a decorated tree via sharing. */ protected DecoratedNode forwardParent; /** @@ -102,27 +102,16 @@ public class DecoratedNode implements Decorable, Typed { protected Lazy[] inheritedAttributes; /** - * A cache of the values of local attributes on this node. (incl. locals and prod) + * A place where this tree will be decorated with additional inherited attributes. + * Decoration can be forced by evaluating this with context 'parent'. */ - protected final Object[] localValues; + protected Lazy decorationSite; /** - * Track whether a decorated child has already been created, for sanity checking. - * This may be true when childrenValues[i] == null, because of how unique references are translated. - */ - protected final boolean[] childCreated; - /** - * Track whether a decorated local has already been created, for sanity checking. - * This may be true when localValues[i] == null, because of how unique references are translated. - */ - protected final boolean[] localCreated; - /** - * Track whether a decorated translation attribute has already been created, for sanity checking. - * This may be true when synthesizedValues[i] == null, because of how unique references are translated. + * A cache of the values of local attributes on this node. (incl. locals and prod) */ - protected final boolean[] transCreated; + protected final Object[] localValues; - /** * Construct a decorated form of a Node. Called only via Node. * @@ -145,12 +134,14 @@ public class DecoratedNode implements Decorable, Typed { final int cc, final int ic, final int sc, final int lc, final Node self, final DecoratedNode parent, final Lazy[] inhs, - final DecoratedNode forwardParent, final boolean isProdForward) { + final DecoratedNode forwardParent, final boolean isProdForward, + final Lazy decorationSite) { this.self = self; this.parent = parent; this.originCtx = parent!=null?parent.originCtx:null; this.forwardParent = forwardParent; this.isProdForward = isProdForward; + this.decorationSite = decorationSite; if(inhs != null && inhs.length < ic) { // TODO: Due to the implementation of inherited occurs-on constraints, we might @@ -166,9 +157,6 @@ public class DecoratedNode implements Decorable, Typed { this.inheritedValues = (ic > 0) ? new Object[ic] : null; this.synthesizedValues = (sc > 0) ? new Object[sc] : null; this.localValues = (lc > 0) ? new Object[lc] : null; - this.childCreated = (cc > 0) ? new boolean[cc] : null; - this.localCreated = (lc > 0) ? new boolean[lc] : null; - this.transCreated = (sc > 0) ? new boolean[sc] : null; // STATS: Uncomment to enable statistics //Statistics.dnSpawn(self!=null?self.getClass():TopNode.class); @@ -196,9 +184,6 @@ public class DecoratedNode implements Decorable, Typed { this.inheritedValues = null; this.synthesizedValues = null; this.localValues = (lc > 0) ? new Object[lc] : null; - this.childCreated = new boolean[cc]; - this.localCreated = (lc > 0) ? new boolean[lc] : null; - this.transCreated = null; } // STATS: Uncomment to enable statistics @@ -226,12 +211,11 @@ public final Node undecorate() { * @param parent The DecoratedNode extra-decorating this one. (Whether this is a child or a local (or other) of that node.) * @param inhs Overrides for inherited attributes that should not be computed via forwarding. * These Lazys will be supplied with 'parent' as their context for evaluation. - * @param transInhs Overrides for inherited attributes on translation attributes that should not be computed via forwarding. - * These Lazys will be supplied with 'parent' as their context for evaluation. + * @param decSite An accessor for where this DecoratedNode will be supplied with additional inherited attributes. * @return A DecoratedNode with the additional attributes supplied, referencing this DecoratedNode as 'base'. */ @Override - public DecoratedNode decorate(final DecoratedNode parent, final Lazy[] inhs) { + public DecoratedNode decorate(final DecoratedNode parent, final Lazy[] inhs, final Lazy decSite) { // System.err.println("TRACE: " + parent.getDebugID() + " extra-decorating " + getDebugID()); if (forwardParent == null) { if (inhs != null) { @@ -247,6 +231,7 @@ public DecoratedNode decorate(final DecoratedNode parent, final Lazy[] inhs) { } } } + decorationSite = decSite != null? decSite.withContext(parent) : null; } return this; } @@ -257,8 +242,6 @@ public DecoratedNode decorate(final DecoratedNode parent, final Lazy[] inhs) { * * @param parent The "true parent" of this node (same as the fwdParent's parent) * @param inhs A map from attribute indexes to Lazys that define them. These Lazys will be supplied with 'parent' as their context for evaluation. - * @param transInhs Overrides for inherited attributes on translation attributes that should not be computed via forwarding. - * These Lazys will be supplied with 'parent' as their context for evaluation. * @param fwdParent The DecoratedNode that forwards to the one we are about to create. We will pass inherited attribute access requests to this node. * @param prodFwrd Is this the forward for fwdParent's prod? False for forward prod attributes. * @return A DecoratedNode with the attributes supplied. @@ -266,7 +249,7 @@ public DecoratedNode decorate(final DecoratedNode parent, final Lazy[] inhs) { @Override public DecoratedNode decorate(final DecoratedNode parent, final Lazy[] inhs, final DecoratedNode fwdParent, final boolean prodFwrd) { if (forwardParent == null) { - decorate(parent, inhs); + decorate(parent, inhs, null); forwardParent = fwdParent; isProdForward = prodFwrd; } @@ -277,7 +260,7 @@ public DecoratedNode decorate(final DecoratedNode parent, final Lazy[] inhs, fin * Accessor function to access the originally-decorated Node. * The Node returned by this function must never be decorated - * e.g. for use by origin tracking or for debugging purposes. - * One should typically use {@link undecorate} instead to avoid duplicating any unique children. + * One should typically use {@link undecorate} instead to avoid duplicating any shared children. * * @return The {@link Node} this decorates. */ @@ -327,7 +310,7 @@ public T childAsIs(final int child) { public DecoratedNode childDecorated(final int child) { Object o = this.childrenValues[child]; if(o == null) { - o = obtainDecoratedChild(child); + o = createDecoratedChild(child); assert(o != null); @@ -337,36 +320,17 @@ public DecoratedNode childDecorated(final int child) { return (DecoratedNode)o; } - /** - * Create or retrieve the DecoratedNode for a child. - * Separate function to keep {@link #childDecorated} small and inlineable. - * This is, after all, the "slow path." - */ - private final DecoratedNode obtainDecoratedChild(final int child) { - Lazy decSite = self.getChildDecSite(child); - if(decSite == null) { - return createDecoratedChild(child); - } else { - return (DecoratedNode)decSite.eval(this); - } - } - /** * Create the DecoratedNode for a child. - * This can also be called directly in the translation of taking a unique reference. * Invariant: should never be called more than once for a child! * * @param child The number of the child to create. * @return The decorated value of the child. */ - public final DecoratedNode createDecoratedChild(final int child) { + private final DecoratedNode createDecoratedChild(final int child) { assert self.isChildDecorable(child); - if(childCreated[child]) { - throw new SilverInternalError("Decorated child " + child + " created more than once in " + getDebugID()); - } - DecoratedNode result = ((Decorable)self.getChild(child)).decorate(this, self.getChildInheritedAttributes(child)); - childCreated[child] = true; - return result; + return ((Decorable)self.getChild(child)).decorate( + this, self.getChildInheritedAttributes(child), self.getChildDecSite(child)); } /** @@ -443,7 +407,7 @@ private final SilverException handleLocalError(final int attribute, final Throwa public DecoratedNode localDecorated(final int attribute) { Object o = this.localValues[attribute]; if(o == null) { - o = obtainDecoratedLocal(attribute); + o = evalLocalDecorated(attribute); assert(o != null); @@ -454,41 +418,22 @@ public DecoratedNode localDecorated(final int attribute) { return (DecoratedNode)o; } - /** - * Another case of keeping the slow paths out of here, so it can be inlined. - */ - private final DecoratedNode obtainDecoratedLocal(final int attribute) { - Lazy decSite = self.getLocalDecSite(attribute); - if(decSite == null) { - return evalLocalDecorated(attribute); - } else { - return (DecoratedNode)decSite.eval(this); - } - } - /** * Evaluate a local and decorate it. - * This can also be called directly in the translation of taking a unique reference. * Invariant: should never be called more than once for a local! * * @param attribute The index of the local to obtain. * @return The decorated value of the local. */ - public final DecoratedNode evalLocalDecorated(final int attribute) { + private final DecoratedNode evalLocalDecorated(final int attribute) { assert self.isLocalDecorable(attribute); - if(localCreated[attribute]) { - throw new SilverInternalError("Decorated local '" + self.getNameOfLocalAttr(attribute) + "' created more than once in " + getDebugID()); - } Decorable localAsIs = (Decorable)evalLocalAsIs(attribute); Lazy[] inhs = self.getLocalInheritedAttributes(attribute); - DecoratedNode result; if(self.getLocalIsForward(attribute)) { - result = localAsIs.decorate(this, inhs, this, false); + return localAsIs.decorate(this, inhs, this, false); } else { - result = localAsIs.decorate(this, inhs); + return localAsIs.decorate(this, inhs, self.getLocalDecSite(attribute)); } - localCreated[attribute] = true; - return result; } /** @@ -562,6 +507,7 @@ private final Object evalSyn(final int attribute) { * Evaluate it as a synthesized attribute, then decorate it. * * @param attribute The index of the attribute. + * @param inhsAttribute The index of the TransInhs supplying the attribute's inherited attributes * @param decSiteAttribute The index of the attribute's decoration site attribute * @return The value of the attribute. */ @@ -571,7 +517,7 @@ public DecoratedNode translation(final int attribute, final int inhsAttribute, f DecoratedNode o = (DecoratedNode)this.synthesizedValues[attribute]; if(o == null) { - o = obtainDecoratedTrans(attribute, inhsAttribute, decSiteAttribute); + o = evalTrans(attribute, inhsAttribute, decSiteAttribute); assert(o != null); @@ -581,29 +527,20 @@ public DecoratedNode translation(final int attribute, final int inhsAttribute, f return o; } - private final DecoratedNode obtainDecoratedTrans(final int attribute, final int inhsAttribute, final int decSiteAttribute) { - Lazy decSite = inheritedAttributes == null? null : inheritedAttributes[decSiteAttribute]; - if(decSite != null) { - return (DecoratedNode)decSite.eval(parent); - } else if(forwardParent != null && isProdForward) { - return forwardParent.translation(attribute, inhsAttribute, decSiteAttribute); - } else { - return evalTrans(attribute, inhsAttribute); - } - } - /** * Evaluate a translation attribute and decorate it. - * This can also be called directly in the translation of taking a unique reference. * Invariant: should never be called more than once for an attribute! * * @param attribute The index of the translation attribute to obtain. + * @param inhsAttribute The index of the TransInhs supplying the attribute's inherited attributes + * @param decSiteAttribute The index of the attribute's decoration site attribute * @return The decorated value of the translation attribute. */ - public final DecoratedNode evalTrans(final int attribute, final int inhsAttribute) { - if(transCreated[attribute]) { - throw new SilverInternalError("Decorated translation attribute " + self.getNameOfSynAttr(attribute) + " created more than once!"); + private final DecoratedNode evalTrans(final int attribute, final int inhsAttribute, final int decSiteAttribute) { + if(forwardParent != null && isProdForward) { + return forwardParent.translation(attribute, inhsAttribute, decSiteAttribute); } + Lazy l = self.getSynthesized(attribute); Decorable d; if(l != null) { @@ -614,7 +551,7 @@ public final DecoratedNode evalTrans(final int attribute, final int inhsAttribut } } else if(self.hasForward()) { try { - d = forward().evalTrans(attribute, inhsAttribute); + d = forward().evalTrans(attribute, inhsAttribute, decSiteAttribute); } catch(Throwable t) { throw new TraceException("While evaling trans '" + self.getNameOfSynAttr(attribute) + "' via forward in " + getDebugID(), t); } @@ -638,9 +575,8 @@ public final DecoratedNode evalTrans(final int attribute, final int inhsAttribut throw new SilverInternalError("Supplied trans inhs attribute not TransInhs!"); } } - DecoratedNode result = d.decorate(parent, inhs); - transCreated[attribute] = true; - return result; + Lazy decSite = inheritedAttributes == null? null : inheritedAttributes[decSiteAttribute]; + return d.decorate(parent, inhs, decSite); } /** @@ -734,7 +670,23 @@ private final Object evalInhSomehow(final int attribute) { if(inheritedAttributes != null && inheritedAttributes[attribute] != null) return evalInhHere(attribute); else + return evalInhViaDecSiteOrFwrd(attribute); + } + private final Object evalInhViaDecSiteOrFwrd(final int attribute) { + if(this.decorationSite != null) { + return evalInhViaDecSite(attribute); + } else { return evalInhViaFwdP(attribute); + } + } + private final Object evalInhViaDecSite(final int attribute) { + Lazy decSite = this.decorationSite; + this.decorationSite = null; + Object decSiteTree = decSite.eval(parent); + if(this != decSiteTree) { + throw new SilverInternalError("Decoration site for " + getDebugID() + " returned a different tree: " + decSiteTree.toString()); + } + return inherited(attribute); } private final Object evalInhViaFwdP(final int attribute) { try { diff --git a/runtime/java/src/common/Node.java b/runtime/java/src/common/Node.java index 61a3fe6bb..ff63d07b7 100644 --- a/runtime/java/src/common/Node.java +++ b/runtime/java/src/common/Node.java @@ -28,18 +28,17 @@ protected Node(final boolean isUnique) { * * @param parent The DecoratedNode creating this one. (Whether this is a child or a local (or other) of that node.) * @param inhs A map from attribute indexes to Lazys that define them. These Lazys will be supplied with 'parent' as their context for evaluation. - * @param transInhs A map from trans (syn) attribute indexes, to maps from inh attribute indexes to Lazys that define them. - * These Lazys will be supplied with 'parent' as their context for evaluation. + * @param decSite An accessor for where this DecoratedNode will be supplied with additional inherited attributes. * @return A "decorated" form of this Node */ @Override public DecoratedNode decorate( - final DecoratedNode parent, final Lazy[] inhs) { + final DecoratedNode parent, final Lazy[] inhs, final Lazy decSite) { return new DecoratedNode(getNumberOfChildren(), getNumberOfInhAttrs(), getNumberOfSynAttrs(), getNumberOfLocalAttrs(), - this, parent, inhs, null, false); + this, parent, inhs, null, false, decSite); } /** @@ -49,8 +48,6 @@ public DecoratedNode decorate( * @param parent The "true parent" of this node (same as the fwdParent's parent) * @param inhs Overrides for inherited attributes that should not be computed via forwarding. * These Lazys will be supplied with 'parent' as their context for evaluation. - * @param transInhs Overrides for inherited attributes on translation attributes that should not be computed via forwarding. - * These Lazys will be supplied with 'parent' as their context for evaluation. * @param fwdParent The DecoratedNode that forwards to the one we are about to create. * We will pass inherited attribute access requests to this node. * @param prodFwrd Is this the forward for fwdParent's prod? False for forward prod attributes. @@ -64,7 +61,7 @@ public DecoratedNode decorate( getNumberOfInhAttrs(), getNumberOfSynAttrs(), getNumberOfLocalAttrs(), - this, parent, inhs, fwdParent, isProdForward); + this, parent, inhs, fwdParent, isProdForward, null); } private Node undecoratedValue = null; diff --git a/runtime/java/src/common/TopNode.java b/runtime/java/src/common/TopNode.java index 8e028360f..897805535 100644 --- a/runtime/java/src/common/TopNode.java +++ b/runtime/java/src/common/TopNode.java @@ -17,12 +17,12 @@ public class TopNode extends DecoratedNode{ // TODO: this should become a Node! public static final TopNode singleton = new TopNode(); private TopNode() { - super(0,0,0,0,null,null,null,null,false); + super(0,0,0,0,null,null,null,null,false,null); this.originCtx = OriginContext.GLOBAL_CONTEXT; } @Override - public final DecoratedNode decorate(final DecoratedNode parent, final Lazy[] inhs) { + public final DecoratedNode decorate(final DecoratedNode parent, final Lazy[] inhs, final Lazy decSite) { throw new SilverInternalError("TopNode cannot be decorated."); } From a7d358571bf9633f5859f812fd2c4beb35676a96 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 11 Apr 2024 23:01:46 -0500 Subject: [PATCH 223/283] Fixing some bugs in revised inh completeness checking --- .../compiler/analysis/warnings/flow/Inh.sv | 58 ++++++++++++++----- .../definition/core/ProductionBody.sv | 2 +- .../definition/flow/ast/VertexType.sv | 10 +++- .../compiler/definition/flow/env/DecSites.sv | 27 ++++++++- .../compiler/definition/flow/env/FlowEnv.sv | 13 +++++ 5 files changed, 90 insertions(+), 20 deletions(-) diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index c6b4df8f8..a88a3b3fd 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -238,9 +238,12 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr inhDepsForSyn("forward", top.frame.lhsNtName, myFlow)))); -- Make sure we aren't introducing any hidden transitive dependencies. + -- TODO: Revisit these checks with dispatch sharing. local refDecSiteInhDepsLhsInh :: Maybe> = - case lookupRefPossibleDecSites(top.frame.fullName, dl.defLHSVertex, top.flowEnv) of + case filter( + notSharedInputVertex(_, top.env), + lookupRefPossibleDecSites(top.frame.fullName, dl.defLHSVertex, top.flowEnv)) of | [] -> nothing() | vs -> just(onlyLhsInh(expandGraph( dl.defLHSVertex.eqVertex ++ @@ -251,7 +254,9 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr local transBaseRefDecSiteInhDepsLhsInh :: Maybe> = case dl.defLHSVertex of | transAttrVertexType(v, transAttr) -> - case lookupRefPossibleDecSites(top.frame.fullName, v, top.flowEnv) of + case filter( + notSharedInputVertex(_, top.env), + lookupRefPossibleDecSites(top.frame.fullName, dl.defLHSVertex, top.flowEnv)) of | [] -> nothing() | vs -> just(onlyLhsInh(expandGraph( v.eqVertex ++ @@ -300,6 +305,17 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr end; } +fun notSharedInputVertex Boolean ::= v::VertexType env::Env = + case v of + | subtermVertexType(_, prodName, sigName) -> + case getTypeDcl(prodName, env), getValueDcl(prodName, env) of + | dcl :: _, _ -> !lookupSignatureInputElem(sigName, dcl.dispatchSignature).elementShared + | _, dcl :: _ -> !lookupSignatureInputElem(sigName, dcl.namedSignature).elementShared + | _, _ -> false + end + | _ -> true + end; + ----- WARNING TODO BEGIN MASSIVE COPY & PASTE SESSION aspect production synBaseColAttributeDef top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr @@ -619,14 +635,19 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur if null(e.errors) && top.config.warnMissingInh then case e.flowVertexInfo of - | just(vt) -> - let decSites::[DecSite] = findDecSites(top.frame.fullName, vt, [], top.flowEnv, top.env) in - case filter(decSitesMissingInhEq(_, decSites, top.flowEnv), set:toList(inhDeps)) of - | [] -> [] - | inhs -> [mwdaWrnFromOrigin(top, "Access of syn attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied to " ++ prettyDecSites(decSites))] - end + | just(vt) when + case vt of + | rhsVertexType(_) -> true + | localVertexType(_) -> true + | _ -> false + end -> + let decSites::[DecSite] = findDecSites(top.frame.fullName, vt, [], top.flowEnv, top.env) in + case filter(decSitesMissingInhEq(_, decSites, top.flowEnv), set:toList(inhDeps)) of + | [] -> [] + | inhs -> [mwdaWrnFromOrigin(top, "Access of synthesized attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied to " ++ prettyDecSites(decSites))] end - | nothing() -> [] + end + | _ -> [] end else []; } @@ -722,14 +743,19 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur if null(e.errors) && top.config.warnMissingInh then case e.flowVertexInfo of - | just(vt) -> - let decSites::[DecSite] = findDecSites(top.frame.fullName, vt, [], top.flowEnv, top.env) in - case filter(decSitesMissingInhEq(_, decSites, top.flowEnv), set:toList(inhDeps)) of - | [] -> [] - | inhs -> [mwdaWrnFromOrigin(top, "Access of trans attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied to " ++ prettyDecSites(decSites))] - end + | just(vt) when + case vt of + | rhsVertexType(_) -> true + | localVertexType(_) -> true + | _ -> false + end -> + let decSites::[DecSite] = findDecSites(top.frame.fullName, vt, [], top.flowEnv, top.env) in + case filter(decSitesMissingInhEq(_, decSites, top.flowEnv), set:toList(inhDeps)) of + | [] -> [] + | inhs -> [mwdaWrnFromOrigin(top, "Access of translation attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied to " ++ prettyDecSites(decSites))] end - | nothing() -> [] + end + | _ -> [] end else []; } diff --git a/grammars/silver/compiler/definition/core/ProductionBody.sv b/grammars/silver/compiler/definition/core/ProductionBody.sv index 146b893eb..9eb2ecb31 100644 --- a/grammars/silver/compiler/definition/core/ProductionBody.sv +++ b/grammars/silver/compiler/definition/core/ProductionBody.sv @@ -419,7 +419,7 @@ top::DefLHS ::= @q::QName top.errors <- if existingProblems || top.found then [] else [errFromOrigin(q, "Cannot define synthesized attribute '" ++ top.defLHSattr.name ++ "' on child '" ++ q.name ++ "'")]; - + top.typerep = q.lookupValue.typeScheme.monoType; } diff --git a/grammars/silver/compiler/definition/flow/ast/VertexType.sv b/grammars/silver/compiler/definition/flow/ast/VertexType.sv index 224c8e864..1c80e2821 100644 --- a/grammars/silver/compiler/definition/flow/ast/VertexType.sv +++ b/grammars/silver/compiler/definition/flow/ast/VertexType.sv @@ -8,12 +8,13 @@ grammar silver:compiler:definition:flow:ast; - forwardVertexType, anonVertexType(x) -} data nonterminal VertexType with - vertexName, vertexPP, + vertexName, vertexPP, isInhDefVertex, synVertex, inhVertex, fwdVertex, eqVertex; derive Eq, Ord on VertexType; synthesized attribute vertexName::String; synthesized attribute vertexPP::String; +synthesized attribute isInhDefVertex::Boolean; {-- FlowVertex for a synthesized attribute for this FlowVertex -} synthesized attribute synVertex :: (FlowVertex ::= String); @@ -41,6 +42,7 @@ top::VertexType ::= { top.vertexName = "top"; top.vertexPP = "left-hand side"; + top.isInhDefVertex = false; top.synVertex = lhsSynVertex; top.inhVertex = lhsInhVertex; top.fwdVertex = forwardEqVertex_singleton; @@ -55,6 +57,7 @@ top::VertexType ::= sigName::String { top.vertexName = sigName; top.vertexPP = "child " ++ sigName; + top.isInhDefVertex = true; top.synVertex = rhsSynVertex(sigName, _); top.inhVertex = rhsInhVertex(sigName, _); top.fwdVertex = rhsSynVertex(sigName, "forward"); @@ -69,6 +72,7 @@ top::VertexType ::= fName::String { top.vertexName = fName; top.vertexPP = "local " ++ fName; + top.isInhDefVertex = true; top.synVertex = localSynVertex(fName, _); top.inhVertex = localInhVertex(fName, _); top.fwdVertex = localSynVertex(fName, "forward"); @@ -83,6 +87,7 @@ top::VertexType ::= v::VertexType transAttr::String { top.vertexName = s"${v.vertexName}.${transAttr}"; top.vertexPP = s"translation attribute ${transAttr} of ${v.vertexPP}"; + top.isInhDefVertex = v.isInhDefVertex; top.synVertex = \ attr::String -> v.synVertex(s"${transAttr}.${attr}"); top.inhVertex = \ attr::String -> v.inhVertex(s"${transAttr}.${attr}"); top.fwdVertex = v.synVertex(s"${transAttr}.forward"); @@ -97,6 +102,7 @@ top::VertexType ::= { top.vertexName = "forward"; top.vertexPP = "forward"; + top.isInhDefVertex = false; top.synVertex = forwardSynVertex; top.inhVertex = forwardInhVertex; top.fwdVertex = forwardSynVertex("forward"); @@ -111,6 +117,7 @@ top::VertexType ::= x::String { top.vertexName = x; top.vertexPP = s"anonymous decoration site ${x}"; + top.isInhDefVertex = true; top.synVertex = anonSynVertex(x, _); top.inhVertex = anonInhVertex(x, _); top.fwdVertex = anonSynVertex(x, "forward"); @@ -125,6 +132,7 @@ top::VertexType ::= parent::VertexType prodName::String sigName::String { top.vertexName = s"${parent.vertexName}[${prodName}:${sigName}]"; top.vertexPP = top.vertexName; -- Shouldn't appear in error messages? Gets too long to spell out anyway. + top.isInhDefVertex = false; top.synVertex = subtermSynVertex(parent, prodName, sigName, _); top.inhVertex = subtermInhVertex(parent, prodName, sigName, _); top.fwdVertex = subtermSynVertex(parent, prodName, sigName, "forward"); diff --git a/grammars/silver/compiler/definition/flow/env/DecSites.sv b/grammars/silver/compiler/definition/flow/env/DecSites.sv index 731802c5d..7bc0c542a 100644 --- a/grammars/silver/compiler/definition/flow/env/DecSites.sv +++ b/grammars/silver/compiler/definition/flow/env/DecSites.sv @@ -63,12 +63,18 @@ top::DecSite ::= attrName::String d::DecSite fun foldAnyDecSite DecSite ::= ds::[DecSite] = case ds of | [d] -> d - | _ -> anyDecSite(flatMap(\ d -> case d of anyDecSite(ds1) -> ds1 | _ -> [d] end, ds)) + | _ -> anyDecSite(flatMap(\ d -> + case d of + | anyDecSite(ds1) -> ds1 + | allDecSite([]) -> [] + | _ -> [d] + end, ds)) end; fun foldAllDecSite DecSite ::= ds::[DecSite] = case ds of | [d] -> d + | _ when any(map(\ d -> case d of anyDecSite([]) -> true | _ -> false end, ds)) -> anyDecSite([]) | _ -> allDecSite(flatMap(\ d -> case d of allDecSite(ds1) -> ds1 | _ -> [d] end, ds)) end; @@ -102,19 +108,36 @@ function findDecSites if contains((prodName, vt), seen) then [] else - directDecSite(prodName, vt) :: + -- Direct inherited equation at a decoration site + (if vt.isInhDefVertex + then [directDecSite(prodName, vt)] + else []) ++ + -- Via forwarding case vt of | forwardVertexType_real() -> [forwardDecSite()] | localVertexType("forward") -> [forwardDecSite()] -- TODO: Not sure if this is actually possible? | localVertexType(fName) when isForwardProdAttr(fName, realEnv) -> [forwardDecSite()] | _ -> [] end ++ + -- Via direct sharing flatMap(recurse(prodName, _), lookupRefDecSite(prodName, vt, flowEnv)) ++ case vt of + | subtermVertexType(_, prodOrSig, sigName) -> + [foldAllDecSite( + map(foldAnyDecSite, + map(recurse(_, rhsVertexType(sigName)), + if !null(getValueDcl(prodOrSig, realEnv)) + then [prodOrSig] + else getImplementingProds(prodOrSig, flowEnv, realEnv))))] + | _ -> [] + end ++ + -- Via signature/dispatch sharing + case vt of | rhsVertexType(sigName) when lookupSignatureInputElem(sigName, ns).elementShared -> [foldAllDecSite(map(foldAnyDecSite, unzipWith(recurse, lookupAllSigShareSites(prodName, sigName, flowEnv, realEnv))))] | _ -> [] end ++ + -- Via translation attributes filterMap( \ attrName -> case getAttrDcl(attrName, realEnv) of diff --git a/grammars/silver/compiler/definition/flow/env/FlowEnv.sv b/grammars/silver/compiler/definition/flow/env/FlowEnv.sv index 51ac799fe..32bc55cfa 100644 --- a/grammars/silver/compiler/definition/flow/env/FlowEnv.sv +++ b/grammars/silver/compiler/definition/flow/env/FlowEnv.sv @@ -146,6 +146,19 @@ function getNonforwardingProds return map(extractProdName, searchEnvTree(nt, e.prodTree)); } +-- all (non-forwarding) productions implementing a dispatch signature +fun getImplementingProds [String] ::= sig::String e::FlowEnv realEnv::Env = + case getTypeDcl(sig, realEnv) of + | sigDcl :: _ -> + filter( + \p::String -> case getValueDcl(p, realEnv) of + | dcl :: _ when dcl.implementedSignature matches just(ns) -> ns.fullName == sig + | _ -> false + end, + getNonforwardingProds(sigDcl.dispatchSignature.outputElement.typerep.typeName, e)) + | _ -> error("Undefined dispatch sig " ++ sig) + end; + -- Ext Syns subject to ft lower bound function getHostSynsFor [String] ::= nt::String e::FlowEnv From 0a1a4f78d0f08c086673d0fd2f8c7d94ae8ba384 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 12 Apr 2024 14:07:49 -0500 Subject: [PATCH 224/283] Error message tweaks, fix propagate bug --- .../compiler/analysis/warnings/flow/Inh.sv | 16 +++++++++++----- .../compiler/extension/autoattr/Threaded.sv | 4 ++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index a88a3b3fd..eb2dc1eda 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -285,7 +285,7 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr else []; top.errors <- if top.config.warnMissingInh && dl.name == "forward" && !null(lhsInhExceedsForwardFlowType) - then [mwdaWrnFromOrigin(top, "Forward inherited equation exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsForwardFlowType))] + then [mwdaWrnFromOrigin(top, "Forward inherited equation for " ++ dl.inhAttrName ++ " exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsForwardFlowType))] else []; top.errors <- if top.config.warnMissingInh && !null(lhsInhExceedsRefDecSiteDeps) @@ -378,7 +378,7 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr if top.config.warnMissingInh then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ if dl.name != "forward" || null(lhsInhExceedsForwardFlowType) then [] - else [mwdaWrnFromOrigin(top, "Forward inherited equation exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsForwardFlowType))] + else [mwdaWrnFromOrigin(top, "Forward inherited equation for " ++ dl.inhAttrName ++ " exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsForwardFlowType))] else []; } aspect production inhAppendColAttributeDef @@ -404,7 +404,7 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr if top.config.warnMissingInh then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ if dl.name != "forward" || null(lhsInhExceedsForwardFlowType) then [] - else [mwdaWrnFromOrigin(top, "Forward inherited equation exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsForwardFlowType))] + else [mwdaWrnFromOrigin(top, "Forward inherited equation exceeds for " ++ dl.inhAttrName ++ " flow type with dependencies on " ++ implode(", ", lhsInhExceedsForwardFlowType))] else []; } ------ END AWFUL COPY & PASTE SESSION @@ -644,7 +644,10 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur let decSites::[DecSite] = findDecSites(top.frame.fullName, vt, [], top.flowEnv, top.env) in case filter(decSitesMissingInhEq(_, decSites, top.flowEnv), set:toList(inhDeps)) of | [] -> [] - | inhs -> [mwdaWrnFromOrigin(top, "Access of synthesized attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied to " ++ prettyDecSites(decSites))] + | inhs -> [mwdaWrnFromOrigin(top, + "Access of synthesized attribute " ++ q.name ++ " on " ++ e.unparse ++ + " requires missing inherited attribute(s) " ++ implode(", ", inhs) ++ + " to be supplied to " ++ prettyDecSites(decSites))] end end | _ -> [] @@ -752,7 +755,10 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur let decSites::[DecSite] = findDecSites(top.frame.fullName, vt, [], top.flowEnv, top.env) in case filter(decSitesMissingInhEq(_, decSites, top.flowEnv), set:toList(inhDeps)) of | [] -> [] - | inhs -> [mwdaWrnFromOrigin(top, "Access of translation attribute " ++ q.name ++ " on " ++ e.unparse ++ " requires missing inherited attributes " ++ implode(", ", inhs) ++ " to be supplied to " ++ prettyDecSites(decSites))] + | inhs -> [mwdaWrnFromOrigin(top, + "Access of translation attribute " ++ q.name ++ " on " ++ e.unparse ++ + " requires missing inherited attribute(s) " ++ implode(", ", inhs) ++ + " to be supplied to " ++ prettyDecSites(decSites))] end end | _ -> [] diff --git a/grammars/silver/compiler/extension/autoattr/Threaded.sv b/grammars/silver/compiler/extension/autoattr/Threaded.sv index 32615ca88..0c103ea1a 100644 --- a/grammars/silver/compiler/extension/autoattr/Threaded.sv +++ b/grammars/silver/compiler/extension/autoattr/Threaded.sv @@ -107,7 +107,7 @@ top::ProductionStmt ::= includeShared::Boolean @inh::QName isCol::Boolean rev::B (.elementName), filter( \ ie::NamedSignatureElement -> - isDecorable(ie.typerep, top.env) && + isDecorable(ie.elementDclType, top.env) && !null(getOccursDcl(inh.lookupAttribute.fullName, ie.typerep.typeName, top.env)) && !null(getOccursDcl(syn, ie.typerep.typeName, top.env)) && (includeShared || !ie.elementShared), @@ -138,7 +138,7 @@ top::ProductionStmt ::= includeShared::Boolean @syn::QName isCol::Boolean rev::B (.elementName), filter( \ ie::NamedSignatureElement -> - isDecorable(ie.typerep, top.env) && + isDecorable(ie.elementDclType, top.env) && !null(getOccursDcl(inh, ie.typerep.typeName, top.env)) && !null(getOccursDcl(syn.lookupAttribute.fullName, ie.typerep.typeName, top.env)) && (includeShared || !ie.elementShared), From 347a1d941115fabcb7b82d907f40198e0664047c Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 12 Apr 2024 14:10:43 -0500 Subject: [PATCH 225/283] Fix flow errors with implicit monad extension --- .../extension/implicit_monads/Expr.sv | 34 ++++++------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index 39108f3ae..2dca5bd43 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -9,7 +9,7 @@ inherited attribute monadicallyUsed::Boolean occurs on Expr; synthesized attribute monadicNames::[Expr] occurs on Expr, AppExpr, AppExprs, AnnoExpr, AnnoAppExprs; attribute monadRewritten, merrors, mtyperep, mDownSubst, mUpSubst, expectedMonad occurs on Expr; -propagate expectedMonad on Expr; +propagate @expectedMonad on Expr; type MonadInhs = { @@ -480,18 +480,6 @@ top::Expr ::= e::Expr '.' 'forward' top.monadRewritten = forwardAccess(ne.monadRewritten, '.', 'forward'); } -aspect production access -top::Expr ::= e::Expr '.' q::QNameAttrOccur -{ - propagate mDownSubst, mUpSubst, expectedMonad; -} - -aspect production accessBouncer -top::Expr ::= e::Expr @q::QNameAttrOccur target::Access -{ - propagate mDownSubst, mUpSubst, expectedMonad; -} - aspect production errorAccessHandler top::Expr ::= @e::Expr @q::QNameAttrOccur { @@ -554,7 +542,7 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur then q.typerep else monadOfType(top.expectedMonad, q.typerep) else q.typerep; - top.mUpSubst = top.mDownSubst; + propagate @mDownSubst, @mUpSubst; top.notExplicitAttributes <- e.notExplicitAttributes ++ if q.found @@ -615,7 +603,7 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur else monadOfType(top.expectedMonad, q.typerep) else q.typerep; - top.mUpSubst = top.mDownSubst; + propagate @mDownSubst, @mUpSubst; top.merrors := []; {- Note that we don't treat annotations as having a plicitness (restricted, @@ -673,7 +661,7 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur else monadOfType(top.expectedMonad, q.typerep) else q.typerep; - top.mUpSubst = top.mDownSubst; + propagate @mDownSubst, @mUpSubst; top.merrors := []; top.merrors <- case q.attrDcl of | restrictedSynDcl(_, _, _) -> [] @@ -702,7 +690,7 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur { top.merrors := e.merrors; - top.mUpSubst = top.mDownSubst; + propagate @mDownSubst, @mUpSubst; e.monadicallyUsed = false; --this needs to change when we decorate monadic trees top.monadicNames = if top.monadicallyUsed @@ -792,7 +780,7 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur else monadOfType(top.expectedMonad, q.typerep) else q.typerep; - top.mUpSubst = top.mDownSubst; + propagate @mDownSubst, @mUpSubst; top.merrors := e.merrors; top.merrors <- case q.attrDcl of | restrictedSynDcl(_, _, _) -> [] @@ -864,7 +852,7 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur else monadOfType(top.expectedMonad, q.typerep) else q.typerep; - top.mUpSubst = top.mDownSubst; + propagate @mDownSubst, @mUpSubst; top.merrors := e.merrors; top.merrors <- case q.attrDcl of | restrictedSynDcl(_, _, _) -> [] @@ -897,7 +885,7 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur then [access(e, '.', q)] ++ e.monadicNames else e.monadicNames; - propagate mDownSubst, mUpSubst; + propagate @mDownSubst, @mUpSubst; top.merrors := []; top.merrors <- case q.attrDcl of -- TODO: restricted translation attributes? @@ -1003,7 +991,7 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur "be either implicit or restricted; " ++ q.unparse ++ " is neither")] end; - top.mUpSubst = top.mDownSubst; + propagate @mDownSubst, @mUpSubst; top.notExplicitAttributes <- e.notExplicitAttributes ++ if q.found @@ -1024,7 +1012,7 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur then [access(e, '.', q)] ++ e.monadicNames else e.monadicNames; - propagate mDownSubst, mUpSubst; + propagate @mDownSubst, @mUpSubst; top.merrors := []; top.merrors <- case q.attrDcl of -- TODO: restricted translation attributes? @@ -1078,7 +1066,7 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur then [access(e, '.', q)] ++ e.monadicNames else e.monadicNames; - propagate mDownSubst, mUpSubst; + propagate @mDownSubst, @mUpSubst; top.merrors := []; top.merrors <- case q.attrDcl of -- TODO: restricted translation attributes? From 7a79b2ecb71fbf7e0c45d9842387f87589771d78 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 12 Apr 2024 15:25:27 -0500 Subject: [PATCH 226/283] Workaround some flow errors --- grammars/silver/compiler/translation/java/core/Expr.sv | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/grammars/silver/compiler/translation/java/core/Expr.sv b/grammars/silver/compiler/translation/java/core/Expr.sv index 489185ca2..7479fa20b 100644 --- a/grammars/silver/compiler/translation/java/core/Expr.sv +++ b/grammars/silver/compiler/translation/java/core/Expr.sv @@ -509,6 +509,10 @@ top::Expr ::= '@' e::Expr e.translation})"; top.lazyTranslation = wrapThunk(top.translation, top.frame.lazyApplication); + -- TODO: There isn't really a good place to put this. + -- We don't have a QNameAttrOccur, so we need to re-do all the work of looking up the occurs dcl, etc. + -- Currently we aren't resolving contexts! This uses attrGlobalOccursInitIndex, + -- which breaks if the occurs-on of the translation attr is defined as an occurs-on constraint. top.initTransDecSites <- case top.decSiteVertexInfo of | just(decSite) when top.alwaysDecorated -> @@ -517,7 +521,7 @@ top::Expr ::= '@' e::Expr case lookup(sigName, zip(top.frame.signature.inputNames, top.frame.signature.inputTypes)) of | just(ty) when getOccursDcl(transAttr, ty.typeName, top.env) matches occDcl :: _ -> s"\t\t// Decoration site for ${e.flowVertexInfo.fromJust.vertexPP}: ${decSite.vertexPP}\n" ++ - s"\t\t${top.frame.className}.childInheritedAttributes[${top.frame.className}.i_${sigName}][${occDcl.attrOccursInitIndex}_dec_site] = " ++ + s"\t\t${top.frame.className}.childInheritedAttributes[${top.frame.className}.i_${sigName}][${occDcl.attrGlobalOccursInitIndex}_dec_site] = " ++ s"(context) -> ${refAccessTranslation(top.env, top.flowEnv, top.frame.lhsNtName, decSite)};\n" | _ -> error("Couldn't find occurs dcl for " ++ transAttr ++ " on " ++ sigName) end @@ -525,7 +529,7 @@ top::Expr ::= '@' e::Expr case getValueDcl(fName, top.env) of | dcl :: _ when getOccursDcl(transAttr, dcl.typeScheme.typeName, top.env) matches occDcl :: _ -> s"\t\t// Decoration site for ${e.flowVertexInfo.fromJust.vertexPP}: ${decSite.vertexPP}\n" ++ - s"\t\t${top.frame.className}.localInheritedAttributes[${dcl.attrOccursIndex}][${occDcl.attrOccursInitIndex}_dec_site] = " ++ + s"\t\t${top.frame.className}.localInheritedAttributes[${dcl.attrOccursIndex}][${occDcl.attrGlobalOccursInitIndex}_dec_site] = " ++ s"(context) -> ${refAccessTranslation(top.env, top.flowEnv, top.frame.lhsNtName, decSite)};\n" | _ -> error("Couldn't find occurs dcl for " ++ transAttr ++ " on " ++ fName) end From e9d2835f6b83dde6665bae8bfe20bd8b815613b8 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 12 Apr 2024 15:51:04 -0500 Subject: [PATCH 227/283] Track dispatch impl prods in the flow env --- .../compiler/definition/flow/ast/Flow.sv | 26 +++++++++++++--- .../compiler/definition/flow/env/DecSites.sv | 2 +- .../compiler/definition/flow/env/FlowEnv.sv | 31 ++++++------------- .../definition/flow/env/ProductionDcl.sv | 8 +++++ 4 files changed, 40 insertions(+), 27 deletions(-) diff --git a/grammars/silver/compiler/definition/flow/ast/Flow.sv b/grammars/silver/compiler/definition/flow/ast/Flow.sv index aec5bb0f5..721bd6af5 100644 --- a/grammars/silver/compiler/definition/flow/ast/Flow.sv +++ b/grammars/silver/compiler/definition/flow/ast/Flow.sv @@ -43,7 +43,10 @@ monoid attribute localTreeContribs :: [(String, FlowDef)]; {-- lookup (nonterminal) to find all non-forwarding production. - ONLY used to determine all productions that need an equation for a new attribute. -} -monoid attribute prodTreeContribs :: [(String, FlowDef)]; +monoid attribute prodTreeContribs :: [(String, String)]; + +{-- lookup (dispatch) to find all host implementation productions. -} +monoid attribute implTreeContribs :: [(String, String)]; {-- find all equations having to do DIRECTLY with a production (directly meaning e.g. no default equations, even if they might @@ -77,13 +80,13 @@ monoid attribute sigShareContribs :: [(String, String, VertexType)]; attribute synTreeContribs, inhTreeContribs, defTreeContribs, - fwdTreeContribs, fwdInhTreeContribs, localInhTreeContribs, localTreeContribs, prodTreeContribs, + fwdTreeContribs, fwdInhTreeContribs, localInhTreeContribs, localTreeContribs, prodTreeContribs, implTreeContribs, prodGraphContribs, hostSynTreeContribs, nonSuspectContribs, refPossibleDecSiteContribs, refDecSiteContribs, sigShareContribs occurs on FlowDefs, FlowDef; propagate synTreeContribs, inhTreeContribs, defTreeContribs, - fwdTreeContribs, fwdInhTreeContribs, localInhTreeContribs, localTreeContribs, prodTreeContribs, + fwdTreeContribs, fwdInhTreeContribs, localInhTreeContribs, localTreeContribs, prodTreeContribs, implTreeContribs, prodGraphContribs, hostSynTreeContribs, nonSuspectContribs, refPossibleDecSiteContribs, refDecSiteContribs, sigShareContribs on FlowDefs; @@ -111,6 +114,7 @@ top::FlowDef ::= top.fwdTreeContribs := []; top.fwdInhTreeContribs := []; top.prodTreeContribs := []; + top.implTreeContribs := []; top.localInhTreeContribs := []; top.localTreeContribs := []; top.hostSynTreeContribs := []; @@ -132,7 +136,21 @@ top::FlowDef ::= abstract production prodFlowDef top::FlowDef ::= nt::String prod::String { - top.prodTreeContribs := [(nt, top)]; + top.prodTreeContribs := [(nt, prod)]; + top.prodGraphContribs := []; + top.flowEdges = error("Internal compiler error: this sort of def should not be in a context where edges are requested."); +} + +{-- + - Declaration of a host implementation production for a dispatch signature. + - + - @param dispatchSig The full name of the dispatch signature that is implemented + - @param prod The full name of the production + -} +abstract production implFlowDef +top::FlowDef ::= dispatchSig::String prod::String +{ + top.implTreeContribs := [(dispatchSig, prod)]; top.prodGraphContribs := []; top.flowEdges = error("Internal compiler error: this sort of def should not be in a context where edges are requested."); } diff --git a/grammars/silver/compiler/definition/flow/env/DecSites.sv b/grammars/silver/compiler/definition/flow/env/DecSites.sv index 7bc0c542a..6e34dd993 100644 --- a/grammars/silver/compiler/definition/flow/env/DecSites.sv +++ b/grammars/silver/compiler/definition/flow/env/DecSites.sv @@ -128,7 +128,7 @@ function findDecSites map(recurse(_, rhsVertexType(sigName)), if !null(getValueDcl(prodOrSig, realEnv)) then [prodOrSig] - else getImplementingProds(prodOrSig, flowEnv, realEnv))))] + else getImplementingProds(prodOrSig, flowEnv))))] | _ -> [] end ++ -- Via signature/dispatch sharing diff --git a/grammars/silver/compiler/definition/flow/env/FlowEnv.sv b/grammars/silver/compiler/definition/flow/env/FlowEnv.sv index 32bc55cfa..adab9d172 100644 --- a/grammars/silver/compiler/definition/flow/env/FlowEnv.sv +++ b/grammars/silver/compiler/definition/flow/env/FlowEnv.sv @@ -17,7 +17,7 @@ monoid attribute specDefs :: [(String, String, [String], [String])]; -- (nt, at monoid attribute refDefs :: [(String, [String])]; data nonterminal FlowEnv with - synTree, inhTree, defTree, fwdTree, prodTree, fwdInhTree, refTree, + synTree, inhTree, defTree, fwdTree, prodTree, implTree, fwdInhTree, refTree, sharedRefTree, refPossibleDecSiteTree, refDecSiteTree, sigShareTree, localInhTree, localTree, nonSuspectTree, hostSynTree, specTree, prodGraphTree; @@ -27,7 +27,8 @@ synthesized attribute inhTree :: EnvTree; synthesized attribute defTree :: EnvTree; synthesized attribute fwdTree :: EnvTree; synthesized attribute fwdInhTree :: EnvTree; -synthesized attribute prodTree :: EnvTree; +synthesized attribute prodTree :: EnvTree; +synthesized attribute implTree :: EnvTree; synthesized attribute refTree :: EnvTree<[String]>; synthesized attribute sharedRefTree :: EnvTree; synthesized attribute refPossibleDecSiteTree :: EnvTree; @@ -52,6 +53,7 @@ top::FlowEnv ::= top.fwdTree = directBuildTree(d.fwdTreeContribs); top.fwdInhTree = directBuildTree(d.fwdInhTreeContribs); top.prodTree = directBuildTree(d.prodTreeContribs); + top.implTree = directBuildTree(d.implTreeContribs); top.refTree = directBuildTree(refContribs); top.sharedRefTree = directBuildTree(sharedRefContribs); top.refPossibleDecSiteTree = directBuildTree(d.refPossibleDecSiteContribs); @@ -137,27 +139,12 @@ fun getNonSuspectAttrsForProd [String] ::= prod::String e::FlowEnv = concat(searchEnvTree(prod, e.nonSuspectTree)); -- all (non-forwarding) productions constructing a nonterminal -function getNonforwardingProds -[String] ::= nt::String e::FlowEnv -{ - local extractProdName :: (String ::= FlowDef) = - \p::FlowDef -> case p of prodFlowDef(_, p) -> p | _ -> error("Searches only prod defs") end; +fun getNonforwardingProds [String] ::= nt::String e::FlowEnv = + searchEnvTree(nt, e.prodTree); - return map(extractProdName, searchEnvTree(nt, e.prodTree)); -} - --- all (non-forwarding) productions implementing a dispatch signature -fun getImplementingProds [String] ::= sig::String e::FlowEnv realEnv::Env = - case getTypeDcl(sig, realEnv) of - | sigDcl :: _ -> - filter( - \p::String -> case getValueDcl(p, realEnv) of - | dcl :: _ when dcl.implementedSignature matches just(ns) -> ns.fullName == sig - | _ -> false - end, - getNonforwardingProds(sigDcl.dispatchSignature.outputElement.typerep.typeName, e)) - | _ -> error("Undefined dispatch sig " ++ sig) - end; +-- all host productions implementing a dispatch signature +fun getImplementingProds [String] ::= dispatchSig::String e::FlowEnv = + searchEnvTree(dispatchSig, e.implTree); -- Ext Syns subject to ft lower bound function getHostSynsFor diff --git a/grammars/silver/compiler/definition/flow/env/ProductionDcl.sv b/grammars/silver/compiler/definition/flow/env/ProductionDcl.sv index 9befa2116..1e7927ef1 100644 --- a/grammars/silver/compiler/definition/flow/env/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/flow/env/ProductionDcl.sv @@ -32,6 +32,14 @@ top::AGDcl ::= 'abstract' 'production' id::Name d::ProductionImplements ns::Prod then [prodFlowDef(namedSig.outputElement.typerep.typeName, fName)] else []; + top.flowDefs <- + case d.implementsSig of + | just(dSig) when + isExportedBy(top.grammarName, [implode(":", init(explode(":", dSig.fullName)))], top.compiledGrammars) -> + [implFlowDef(dSig.fullName, fName)] + | _ -> [] + end; + top.flowDefs <- flatMap( \ ie::NamedSignatureElement -> occursContextDeps(namedSig, body.env, ie.typerep, rhsVertexType(ie.elementName)), namedSig.inputElements); From eb1cdb21a06a53ff49f100069eebe34ef0b639a2 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 12 Apr 2024 16:33:00 -0500 Subject: [PATCH 228/283] Add check for sharing forward prod attributes in non-forward decoration contexts --- .../compiler/analysis/warnings/flow/Inh.sv | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index eb2dc1eda..fa8493d50 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -773,6 +773,26 @@ top::Expr ::= 'decorate' e::Expr 'with' '{' inh::ExprInhs '}' -- Do nothing. Everything gets taken care of with anonResolve and checkEqDeps at the top-level of the equation } +aspect production decorationSiteExpr +top::Expr ::= '@' e::Expr +{ + -- Sharing a forward production attribute somewhere that isn't already being decorated as the forward + -- may cause hidden transitive dependency issues for attributes we don't know about, so we forbid this. + top.errors <- + if top.config.warnMissingInh + then + case e.flowVertexInfo of + | just(localVertexType(fName)) when isForwardProdAttr(fName, top.env) -> + case top.decSiteVertexInfo of + | just(forwardVertexType_real()) -> [] + | just(localVertexType(dSiteFName)) when isForwardProdAttr(dSiteFName, top.env) -> [] + | _ -> [mwdaWrnFromOrigin(top, s"Forward production attribute ${fName} may only be shared in a forward decoration site")] + end + | _ -> [] + end + else []; +} + {-- - For pattern matching, we have an obligation to check: - 1. If we invented an anon vertex type for the scrutinee, then it's a sink, and From cef19ccda0ce3c33b7821756826269554f085fc4 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 12 Apr 2024 17:23:22 -0500 Subject: [PATCH 229/283] Permit ordinary flow projections through arbitrary dispatch application --- grammars/silver/compiler/definition/flow/env/Expr.sv | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index e95a03d24..5f27da6f3 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -208,7 +208,7 @@ top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { top.flowVertexInfo = top.decSiteVertexInfo; es.appProd = - case e, e.typerep of + case e, e.finalType of | productionReference(q), _ -> just(q.lookupValue.dcl.namedSignature) | _, dispatchType(ns) -> just(ns) | _, _ -> error("dispatchApplication: unexpected type") @@ -216,11 +216,7 @@ top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs es.appIndexOffset = 0; e.decSiteVertexInfo = top.decSiteVertexInfo; es.decSiteVertexInfo = top.decSiteVertexInfo; - es.alwaysDecorated = - case e of - | productionReference(q) -> top.alwaysDecorated - | _ -> false - end; + es.alwaysDecorated = top.alwaysDecorated; } aspect production annoExpr From 0ad44eb4e2005ab922389102a08a4ebe4004bff2 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 12 Apr 2024 17:23:57 -0500 Subject: [PATCH 230/283] Fix strategy attr occurs-on dcl to forward to a proper implementation prod --- .../compiler/definition/core/OccursDcl.sv | 15 ++++++++++ .../extension/strategyattr/Strategy.sv | 29 ++++++++----------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/grammars/silver/compiler/definition/core/OccursDcl.sv b/grammars/silver/compiler/definition/core/OccursDcl.sv index f69be4f21..0d57d6fbd 100644 --- a/grammars/silver/compiler/definition/core/OccursDcl.sv +++ b/grammars/silver/compiler/definition/core/OccursDcl.sv @@ -201,3 +201,18 @@ top::AGDcl ::= 'annotation' at::QName attl::BracketedOptTypeExprs 'occurs' 'on' forwards to attributionDcl('attribute', @at, @attl, $4, $5, @nt, @nttl, $8); } +-- Utility productions for extensions to inject extra declarations besides the occurs-on. +production extraDefaultAttributionDcl implements AttributionDcl +top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs extraDcls::AGDcl +{ + forwards to + appendAGDcl( + directDefaultAttributionDcl(@at, @attl, @nt, @nttl), + @extraDcls); +} +production directDefaultAttributionDcl +top::AGDcl ::= at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs +{ + at.env = top.env; + forwards to defaultAttributionDcl(at, @attl, @nt, @nttl); +} diff --git a/grammars/silver/compiler/extension/strategyattr/Strategy.sv b/grammars/silver/compiler/extension/strategyattr/Strategy.sv index afdc0ab11..71b68d903 100644 --- a/grammars/silver/compiler/extension/strategyattr/Strategy.sv +++ b/grammars/silver/compiler/extension/strategyattr/Strategy.sv @@ -58,7 +58,9 @@ top::AGDcl ::= isTotal::Boolean a::Name recVarNameEnv::[Pair] rec abstract production strategyAttributionDcl implements AttributionDcl top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedOptTypeExprs { - propagate grammarName, env, flowEnv; + attl.grammarName = top.grammarName; + attl.env = top.env; + attl.flowEnv = top.flowEnv; production attribute localErrors::[Message] with ++; localErrors := @@ -81,8 +83,14 @@ top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedO top.errors := if !null(localErrors) then localErrors else forward.errors; - local atOccursDcl::AGDcl = - defaultAttributionDcl( + forwards to + extraDefaultAttributionDcl( + foldr(appendAGDcl, emptyAGDcl(), + map( + \ n::String -> + attributionDcl( + 'attribute', qName(n), attl, 'occurs', 'on', nt, nttl, ';'), + at.lookupAttribute.dcl.liftedStrategyNames)))( at, botlSome( bTypeList( @@ -96,20 +104,7 @@ top::AGDcl ::= @at::QName attl::BracketedOptTypeExprs nt::QName nttl::BracketedO | botlNone() -> nominalTypeExpr(nt.qNameType) end), '>')), - nt, nttl); - - forwards to - if null(at.lookupAttribute.dcl.liftedStrategyNames) then @atOccursDcl - else - appendAGDcl( - @atOccursDcl, - foldr1( - appendAGDcl, - map( - \ n::String -> - attributionDcl( - 'attribute', qName(n), attl, 'occurs', 'on', nt, nttl, ';'), - at.lookupAttribute.dcl.liftedStrategyNames))); + @nt, @nttl); } {-- From cb7d546e07db1c7e85687e081c0687eee54733ed Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 15 Apr 2024 14:15:25 -0500 Subject: [PATCH 231/283] Revised representation of decoration sites as a decision tree, resolution via rewriting with strategy attributes --- .../compiler/analysis/warnings/flow/Inh.sv | 59 ++-- .../compiler/definition/flow/env/DecSites.sv | 274 ++++++++++++------ .../extension/strategyattr/StrategyExpr.sv | 1 + 3 files changed, 229 insertions(+), 105 deletions(-) diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index fa8493d50..6a66d69b8 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -129,11 +129,12 @@ fun checkAllEqDeps function checkInhEq [Message] ::= prodName::String vt::VertexType attrName::String config::Decorated CmdArgs flowEnv::FlowEnv realEnv::Env { - local decSites::[DecSite] = findDecSites(prodName, vt, [], flowEnv, realEnv); + local decSites::DecSiteTree = findDecSites(prodName, vt, [], flowEnv, realEnv); return - if decSitesMissingInhEq(attrName, decSites, flowEnv) - then [mwdaWrnAmbientOrigin(config, s"Equation requires inherited attribute ${attrName} be supplied to ${prettyDecSites(decSites)}")] - else []; + case resolveDecSiteInhEq(attrName, decSites, flowEnv) of + | alwaysDec() -> [] + | missing -> [mwdaWrnAmbientOrigin(config, s"Equation requires inherited attribute ${attrName} be supplied to ${prettyDecSites(missing)}")] + end; } {-- @@ -641,14 +642,18 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur | localVertexType(_) -> true | _ -> false end -> - let decSites::[DecSite] = findDecSites(top.frame.fullName, vt, [], top.flowEnv, top.env) in - case filter(decSitesMissingInhEq(_, decSites, top.flowEnv), set:toList(inhDeps)) of - | [] -> [] - | inhs -> [mwdaWrnFromOrigin(top, + case + decSitesMissingInhEqs( + set:toList(inhDeps), + findDecSites(top.frame.fullName, vt, [], top.flowEnv, top.env), + top.flowEnv) of + | [] -> [] + | missingEqs -> map(\ di::(DecSiteTree, [String]) -> + mwdaWrnFromOrigin(top, "Access of synthesized attribute " ++ q.name ++ " on " ++ e.unparse ++ - " requires missing inherited attribute(s) " ++ implode(", ", inhs) ++ - " to be supplied to " ++ prettyDecSites(decSites))] - end + " requires missing inherited attribute(s) " ++ implode(", ", di.2) ++ + " to be supplied to " ++ prettyDecSites(di.1)), + missingEqs) end | _ -> [] end @@ -752,14 +757,18 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur | localVertexType(_) -> true | _ -> false end -> - let decSites::[DecSite] = findDecSites(top.frame.fullName, vt, [], top.flowEnv, top.env) in - case filter(decSitesMissingInhEq(_, decSites, top.flowEnv), set:toList(inhDeps)) of - | [] -> [] - | inhs -> [mwdaWrnFromOrigin(top, + case + decSitesMissingInhEqs( + set:toList(inhDeps), + findDecSites(top.frame.fullName, vt, [], top.flowEnv, top.env), + top.flowEnv) of + | [] -> [] + | missingEqs -> map(\ di::(DecSiteTree, [String]) -> + mwdaWrnFromOrigin(top, "Access of translation attribute " ++ q.name ++ " on " ++ e.unparse ++ - " requires missing inherited attribute(s) " ++ implode(", ", inhs) ++ - " to be supplied to " ++ prettyDecSites(decSites))] - end + " requires missing inherited attribute(s) " ++ implode(", ", di.2) ++ + " to be supplied to " ++ prettyDecSites(di.1)), + missingEqs) end | _ -> [] end @@ -855,23 +864,25 @@ top::VarBinder ::= n::Name -- fName is our invented vertex name for the pattern variable local requiredInhs :: [String] = toAnonInhs(top.receivedDeps, fName); - local remoteDecSites :: [DecSite] = + local remoteDecSites :: DecSiteTree = findDecSites(top.matchingAgainst.fromJust.fullName, rhsVertexType(top.bindingName), [], top.flowEnv, top.env); -- Check for equation's existence: -- Prod: top.matchingAgainst.fromJust.fullName -- Child: top.bindingName -- Inh: each of requiredInhs - local missingInhs :: [String] = - filter(decSitesMissingInhEq(_, remoteDecSites, top.flowEnv), - removeAll(getMinRefSet(top.bindingType, top.env), requiredInhs)); + local missingInhEqs :: [(DecSiteTree, [String])] = + decSitesMissingInhEqs( + removeAll(getMinRefSet(top.bindingType, top.env), requiredInhs), + remoteDecSites, top.flowEnv); top.errors <- if top.config.warnMissingInh && isDecorable(top.bindingType, top.env) && top.matchingAgainst.isJust - && !null(missingInhs) - then [mwdaWrnFromOrigin(top, s"Pattern variable '${n.name}' has transitive dependencies with missing remote equations for ${implode(", ", missingInhs)}. These attributes must be supplied to ${prettyDecSites(remoteDecSites)}\n")] + then map(\ eqs::(DecSiteTree, [String]) -> + mwdaWrnFromOrigin(top, s"Pattern variable '${n.name}' has transitive dependencies with missing remote equations for ${implode(", ", eqs.2)}. These attributes must be supplied to ${prettyDecSites(eqs.1)}\n"), + missingInhEqs) else []; } diff --git a/grammars/silver/compiler/definition/flow/env/DecSites.sv b/grammars/silver/compiler/definition/flow/env/DecSites.sv index 6e34dd993..325565fb3 100644 --- a/grammars/silver/compiler/definition/flow/env/DecSites.sv +++ b/grammars/silver/compiler/definition/flow/env/DecSites.sv @@ -1,6 +1,6 @@ grammar silver:compiler:definition:flow:env; -import silver:util:treeset as set; +import silver:util:treemap as map; -- places where this child was decorated in a production forwarding to this one, -- or in a dispatch signature that this production implements @@ -16,76 +16,130 @@ fun lookupAllSigShareSites [(String, VertexType)] ::= prod::String sigName::Stri end; {-- - - Represents a tree of decoration sites where an equation might need to be supplied - - to ensure an inherited attribute is always present on some tree. + - Represents a decision tree of potential decoration sites to determine if an inherited attribute + - has been supplied for some vertex type. -} -data nonterminal DecSite with decSitePP; +nonterminal DecSiteTree with decSitePP, decSiteAlts, decSiteReqs; +flowtype DecSiteTree = decorate {}, forward {}; synthesized attribute decSitePP::String; +synthesized attribute decSiteAlts::[DecSiteTree]; +synthesized attribute decSiteReqs::[DecSiteTree]; + +aspect default production +top::DecSiteTree ::= +{ + top.decSiteAlts = [top]; + top.decSiteReqs = [top]; +} {-- - - An attribute is present if it is supplied by any of these sites. + - No attributes can be known to be supplied. + - Primarilly, denotes a cycle in decoration site resolution. + -} +production neverDec +top::DecSiteTree ::= +{ + top.decSitePP = "never"; + top.decSiteAlts = []; +} + +{- + - All attributes are known to be supplied. + - Can occur if a dispatch signature has no implementing productions, or in the search reduction process. -} -production anyDecSite -top::DecSite ::= ds::[DecSite] +production alwaysDec +top::DecSiteTree ::= { - top.decSitePP = implode(" | ", map((.decSitePP), ds)); + top.decSitePP = "always"; + top.decSiteReqs = []; } {-- - - An attribute is present if it is supplied by all of these sites. + - An attribute can be supplied by either of these sites. -} -production allDecSite -top::DecSite ::= ds::[DecSite] +production altDec +top::DecSiteTree ::= d1::DecSiteTree d2::DecSiteTree { - top.decSitePP = s"{${implode(", ", map((.decSitePP), ds))}}"; + top.decSitePP = implode(" | ", map((.decSitePP), top.decSiteAlts)); + top.decSiteAlts = d1.decSiteAlts ++ d2.decSiteAlts; } -production directDecSite -top::DecSite ::= prodName::String vt::VertexType +{-- + - An attribute is present if it is supplied by both of these sites. + -} +production bothDec +top::DecSiteTree ::= d1::DecSiteTree d2::DecSiteTree +{ + top.decSitePP = s"{${implode(", ", map((.decSitePP), top.decSiteReqs))}}"; + top.decSiteReqs = d1.decSiteReqs ++ d2.decSiteReqs; +} + +{-- + - An attribute can be supplied to a vertex type in some production. + -} +production directDec +top::DecSiteTree ::= prodName::String vt::VertexType { -- TODO: What if vt is an anonVertexType? top.decSitePP = s"${vt.vertexPP} of production ${prodName}"; } -production forwardDecSite -top::DecSite ::= +{-- + - An attribute can be supplied via forwarding. + - This does *not* include inherited attributes of translation attributes. + -} +production forwardDec +top::DecSiteTree ::= { top.decSitePP = "via forwarding"; } -production transAttrDecSite -top::DecSite ::= attrName::String d::DecSite +{-- + - An inherited attribute on a translation attribute can be supplied via a translation attribute. + -} +production transAttrDec +top::DecSiteTree ::= attrName::String d::DecSiteTree { top.decSitePP = s"via translation attribute ${attrName}: ${d.decSitePP}"; } -fun foldAnyDecSite DecSite ::= ds::[DecSite] = - case ds of - | [d] -> d - | _ -> anyDecSite(flatMap(\ d -> - case d of - | anyDecSite(ds1) -> ds1 - | allDecSite([]) -> [] - | _ -> [d] - end, ds)) - end; +fun foldAnyDecSite DecSiteTree ::= ds::[DecSiteTree] = + foldr(altDec, neverDec(), ds); -fun foldAllDecSite DecSite ::= ds::[DecSite] = - case ds of - | [d] -> d - | _ when any(map(\ d -> case d of anyDecSite([]) -> true | _ -> false end, ds)) -> anyDecSite([]) - | _ -> allDecSite(flatMap(\ d -> case d of allDecSite(ds1) -> ds1 | _ -> [d] end, ds)) - end; +fun foldAllDecSite DecSiteTree ::= ds::[DecSiteTree] = + foldr(bothDec, alwaysDec(), ds); -fun prettyDecSites String ::= ds::[DecSite] = - case ds of +fun prettyDecSites String ::= d::DecSiteTree = + case d.decSiteAlts of | [d] -> d.decSitePP - | _ -> "any of\n\t" ++ implode("\n\t", map((.decSitePP), ds)) + | ds -> "any of\n\t" ++ implode("\n\t", map((.decSitePP), ds)) end; +derive Eq, Ord on DecSiteTree; + +-- Semigroup/monoid instances for composing alternatives, since that more common that conjunction +instance Semigroup DecSiteTree { + append = altDec; +} + +instance Monoid DecSiteTree { + mempty = neverDec(); +} + +{-- + - Generate a decision tree to determine all decoration sites where an inherited equation could be supplied + - for it to be available on some vertex type. + - + - @param prodName The name of the production containing the vertex type. + - @param vt The vertex type to find decoration sites for. + - @param seen A list of (production name, vertex type) pairs that have already been visited. + - @param flowEnv The flow environment. + - @param realEnv The regular environment. + - @return A decision tree to determine if an inherited attributes has been supplied for vt. + -} function findDecSites -[DecSite] ::= prodName::String vt::VertexType seen::[(String, VertexType)] flowEnv::FlowEnv realEnv::Env +DecSiteTree ::= prodName::String vt::VertexType seen::[(String, VertexType)] flowEnv::FlowEnv realEnv::Env { local prodDcl :: [ValueDclInfo] = getValueDcl(prodName, realEnv); local ns :: NamedSignature = @@ -101,70 +155,128 @@ function findDecSites | _ -> "" end; - local recurse::([DecSite] ::= String VertexType) = + local recurse::(DecSiteTree ::= String VertexType) = findDecSites(_, _, (prodName, vt) :: seen, flowEnv, realEnv); return if contains((prodName, vt), seen) - then [] + then neverDec() else -- Direct inherited equation at a decoration site (if vt.isInhDefVertex - then [directDecSite(prodName, vt)] - else []) ++ + then directDec(prodName, vt) + else neverDec()) ++ -- Via forwarding case vt of - | forwardVertexType_real() -> [forwardDecSite()] - | localVertexType("forward") -> [forwardDecSite()] -- TODO: Not sure if this is actually possible? - | localVertexType(fName) when isForwardProdAttr(fName, realEnv) -> [forwardDecSite()] - | _ -> [] + | forwardVertexType_real() -> forwardDec() + | localVertexType("forward") -> forwardDec() -- TODO: Not sure if this is actually possible? + | localVertexType(fName) when isForwardProdAttr(fName, realEnv) -> forwardDec() + | _ -> neverDec() end ++ -- Via direct sharing - flatMap(recurse(prodName, _), lookupRefDecSite(prodName, vt, flowEnv)) ++ + foldAnyDecSite(map(recurse(prodName, _), lookupRefDecSite(prodName, vt, flowEnv))) ++ case vt of | subtermVertexType(_, prodOrSig, sigName) -> - [foldAllDecSite( - map(foldAnyDecSite, - map(recurse(_, rhsVertexType(sigName)), - if !null(getValueDcl(prodOrSig, realEnv)) - then [prodOrSig] - else getImplementingProds(prodOrSig, flowEnv))))] - | _ -> [] + foldAllDecSite( + map(recurse(_, rhsVertexType(sigName)), + if !null(getValueDcl(prodOrSig, realEnv)) + then [prodOrSig] + else getImplementingProds(prodOrSig, flowEnv))) + | _ -> neverDec() end ++ -- Via signature/dispatch sharing case vt of | rhsVertexType(sigName) when lookupSignatureInputElem(sigName, ns).elementShared -> - [foldAllDecSite(map(foldAnyDecSite, unzipWith(recurse, lookupAllSigShareSites(prodName, sigName, flowEnv, realEnv))))] - | _ -> [] + foldAllDecSite(unzipWith(recurse, lookupAllSigShareSites(prodName, sigName, flowEnv, realEnv))) + | _ -> neverDec() end ++ -- Via translation attributes - filterMap( - \ attrName -> - case getAttrDcl(attrName, realEnv) of - | dcl :: _ when dcl.isTranslation -> - just(transAttrDecSite(attrName, foldAnyDecSite(recurse(prodName, transAttrVertexType(vt, attrName))))) - | _ -> nothing() - end, - getHostSynsFor(ntName, flowEnv)); + foldAnyDecSite( + filterMap( + \ attrName -> + case getAttrDcl(attrName, realEnv) of + | dcl :: _ when dcl.isTranslation -> + just(transAttrDec(attrName, recurse(prodName, transAttrVertexType(vt, attrName)))) + | _ -> nothing() + end, + getHostSynsFor(ntName, flowEnv))); +} + +strategy attribute reduceDecSite = outermost( -- TODO: Is innermost more efficient here? + rule on DecSiteTree of + | altDec(alwaysDec(), d) -> alwaysDec() + | altDec(d, alwaysDec()) -> alwaysDec() + | altDec(neverDec(), d) -> d + | altDec(d, neverDec()) -> d + | bothDec(alwaysDec(), d) -> d + | bothDec(d, alwaysDec()) -> d + | bothDec(neverDec(), _) -> neverDec() + | bothDec(_, neverDec()) -> neverDec() + | altDec(altDec(d1, d2), d3) -> altDec(d1, altDec(d2, d3)) + | bothDec(bothDec(d1, d2), d3) -> bothDec(d1, bothDec(d2, d3)) + | altDec(d1, d2) when contains(d1, d2.decSiteAlts) -> d2 + | bothDec(d1, d2) when contains(d1, d2.decSiteReqs) -> d2 + | transAttrDec(attrName, neverDec()) -> neverDec() + -- This is assuming the we have already resolved for some inh-on-a-trans-attr that matches attrName. + | transAttrDec(attrName, alwaysDec()) -> alwaysDec() + end +) occurs on DecSiteTree; + +inherited attribute attrToResolve::String occurs on DecSiteTree; +propagate attrToResolve on DecSiteTree excluding transAttrDec; +aspect production transAttrDec +top::DecSiteTree ::= _ d::DecSiteTree +{ + d.attrToResolve = splitTransAttrInh(top.attrToResolve).fromJust.2; } -function decSiteHasInhEq -Boolean ::= d::DecSite attrName::String flowEnv::FlowEnv +attribute flowEnv occurs on DecSiteTree; +strategy attribute resolveDecSite = allTopDown( + rule on top::DecSiteTree of + | directDec(prodName, vt) + when vertexHasInhEq(prodName, vt, top.attrToResolve, top.flowEnv) -> + alwaysDec() + | forwardDec() -> + if splitTransAttrInh(top.attrToResolve).isJust + then neverDec() + else alwaysDec() + | transAttrDec(attrName, d) when + case splitTransAttrInh(top.attrToResolve) of + | just((transAttr, inhAttr)) -> transAttr != attrName + | _ -> true + end -> neverDec() + end +) <* reduceDecSite +occurs on DecSiteTree; + +propagate flowEnv, reduceDecSite, resolveDecSite on DecSiteTree; + +{-- + - Determine if some decoration site has some inherited attribute supplied. + - + - @param d The decoration site to check. + - @param attrName The name of the inherited attribute. + - @param flowEnv The flow environment. + - @return alwaysDec(), if the attribute is always present, + - or else the places where it could be supplied. + -} +function resolveDecSiteInhEq +DecSiteTree ::= attrName::String d::DecSiteTree flowEnv::FlowEnv { - local transInh::Maybe<(String, String)> = splitTransAttrInh(attrName); - return - case d of - | anyDecSite(ds) -> any(map(decSiteHasInhEq(_, attrName, flowEnv), ds)) - | allDecSite(ds) -> all(map(decSiteHasInhEq(_, attrName, flowEnv), ds)) - | directDecSite(prodName, vt) -> vertexHasInhEq(prodName, vt, attrName, flowEnv) - | forwardDecSite() -> !transInh.isJust - | transAttrDecSite(attrName, d) when transInh matches just((transAttr, inhAttr)) -> - decSiteHasInhEq(d, inhAttr, flowEnv) - | _ -> false - end; + d.attrToResolve = attrName; + d.flowEnv = flowEnv; + return d.resolveDecSite; } --- Helper for filtering -fun decSitesMissingInhEq -Boolean ::= attrName::String decSites::[DecSite] flowEnv::FlowEnv = - !any(map(decSiteHasInhEq(_, attrName, flowEnv), decSites)); +-- Helper for checking multiple inh attributes +fun decSitesMissingInhEqs +[(DecSiteTree, [String])] ::= attrNames::[String] d::DecSiteTree flowEnv::FlowEnv = + let resolved::map:Map = + map:add(map(\ a -> (resolveDecSiteInhEq(a, d, flowEnv), a), attrNames), map:empty()) + in flatMap(\ d -> + case map:lookup(d, resolved) of + | [] -> [] + | missing -> [(d, missing)] + end, + remove(alwaysDec(), map:keys(resolved))) + end; diff --git a/grammars/silver/compiler/extension/strategyattr/StrategyExpr.sv b/grammars/silver/compiler/extension/strategyattr/StrategyExpr.sv index 01403fe65..c86d53e0d 100644 --- a/grammars/silver/compiler/extension/strategyattr/StrategyExpr.sv +++ b/grammars/silver/compiler/extension/strategyattr/StrategyExpr.sv @@ -789,6 +789,7 @@ top::StrategyExpr ::= id::Name ty::TypeExpr ml::MRuleList else if top.frame.signature.outputElement.elementName == id.name then res else Silver_Expr { + -- TODO: Data NTs shouldn't be decorated. let $Name{id}::Decorated $TypeExpr{ty} = $name{top.frame.signature.outputElement.elementName} in $Expr{res} end From 3f6fba934b55713b12f66280efc99ad4990011de Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 16 Apr 2024 17:02:38 -0500 Subject: [PATCH 232/283] Updating test cases --- test/flow/OccursContext.sv | 6 +++--- test/flow/RefSiteProj.sv | 4 ++-- test/flow/References.sv | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/flow/OccursContext.sv b/test/flow/OccursContext.sv index b48002880..bbad5535c 100644 --- a/test/flow/OccursContext.sv +++ b/test/flow/OccursContext.sv @@ -19,7 +19,7 @@ Boolean ::= x::a y::a return x.isEqual; } -warnCode "Equation has transitive dependency on child x's inherited attribute for flow:env1 but this equation appears to be missing." { +warnCode "Equation requires inherited attribute flow:env1 be supplied to child x of production flow:isEqualBad" { function isEqualBad attribute compareTo occurs on a, attribute isEqual {compareTo, env1} occurs on a => @@ -105,7 +105,7 @@ top::Expr ::= x::a top.value = x.value; } -warnCode "Equation has transitive dependency on child x's inherited attribute for flow:env2 but this equation appears to be missing." { +warnCode "Access of synthesized attribute value on x requires missing inherited attribute(s) flow:env2 to be supplied to child x of production flow:valueThing1Bad" { production valueThing1Bad attribute env1 occurs on a, attribute value {env1, env2} occurs on a => @@ -128,7 +128,7 @@ top::Expr ::= x::a top.value = x.value; } -warnCode "Access of syn attribute value on x requires missing inherited attributes flow:env2 to be supplied" { +warnCode "Access of synthesized attribute value on x requires missing inherited attribute(s) flow:env2 to be supplied to child x of production flow:valueThing2Bad" { production valueThing2Bad attribute env1 occurs on a, attribute env2 occurs on a, diff --git a/test/flow/RefSiteProj.sv b/test/flow/RefSiteProj.sv index 7d7796c48..c31ec18e3 100644 --- a/test/flow/RefSiteProj.sv +++ b/test/flow/RefSiteProj.sv @@ -56,7 +56,7 @@ top::RSExpr ::= e::RSExpr forwards to copy1(@e); } -warnCode "missing remote equation" { +warnCode "child e of production flow:copy1" { production proj2Missing top::RSExpr ::= e::RSExpr { @@ -72,7 +72,7 @@ top::RSExpr ::= e::RSExpr forwards to copy12(@e); } -warnCode "missing remote equation" { +warnCode "Equation requires inherited attribute flow:env2 be supplied to child e of production flow:copy1" { production projNestedMissing top::RSExpr ::= e::RSExpr { diff --git a/test/flow/References.sv b/test/flow/References.sv index 8bb42d8b4..5f9a49796 100644 --- a/test/flow/References.sv +++ b/test/flow/References.sv @@ -24,7 +24,7 @@ Decorated Expr ::= x::Expr return x; } -warnCode "Equation has transitive dependency on child x's inherited attribute for flow:env1 but this equation appears to be missing." { +warnCode "Equation requires inherited attribute flow:env1 be supplied to child x of production flow:getRefEnv1Missing" { function getRefEnv1Missing Decorated Expr with {env1} ::= x::Expr { return x; } From d908e679995dd79bc44cd69b2a0cc0c415e01be7 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 16 Apr 2024 17:03:21 -0500 Subject: [PATCH 233/283] Still need to check inherited completeness subterm vertices only transitively depended upon --- grammars/silver/compiler/analysis/warnings/flow/Inh.sv | 7 +++---- .../silver/compiler/definition/flow/env/ProductionDcl.sv | 2 ++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index 6a66d69b8..f07925e33 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -115,10 +115,9 @@ function checkEqDeps else [] -- If it's not in the list, then it's a transitive dep from a DIFFERENT equation (and thus reported there) end | anonSynVertex(fName, attrName) -> [] - -- It's only possible to depend on a subterm inh vertex through sharing, - -- and we always check for missing inh on the remote prod if it's needed there. - -- No need to also report the error here. - | subtermInhVertex(parent, termProdName, sigName, attrName) -> [] + -- A dependency on a projected equation in another production. + | subtermInhVertex(parent, termProdName, sigName, attrName) -> + checkInhEq(prodName, subtermVertexType(parent, termProdName, sigName), attrName, config, flowEnv, realEnv) | subtermSynVertex(parent, termProdName, sigName, attrName) -> [] end; } diff --git a/grammars/silver/compiler/definition/flow/env/ProductionDcl.sv b/grammars/silver/compiler/definition/flow/env/ProductionDcl.sv index 1e7927ef1..630a713b3 100644 --- a/grammars/silver/compiler/definition/flow/env/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/flow/env/ProductionDcl.sv @@ -31,6 +31,8 @@ top::AGDcl ::= 'abstract' 'production' id::Name d::ProductionImplements ns::Prod if null(body.forwardExpr) then [prodFlowDef(namedSig.outputElement.typerep.typeName, fName)] else []; + + top.flowDefs <- case d.implementsSig of From 03c408e3a5c3a19c21c0c2362d8de0bda06e88d2 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 17 Apr 2024 09:40:43 -0500 Subject: [PATCH 234/283] Exclude impl prods that forward to the same dispatch sig from the set of host impl prods used in inherited completeness check --- .../definition/flow/env/ProductionDcl.sv | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/grammars/silver/compiler/definition/flow/env/ProductionDcl.sv b/grammars/silver/compiler/definition/flow/env/ProductionDcl.sv index 630a713b3..9f104dbd9 100644 --- a/grammars/silver/compiler/definition/flow/env/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/flow/env/ProductionDcl.sv @@ -32,12 +32,35 @@ top::AGDcl ::= 'abstract' 'production' id::Name d::ProductionImplements ns::Prod then [prodFlowDef(namedSig.outputElement.typerep.typeName, fName)] else []; - + -- Does this production forward to an application of the same dispatch signature + -- with the same shared children? + production forwardsToImplementedSig :: Boolean = + case d.implementsSig, body.forwardExpr of + | just(dSig), [dispatchApplication(e, es, emptyAnnoAppExprs())] + when e.typerep matches dispatchType(fwrdDSig) -> + dSig.fullName == fwrdDSig.fullName && + all(zipWith( + \ ie::NamedSignatureElement e::Decorated Expr -> + !ie.elementShared || + case e of + | childReference(q) -> + positionOf(q.lookupValue.fullName, namedSig.inputNames) == + positionOf(ie.elementName, dSig.inputNames) + | _ -> false + end, + dSig.inputElements, es.exprs)) + | _, _ -> false + end; top.flowDefs <- case d.implementsSig of | just(dSig) when - isExportedBy(top.grammarName, [implode(":", init(explode(":", dSig.fullName)))], top.compiledGrammars) -> + isExportedBy(top.grammarName, [implode(":", init(explode(":", dSig.fullName)))], top.compiledGrammars) && + -- Productions that forward to the same dispatch signature with the same shared children + -- cannot affect inherited completeness. + -- This is a potential circularity, as the prod could in principle forward to itself, + -- but not something we want to forbid. + !forwardsToImplementedSig -> [implFlowDef(dSig.fullName, fName)] | _ -> [] end; From 0597992ccc0b16043835a389036836665f0cf38a Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 17 Apr 2024 11:01:05 -0500 Subject: [PATCH 235/283] Change dec site tree reduction strategy to innermost for efficiency --- grammars/silver/compiler/definition/flow/env/DecSites.sv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/grammars/silver/compiler/definition/flow/env/DecSites.sv b/grammars/silver/compiler/definition/flow/env/DecSites.sv index 325565fb3..5f966ce9e 100644 --- a/grammars/silver/compiler/definition/flow/env/DecSites.sv +++ b/grammars/silver/compiler/definition/flow/env/DecSites.sv @@ -130,6 +130,7 @@ instance Monoid DecSiteTree { {-- - Generate a decision tree to determine all decoration sites where an inherited equation could be supplied - for it to be available on some vertex type. + - TODO should be cached in the flow environment. - - @param prodName The name of the production containing the vertex type. - @param vt The vertex type to find decoration sites for. @@ -202,7 +203,7 @@ DecSiteTree ::= prodName::String vt::VertexType seen::[(String, VertexType)] flo getHostSynsFor(ntName, flowEnv))); } -strategy attribute reduceDecSite = outermost( -- TODO: Is innermost more efficient here? +strategy attribute reduceDecSite = innermost( -- TODO: Avoid forcing the entire tree if the first dec site is supplied? rule on DecSiteTree of | altDec(alwaysDec(), d) -> alwaysDec() | altDec(d, alwaysDec()) -> alwaysDec() From a74e02e769cfd72b7cd15e70826cc02d37d043cb Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 17 Apr 2024 11:02:53 -0500 Subject: [PATCH 236/283] Don't introduce sharing eqs when the dec site lacks an inh equation, to avoid spurious decoration sites --- .../compiler/definition/flow/driver/ProductionGraph.sv | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv index 83a68d864..02f0f5d56 100644 --- a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv @@ -424,8 +424,14 @@ fun addDefEqs end -> filterMap( \ attr::String -> + -- There is an override equation, so the attribute isn't supplied through sharing if vertexHasInhEq(prod, ref, attr, flowEnv) - then nothing() -- There is an override equation, so the attribute isn't supplied through sharing + -- The sharing decoration site doesn't supply the attribute. + -- This will be a missing transitive dep error for ref, don't add the edge to avoid + -- an additional spurious error on decSite, which might be inaccurate if attr should + -- really have an equation on ref. + || resolveDecSiteInhEq(attr, findDecSites(prod, decSite, [], flowEnv, realEnv), flowEnv) != alwaysDec() + then nothing() else just((ref.inhVertex(attr), decSite.inhVertex(attr))), getInhAndInhOnTransAttrsOn(nt, realEnv)) | _ -> [] From b8d25b998d15f99bda8d947ceb3b18f9c2eaf410 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 17 Apr 2024 17:52:29 -0500 Subject: [PATCH 237/283] Refactoring and cleanup inh completeness site resolution --- .../compiler/analysis/warnings/flow/Inh.sv | 34 +--- .../definition/flow/ast/DecSiteTree.sv | 113 +++++++++++ .../compiler/definition/flow/ast/Flow.sv | 1 + .../definition/flow/driver/ProductionGraph.sv | 2 +- .../compiler/definition/flow/env/DecSites.sv | 181 ++++-------------- test/flow/RefSiteProj.sv | 4 +- 6 files changed, 166 insertions(+), 169 deletions(-) create mode 100644 grammars/silver/compiler/definition/flow/ast/DecSiteTree.sv diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index f07925e33..3615dcca6 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -125,16 +125,12 @@ fun checkAllEqDeps [Message] ::= v::[FlowVertex] config::Decorated CmdArgs prodName::String flowEnv::FlowEnv realEnv::Env anonResolve::[Pair] = flatMap(checkEqDeps(_, config, prodName, flowEnv, realEnv, anonResolve), v); -function checkInhEq -[Message] ::= prodName::String vt::VertexType attrName::String config::Decorated CmdArgs flowEnv::FlowEnv realEnv::Env -{ - local decSites::DecSiteTree = findDecSites(prodName, vt, [], flowEnv, realEnv); - return - case resolveDecSiteInhEq(attrName, decSites, flowEnv) of - | alwaysDec() -> [] - | missing -> [mwdaWrnAmbientOrigin(config, s"Equation requires inherited attribute ${attrName} be supplied to ${prettyDecSites(missing)}")] - end; -} +fun checkInhEq +[Message] ::= prodName::String vt::VertexType attrName::String config::Decorated CmdArgs flowEnv::FlowEnv realEnv::Env = + case resolveInhEq(prodName, vt, attrName, flowEnv, realEnv) of + | alwaysDec() -> [] + | missing -> [mwdaWrnAmbientOrigin(config, s"Equation requires inherited attribute ${attrName} be supplied to ${prettyDecSites(missing)}")] + end; {-- - Look up flow types, either from the flow environment (for a nonterminal) or the occurs-on contexts (for a type var). @@ -641,11 +637,7 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur | localVertexType(_) -> true | _ -> false end -> - case - decSitesMissingInhEqs( - set:toList(inhDeps), - findDecSites(top.frame.fullName, vt, [], top.flowEnv, top.env), - top.flowEnv) of + case decSitesMissingInhEqs(top.frame.fullName, vt, set:toList(inhDeps), top.flowEnv, top.env) of | [] -> [] | missingEqs -> map(\ di::(DecSiteTree, [String]) -> mwdaWrnFromOrigin(top, @@ -756,11 +748,7 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur | localVertexType(_) -> true | _ -> false end -> - case - decSitesMissingInhEqs( - set:toList(inhDeps), - findDecSites(top.frame.fullName, vt, [], top.flowEnv, top.env), - top.flowEnv) of + case decSitesMissingInhEqs(top.frame.fullName, vt, set:toList(inhDeps), top.flowEnv, top.env) of | [] -> [] | missingEqs -> map(\ di::(DecSiteTree, [String]) -> mwdaWrnFromOrigin(top, @@ -863,17 +851,15 @@ top::VarBinder ::= n::Name -- fName is our invented vertex name for the pattern variable local requiredInhs :: [String] = toAnonInhs(top.receivedDeps, fName); - local remoteDecSites :: DecSiteTree = - findDecSites(top.matchingAgainst.fromJust.fullName, rhsVertexType(top.bindingName), [], top.flowEnv, top.env); - -- Check for equation's existence: -- Prod: top.matchingAgainst.fromJust.fullName -- Child: top.bindingName -- Inh: each of requiredInhs local missingInhEqs :: [(DecSiteTree, [String])] = decSitesMissingInhEqs( + top.matchingAgainst.fromJust.fullName, rhsVertexType(top.bindingName), removeAll(getMinRefSet(top.bindingType, top.env), requiredInhs), - remoteDecSites, top.flowEnv); + top.flowEnv, top.env); top.errors <- if top.config.warnMissingInh diff --git a/grammars/silver/compiler/definition/flow/ast/DecSiteTree.sv b/grammars/silver/compiler/definition/flow/ast/DecSiteTree.sv new file mode 100644 index 000000000..9806a2b80 --- /dev/null +++ b/grammars/silver/compiler/definition/flow/ast/DecSiteTree.sv @@ -0,0 +1,113 @@ +grammar silver:compiler:definition:flow:ast; + +{-- + - Represents a decision tree of potential decoration sites to determine if an inherited attribute + - has been supplied for some vertex type. + -} +nonterminal DecSiteTree with decSitePP, decSiteAlts, decSiteReqs; +flowtype DecSiteTree = decorate {}, forward {}; + +synthesized attribute decSitePP::String; +synthesized attribute decSiteAlts::[DecSiteTree]; +synthesized attribute decSiteReqs::[DecSiteTree]; + +aspect default production +top::DecSiteTree ::= +{ + top.decSiteAlts = [top]; + top.decSiteReqs = [top]; +} + +{-- + - No attributes can be known to be supplied. + - Primarilly, denotes a cycle in decoration site resolution. + -} +production neverDec +top::DecSiteTree ::= +{ + top.decSitePP = "never"; + top.decSiteAlts = []; +} + +{- + - All attributes are known to be supplied. + - Can occur if a dispatch signature has no implementing productions, or in the search reduction process. + -} +production alwaysDec +top::DecSiteTree ::= +{ + top.decSitePP = "always"; + top.decSiteReqs = []; +} + +{-- + - An attribute can be supplied by either of these sites. + -} +production altDec +top::DecSiteTree ::= d1::DecSiteTree d2::DecSiteTree +{ + top.decSitePP = implode(" | ", map((.decSitePP), top.decSiteAlts)); + top.decSiteAlts = d1.decSiteAlts ++ d2.decSiteAlts; +} + +{-- + - An attribute is present if it is supplied by both of these sites. + -} +production bothDec +top::DecSiteTree ::= d1::DecSiteTree d2::DecSiteTree +{ + top.decSitePP = s"{${implode(", ", map((.decSitePP), top.decSiteReqs))}}"; + top.decSiteReqs = d1.decSiteReqs ++ d2.decSiteReqs; +} + +{-- + - An attribute can be supplied to a vertex type in some production. + -} +production directDec +top::DecSiteTree ::= prodName::String vt::VertexType +{ + -- TODO: What if vt is an anonVertexType? + top.decSitePP = s"${vt.vertexPP} of production ${prodName}"; +} + +{-- + - An attribute can be supplied via forwarding. + - This does *not* include inherited attributes of translation attributes. + -} +production forwardDec +top::DecSiteTree ::= +{ + top.decSitePP = "via forwarding"; +} + +{-- + - An inherited attribute on a translation attribute can be supplied via a translation attribute. + -} +production transAttrDec +top::DecSiteTree ::= attrName::String d::DecSiteTree +{ + top.decSitePP = s"via translation attribute ${attrName}: ${d.decSitePP}"; +} + +fun foldAnyDecSite DecSiteTree ::= ds::[DecSiteTree] = + foldr(altDec, neverDec(), ds); + +fun foldAllDecSite DecSiteTree ::= ds::[DecSiteTree] = + foldr(bothDec, alwaysDec(), ds); + +fun prettyDecSites String ::= d::DecSiteTree = + case d.decSiteAlts of + | [d] -> d.decSitePP + | ds -> "any of\n\t" ++ implode("\n\t", map((.decSitePP), ds)) + end; + +derive Eq, Ord on DecSiteTree; + +-- Semigroup/monoid instances for composing alternatives, since that more common that conjunction +instance Semigroup DecSiteTree { + append = altDec; +} + +instance Monoid DecSiteTree { + mempty = neverDec(); +} \ No newline at end of file diff --git a/grammars/silver/compiler/definition/flow/ast/Flow.sv b/grammars/silver/compiler/definition/flow/ast/Flow.sv index 721bd6af5..f99e91c03 100644 --- a/grammars/silver/compiler/definition/flow/ast/Flow.sv +++ b/grammars/silver/compiler/definition/flow/ast/Flow.sv @@ -76,6 +76,7 @@ monoid attribute refPossibleDecSiteContribs :: [(String, VertexType)]; {-- lookup dec site to find places that a unique reference to this ref site are *unconditionally* decorated. -} monoid attribute refDecSiteContribs :: [(String, VertexType)]; +{-- lookup (prod, sig) to find source production and vertex type where sig was previously decorated -} monoid attribute sigShareContribs :: [(String, String, VertexType)]; attribute diff --git a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv index 02f0f5d56..7e2afa13f 100644 --- a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv @@ -430,7 +430,7 @@ fun addDefEqs -- This will be a missing transitive dep error for ref, don't add the edge to avoid -- an additional spurious error on decSite, which might be inaccurate if attr should -- really have an equation on ref. - || resolveDecSiteInhEq(attr, findDecSites(prod, decSite, [], flowEnv, realEnv), flowEnv) != alwaysDec() + || resolveInhEq(prod, decSite, attr, flowEnv, realEnv) != alwaysDec() then nothing() else just((ref.inhVertex(attr), decSite.inhVertex(attr))), getInhAndInhOnTransAttrsOn(nt, realEnv)) diff --git a/grammars/silver/compiler/definition/flow/env/DecSites.sv b/grammars/silver/compiler/definition/flow/env/DecSites.sv index 5f966ce9e..6017de09e 100644 --- a/grammars/silver/compiler/definition/flow/env/DecSites.sv +++ b/grammars/silver/compiler/definition/flow/env/DecSites.sv @@ -2,131 +2,6 @@ grammar silver:compiler:definition:flow:env; import silver:util:treemap as map; --- places where this child was decorated in a production forwarding to this one, --- or in a dispatch signature that this production implements -fun lookupAllSigShareSites [(String, VertexType)] ::= prod::String sigName::String e::FlowEnv realEnv::Env = - lookupSigShareSites(prod, sigName, e) ++ - case getValueDcl(prod, realEnv) of - | dcl :: _ when dcl.implementedSignature matches just(sig) -> - lookupSigShareSites( - sig.fullName, - head(drop(positionOf(sigName, dcl.namedSignature.inputNames), sig.inputNames)), - e) - | _ -> [] - end; - -{-- - - Represents a decision tree of potential decoration sites to determine if an inherited attribute - - has been supplied for some vertex type. - -} -nonterminal DecSiteTree with decSitePP, decSiteAlts, decSiteReqs; -flowtype DecSiteTree = decorate {}, forward {}; - -synthesized attribute decSitePP::String; -synthesized attribute decSiteAlts::[DecSiteTree]; -synthesized attribute decSiteReqs::[DecSiteTree]; - -aspect default production -top::DecSiteTree ::= -{ - top.decSiteAlts = [top]; - top.decSiteReqs = [top]; -} - -{-- - - No attributes can be known to be supplied. - - Primarilly, denotes a cycle in decoration site resolution. - -} -production neverDec -top::DecSiteTree ::= -{ - top.decSitePP = "never"; - top.decSiteAlts = []; -} - -{- - - All attributes are known to be supplied. - - Can occur if a dispatch signature has no implementing productions, or in the search reduction process. - -} -production alwaysDec -top::DecSiteTree ::= -{ - top.decSitePP = "always"; - top.decSiteReqs = []; -} - -{-- - - An attribute can be supplied by either of these sites. - -} -production altDec -top::DecSiteTree ::= d1::DecSiteTree d2::DecSiteTree -{ - top.decSitePP = implode(" | ", map((.decSitePP), top.decSiteAlts)); - top.decSiteAlts = d1.decSiteAlts ++ d2.decSiteAlts; -} - -{-- - - An attribute is present if it is supplied by both of these sites. - -} -production bothDec -top::DecSiteTree ::= d1::DecSiteTree d2::DecSiteTree -{ - top.decSitePP = s"{${implode(", ", map((.decSitePP), top.decSiteReqs))}}"; - top.decSiteReqs = d1.decSiteReqs ++ d2.decSiteReqs; -} - -{-- - - An attribute can be supplied to a vertex type in some production. - -} -production directDec -top::DecSiteTree ::= prodName::String vt::VertexType -{ - -- TODO: What if vt is an anonVertexType? - top.decSitePP = s"${vt.vertexPP} of production ${prodName}"; -} - -{-- - - An attribute can be supplied via forwarding. - - This does *not* include inherited attributes of translation attributes. - -} -production forwardDec -top::DecSiteTree ::= -{ - top.decSitePP = "via forwarding"; -} - -{-- - - An inherited attribute on a translation attribute can be supplied via a translation attribute. - -} -production transAttrDec -top::DecSiteTree ::= attrName::String d::DecSiteTree -{ - top.decSitePP = s"via translation attribute ${attrName}: ${d.decSitePP}"; -} - -fun foldAnyDecSite DecSiteTree ::= ds::[DecSiteTree] = - foldr(altDec, neverDec(), ds); - -fun foldAllDecSite DecSiteTree ::= ds::[DecSiteTree] = - foldr(bothDec, alwaysDec(), ds); - -fun prettyDecSites String ::= d::DecSiteTree = - case d.decSiteAlts of - | [d] -> d.decSitePP - | ds -> "any of\n\t" ++ implode("\n\t", map((.decSitePP), ds)) - end; - -derive Eq, Ord on DecSiteTree; - --- Semigroup/monoid instances for composing alternatives, since that more common that conjunction -instance Semigroup DecSiteTree { - append = altDec; -} - -instance Monoid DecSiteTree { - mempty = neverDec(); -} - {-- - Generate a decision tree to determine all decoration sites where an inherited equation could be supplied - for it to be available on some vertex type. @@ -167,30 +42,36 @@ DecSiteTree ::= prodName::String vt::VertexType seen::[(String, VertexType)] flo (if vt.isInhDefVertex then directDec(prodName, vt) else neverDec()) ++ - -- Via forwarding case vt of + -- Via forwarding | forwardVertexType_real() -> forwardDec() | localVertexType("forward") -> forwardDec() -- TODO: Not sure if this is actually possible? | localVertexType(fName) when isForwardProdAttr(fName, realEnv) -> forwardDec() - | _ -> neverDec() - end ++ - -- Via direct sharing - foldAnyDecSite(map(recurse(prodName, _), lookupRefDecSite(prodName, vt, flowEnv))) ++ - case vt of + -- Via projected remote equation | subtermVertexType(_, prodOrSig, sigName) -> foldAllDecSite( map(recurse(_, rhsVertexType(sigName)), if !null(getValueDcl(prodOrSig, realEnv)) then [prodOrSig] else getImplementingProds(prodOrSig, flowEnv))) - | _ -> neverDec() - end ++ -- Via signature/dispatch sharing - case vt of | rhsVertexType(sigName) when lookupSignatureInputElem(sigName, ns).elementShared -> - foldAllDecSite(unzipWith(recurse, lookupAllSigShareSites(prodName, sigName, flowEnv, realEnv))) + foldAllDecSite(unzipWith(recurse, + -- places where this child was decorated in a production forwarding to this one + lookupSigShareSites(prodName, sigName, flowEnv) ++ + -- or in a dispatch signature that this production implements + case getValueDcl(prodName, realEnv) of + | dcl :: _ when dcl.implementedSignature matches just(sig) -> + lookupSigShareSites( + sig.fullName, + head(drop(positionOf(sigName, dcl.namedSignature.inputNames), sig.inputNames)), + flowEnv) + | _ -> [] + end)) | _ -> neverDec() end ++ + -- Via direct sharing + foldAnyDecSite(map(recurse(prodName, _), lookupRefDecSite(prodName, vt, flowEnv))) ++ -- Via translation attributes foldAnyDecSite( filterMap( @@ -269,15 +150,31 @@ DecSiteTree ::= attrName::String d::DecSiteTree flowEnv::FlowEnv return d.resolveDecSite; } +{-- + - Determine if some flow vertex type in a production has some inherited attribute supplied. + - + - @param prodName The name of the production containing the vertex. + - @param vt The vertex type to check. + - @param attrName The name of the inherited attribute. + - @param flowEnv The flow environment. + - @return alwaysDec(), if the attribute is always present, + - or else the places where it could be supplied. + -} +fun resolveInhEq +DecSiteTree ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv realEnv::Env = + resolveDecSiteInhEq(attrName, findDecSites(prodName, vt, [], flowEnv, realEnv), flowEnv); + -- Helper for checking multiple inh attributes -fun decSitesMissingInhEqs -[(DecSiteTree, [String])] ::= attrNames::[String] d::DecSiteTree flowEnv::FlowEnv = - let resolved::map:Map = - map:add(map(\ a -> (resolveDecSiteInhEq(a, d, flowEnv), a), attrNames), map:empty()) - in flatMap(\ d -> +function decSitesMissingInhEqs +[(DecSiteTree, [String])] ::= prodName::String vt::VertexType attrNames::[String] flowEnv::FlowEnv realEnv::Env +{ + local d::DecSiteTree = findDecSites(prodName, vt, [], flowEnv, realEnv); + local resolved::map:Map = + map:add(map(\ a -> (resolveDecSiteInhEq(a, d, flowEnv), a), attrNames), map:empty()); + return flatMap(\ d -> case map:lookup(d, resolved) of | [] -> [] | missing -> [(d, missing)] end, - remove(alwaysDec(), map:keys(resolved))) - end; + remove(alwaysDec(), map:keys(resolved))); +} diff --git a/test/flow/RefSiteProj.sv b/test/flow/RefSiteProj.sv index c31ec18e3..c771660aa 100644 --- a/test/flow/RefSiteProj.sv +++ b/test/flow/RefSiteProj.sv @@ -94,7 +94,7 @@ top::RSExpr ::= e::RSExpr top.errors2 = false; } -warnCode "missing remote equation" { +warnCode "child e of production flow:copy1" { production projNestedLocalsMissing top::RSExpr ::= e::RSExpr { @@ -131,7 +131,7 @@ production incrementalDec top::RSExpr ::= e::RSExpr { e.env1 = top.env1; - local e1::Expr = @e; + local e1::RSExpr = @e; e1.env2 = top.env2; top.errors1 = e1.errors1; From 441a02981b463f6e3d50f77fc7e8b815a0a50ab5 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 17 Apr 2024 18:40:29 -0500 Subject: [PATCH 238/283] Optimizing dec site tree construction during sharing eq computation --- .../definition/flow/driver/ProductionGraph.sv | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv index 7e2afa13f..f8debc58d 100644 --- a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv @@ -417,23 +417,26 @@ fun addDefEqs -} fun addSharingEqs [(FlowVertex, FlowVertex)] ::= flowEnv::FlowEnv realEnv::Env d::FlowDef = case d of - | refDecSiteEq(prod, nt, ref, decSite, _) when + | refDecSiteEq(prod, nt, ref, decSite, isAlwaysDec) when case ref of | localVertexType(fName) -> !isForwardProdAttr(fName, realEnv) | _ -> true end -> - filterMap( + let decSiteTree::DecSiteTree = findDecSites(prod, decSite, [], flowEnv, realEnv) + in filterMap( \ attr::String -> -- There is an override equation, so the attribute isn't supplied through sharing if vertexHasInhEq(prod, ref, attr, flowEnv) - -- The sharing decoration site doesn't supply the attribute. + -- The sharing decoration site fails to supply the attribute. -- This will be a missing transitive dep error for ref, don't add the edge to avoid -- an additional spurious error on decSite, which might be inaccurate if attr should -- really have an equation on ref. - || resolveInhEq(prod, decSite, attr, flowEnv, realEnv) != alwaysDec() + || isAlwaysDec && + resolveDecSiteInhEq(attr, decSiteTree, flowEnv) != alwaysDec() then nothing() else just((ref.inhVertex(attr), decSite.inhVertex(attr))), getInhAndInhOnTransAttrsOn(nt, realEnv)) + end | _ -> [] end; From 3f36509689010b6deb1fcc3383c68bdfd77b6037 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 17 Apr 2024 18:52:02 -0500 Subject: [PATCH 239/283] Another slight optimization --- .../silver/compiler/definition/flow/driver/ProductionGraph.sv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv index f8debc58d..3d8f00cf1 100644 --- a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv @@ -422,7 +422,8 @@ fun addDefEqs | localVertexType(fName) -> !isForwardProdAttr(fName, realEnv) | _ -> true end -> - let decSiteTree::DecSiteTree = findDecSites(prod, decSite, [], flowEnv, realEnv) + let decSiteTree::DecSiteTree = + findDecSites(prod, decSite, [(prod, ref)], flowEnv, realEnv) in filterMap( \ attr::String -> -- There is an override equation, so the attribute isn't supplied through sharing From d28f2164261cd0287844362988e02f0982f1bf5b Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 18 Apr 2024 10:53:56 -0500 Subject: [PATCH 240/283] Optimization - check for a direct equation in the dec site before searching the tree when deciding not to add a sharing eq --- .../silver/compiler/definition/flow/driver/ProductionGraph.sv | 2 ++ 1 file changed, 2 insertions(+) diff --git a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv index 3d8f00cf1..5c78e5b27 100644 --- a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv @@ -433,6 +433,8 @@ fun addDefEqs -- an additional spurious error on decSite, which might be inaccurate if attr should -- really have an equation on ref. || isAlwaysDec && + -- Optimization: check for a direct equation on the decSite before building the tree + !vertexHasInhEq(prod, decSite, attr, flowEnv) && resolveDecSiteInhEq(attr, decSiteTree, flowEnv) != alwaysDec() then nothing() else just((ref.inhVertex(attr), decSite.inhVertex(attr))), From 35444292d228a7ab5bfef844b3e9029554a4c796 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 18 Apr 2024 11:27:41 -0500 Subject: [PATCH 241/283] More tweaks to tests and error messages --- .../silver/compiler/analysis/warnings/flow/Inh.sv | 15 +++++++++++++-- test/flow/RefSiteProj.sv | 4 ++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index 3615dcca6..f8d31292a 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -66,6 +66,7 @@ Either ::= args::[String] - @param prodNt The nonterminal this production belongs to. (For functions, a dummy value is ok) - @param flowEnv The local flow environment - @param realEnv The local real environment + - @param anonResolve A list of anonymous decoration sites - @returns Errors for missing equations -} function checkEqDeps @@ -283,20 +284,30 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr if top.config.warnMissingInh && dl.name == "forward" && !null(lhsInhExceedsForwardFlowType) then [mwdaWrnFromOrigin(top, "Forward inherited equation for " ++ dl.inhAttrName ++ " exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsForwardFlowType))] else []; + local refDecSiteInhDepsLhsInhStr::String = + case set:toList(refDecSiteInhDepsLhsInh.fromJust) of + | [] -> "on no attributes" + | deps -> "only on " ++ implode(", ", deps) + end; top.errors <- if top.config.warnMissingInh && !null(lhsInhExceedsRefDecSiteDeps) then [mwdaWrnFromOrigin(top, s"Inherited override equation may exceed a flow type with hidden transitive dependencies on ${implode(", ", lhsInhExceedsRefDecSiteDeps)}; " ++ - s"${attr.attrDcl.fullName} on some reference to ${dl.defLHSVertex.vertexPP} may be expected to depend only on ${implode(", ", set:toList(refDecSiteInhDepsLhsInh.fromJust))}")] + s"${attr.attrDcl.fullName} on some reference to ${dl.defLHSVertex.vertexPP} may be expected to depend ${refDecSiteInhDepsLhsInhStr}")] else []; + local transBaseRefDecSiteInhDepsLhsInhStr::String = + case set:toList(transBaseRefDecSiteInhDepsLhsInh.fromJust) of + | [] -> "on no attributes" + | deps -> "only on " ++ implode(", ", deps) + end; top.errors <- case dl.defLHSVertex of | transAttrVertexType(v, transAttr) when top.config.warnMissingInh && !null(lhsInhExceedsTransBaseRefDecSiteDeps) -> [mwdaWrnFromOrigin(top, s"Inherited override equation may exceed a flow type with hidden transitive dependencies on ${implode(", ", lhsInhExceedsTransBaseRefDecSiteDeps)}; " ++ - s"${transAttr}.${attr.attrDcl.fullName} on some reference to ${v.vertexPP} may be expected to depend only on ${implode(", ", set:toList(transBaseRefDecSiteInhDepsLhsInh.fromJust))}")] + s"${transAttr}.${attr.attrDcl.fullName} on some reference to ${v.vertexPP} may be expected to depend ${transBaseRefDecSiteInhDepsLhsInhStr}")] | _ -> [] end; } diff --git a/test/flow/RefSiteProj.sv b/test/flow/RefSiteProj.sv index c771660aa..886d1bf30 100644 --- a/test/flow/RefSiteProj.sv +++ b/test/flow/RefSiteProj.sv @@ -269,7 +269,7 @@ top::RSExpr ::= e::RSExpr forwards to implProdRef(e); } -warnCode "Access of syn attribute errors2 on e requires missing inherited attributes flow:env2 to be supplied" { +warnCode "Access of synthesized attribute errors2 on e requires missing inherited attribute(s) flow:env2 to be supplied to child e of production flow:anonDecSuppliedMissing" { production anonDecSuppliedMissing top::RSExpr ::= e::RSExpr { @@ -316,7 +316,7 @@ top::RSExpr ::= e::RSExpr forwards to projChain(@e); } -warnCode "missing remote equation" { +warnCode "child e of production flow:copy1" { production projChain2Missing top::RSExpr ::= e::RSExpr { From 0c22561f7fd0ddaa64d38dc0ca9d4c93492ce08d Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 18 Apr 2024 14:36:42 -0500 Subject: [PATCH 242/283] Another optimization, use treeset to track explored vertices in building dec site tree --- .../definition/flow/driver/ProductionGraph.sv | 4 +--- .../compiler/definition/flow/env/DecSites.sv | 14 +++++++------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv index 5c78e5b27..ecbce659a 100644 --- a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv @@ -423,7 +423,7 @@ fun addDefEqs | _ -> true end -> let decSiteTree::DecSiteTree = - findDecSites(prod, decSite, [(prod, ref)], flowEnv, realEnv) + findDecSites(prod, decSite, set:fromList([crossnames(prod, ref.vertexName)]), flowEnv, realEnv) in filterMap( \ attr::String -> -- There is an override equation, so the attribute isn't supplied through sharing @@ -433,8 +433,6 @@ fun addDefEqs -- an additional spurious error on decSite, which might be inaccurate if attr should -- really have an equation on ref. || isAlwaysDec && - -- Optimization: check for a direct equation on the decSite before building the tree - !vertexHasInhEq(prod, decSite, attr, flowEnv) && resolveDecSiteInhEq(attr, decSiteTree, flowEnv) != alwaysDec() then nothing() else just((ref.inhVertex(attr), decSite.inhVertex(attr))), diff --git a/grammars/silver/compiler/definition/flow/env/DecSites.sv b/grammars/silver/compiler/definition/flow/env/DecSites.sv index 6017de09e..7e2aa00ce 100644 --- a/grammars/silver/compiler/definition/flow/env/DecSites.sv +++ b/grammars/silver/compiler/definition/flow/env/DecSites.sv @@ -1,21 +1,21 @@ grammar silver:compiler:definition:flow:env; import silver:util:treemap as map; +import silver:util:treeset as set; {-- - Generate a decision tree to determine all decoration sites where an inherited equation could be supplied - for it to be available on some vertex type. - - TODO should be cached in the flow environment. - - @param prodName The name of the production containing the vertex type. - @param vt The vertex type to find decoration sites for. - - @param seen A list of (production name, vertex type) pairs that have already been visited. + - @param seen A set of (production name, vertex type) that have already been visited. - @param flowEnv The flow environment. - @param realEnv The regular environment. - @return A decision tree to determine if an inherited attributes has been supplied for vt. -} function findDecSites -DecSiteTree ::= prodName::String vt::VertexType seen::[(String, VertexType)] flowEnv::FlowEnv realEnv::Env +DecSiteTree ::= prodName::String vt::VertexType seen::set:Set flowEnv::FlowEnv realEnv::Env { local prodDcl :: [ValueDclInfo] = getValueDcl(prodName, realEnv); local ns :: NamedSignature = @@ -32,10 +32,10 @@ DecSiteTree ::= prodName::String vt::VertexType seen::[(String, VertexType)] flo end; local recurse::(DecSiteTree ::= String VertexType) = - findDecSites(_, _, (prodName, vt) :: seen, flowEnv, realEnv); + findDecSites(_, _, set:add([crossnames(prodName, vt.vertexName)], seen), flowEnv, realEnv); return - if contains((prodName, vt), seen) + if set:contains(crossnames(prodName, vt.vertexName), seen) then neverDec() else -- Direct inherited equation at a decoration site @@ -162,13 +162,13 @@ DecSiteTree ::= attrName::String d::DecSiteTree flowEnv::FlowEnv -} fun resolveInhEq DecSiteTree ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv realEnv::Env = - resolveDecSiteInhEq(attrName, findDecSites(prodName, vt, [], flowEnv, realEnv), flowEnv); + resolveDecSiteInhEq(attrName, findDecSites(prodName, vt, set:empty(), flowEnv, realEnv), flowEnv); -- Helper for checking multiple inh attributes function decSitesMissingInhEqs [(DecSiteTree, [String])] ::= prodName::String vt::VertexType attrNames::[String] flowEnv::FlowEnv realEnv::Env { - local d::DecSiteTree = findDecSites(prodName, vt, [], flowEnv, realEnv); + local d::DecSiteTree = findDecSites(prodName, vt, set:empty(), flowEnv, realEnv); local resolved::map:Map = map:add(map(\ a -> (resolveDecSiteInhEq(a, d, flowEnv), a), attrNames), map:empty()); return flatMap(\ d -> From 64d23b36f024a3b6519bf0192ab774fea0d0489d Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 19 Apr 2024 10:59:20 -0500 Subject: [PATCH 243/283] Reverting ineffective optimization attempt --- .../definition/flow/driver/ProductionGraph.sv | 2 +- .../silver/compiler/definition/flow/env/DecSites.sv | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv index ecbce659a..3d8f00cf1 100644 --- a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv @@ -423,7 +423,7 @@ fun addDefEqs | _ -> true end -> let decSiteTree::DecSiteTree = - findDecSites(prod, decSite, set:fromList([crossnames(prod, ref.vertexName)]), flowEnv, realEnv) + findDecSites(prod, decSite, [(prod, ref)], flowEnv, realEnv) in filterMap( \ attr::String -> -- There is an override equation, so the attribute isn't supplied through sharing diff --git a/grammars/silver/compiler/definition/flow/env/DecSites.sv b/grammars/silver/compiler/definition/flow/env/DecSites.sv index 7e2aa00ce..268ccf6b2 100644 --- a/grammars/silver/compiler/definition/flow/env/DecSites.sv +++ b/grammars/silver/compiler/definition/flow/env/DecSites.sv @@ -1,7 +1,6 @@ grammar silver:compiler:definition:flow:env; import silver:util:treemap as map; -import silver:util:treeset as set; {-- - Generate a decision tree to determine all decoration sites where an inherited equation could be supplied @@ -9,13 +8,13 @@ import silver:util:treeset as set; - - @param prodName The name of the production containing the vertex type. - @param vt The vertex type to find decoration sites for. - - @param seen A set of (production name, vertex type) that have already been visited. + - @param seen A list of (production name, vertex type) pairs that have already been visited. - @param flowEnv The flow environment. - @param realEnv The regular environment. - @return A decision tree to determine if an inherited attributes has been supplied for vt. -} function findDecSites -DecSiteTree ::= prodName::String vt::VertexType seen::set:Set flowEnv::FlowEnv realEnv::Env +DecSiteTree ::= prodName::String vt::VertexType seen::[(String, VertexType)] flowEnv::FlowEnv realEnv::Env { local prodDcl :: [ValueDclInfo] = getValueDcl(prodName, realEnv); local ns :: NamedSignature = @@ -32,10 +31,10 @@ DecSiteTree ::= prodName::String vt::VertexType seen::set:Set flowEnv::F end; local recurse::(DecSiteTree ::= String VertexType) = - findDecSites(_, _, set:add([crossnames(prodName, vt.vertexName)], seen), flowEnv, realEnv); + findDecSites(_, _, (prodName, vt) :: seen, flowEnv, realEnv); return - if set:contains(crossnames(prodName, vt.vertexName), seen) + if contains((prodName, vt), seen) then neverDec() else -- Direct inherited equation at a decoration site @@ -162,13 +161,13 @@ DecSiteTree ::= attrName::String d::DecSiteTree flowEnv::FlowEnv -} fun resolveInhEq DecSiteTree ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv realEnv::Env = - resolveDecSiteInhEq(attrName, findDecSites(prodName, vt, set:empty(), flowEnv, realEnv), flowEnv); + resolveDecSiteInhEq(attrName, findDecSites(prodName, vt, [], flowEnv, realEnv), flowEnv); -- Helper for checking multiple inh attributes function decSitesMissingInhEqs [(DecSiteTree, [String])] ::= prodName::String vt::VertexType attrNames::[String] flowEnv::FlowEnv realEnv::Env { - local d::DecSiteTree = findDecSites(prodName, vt, set:empty(), flowEnv, realEnv); + local d::DecSiteTree = findDecSites(prodName, vt, [], flowEnv, realEnv); local resolved::map:Map = map:add(map(\ a -> (resolveDecSiteInhEq(a, d, flowEnv), a), attrNames), map:empty()); return flatMap(\ d -> From ec2f4f7faf5d486161b9341688d5971fe314935a Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 19 Apr 2024 19:19:49 -0500 Subject: [PATCH 244/283] Just suppress errors from sharing dec site missing inh attrs when the original inh attr vertex is missing an equation --- .../compiler/analysis/warnings/flow/Inh.sv | 68 +++++++++++++------ .../definition/flow/driver/ProductionGraph.sv | 13 +--- 2 files changed, 50 insertions(+), 31 deletions(-) diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index f8d31292a..ad791752e 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -60,17 +60,18 @@ Either ::= args::[String] - things we reference. - - @param v A value we need an equation for. + - @param anonResolve A list of anonymous decoration sites - @param config Command-line arguments, that affect error reporting - - @param l Where to report an error, if it's missing - @param prodName The full name of the production we're in - @param prodNt The nonterminal this production belongs to. (For functions, a dummy value is ok) - @param flowEnv The local flow environment - @param realEnv The local real environment - - @param anonResolve A list of anonymous decoration sites - @returns Errors for missing equations -} function checkEqDeps -[Message] ::= v::FlowVertex config::Decorated CmdArgs prodName::String flowEnv::FlowEnv realEnv::Env anonResolve::[Pair] +[Message] ::= + v::FlowVertex anonResolve::[(String, Location)] + config::Decorated CmdArgs prodName::String flowEnv::FlowEnv realEnv::Env { -- We're concerned with missing inherited equations on RHS, LOCAL, and ANON. (Implicitly, FORWARD.) @@ -122,9 +123,6 @@ function checkEqDeps | subtermSynVertex(parent, termProdName, sigName, attrName) -> [] end; } -fun checkAllEqDeps -[Message] ::= v::[FlowVertex] config::Decorated CmdArgs prodName::String flowEnv::FlowEnv realEnv::Env anonResolve::[Pair] = - flatMap(checkEqDeps(_, config, prodName, flowEnv, realEnv, anonResolve), v); fun checkInhEq [Message] ::= prodName::String vt::VertexType attrName::String config::Decorated CmdArgs flowEnv::FlowEnv realEnv::Env = @@ -133,6 +131,36 @@ fun checkInhEq | missing -> [mwdaWrnAmbientOrigin(config, s"Equation requires inherited attribute ${attrName} be supplied to ${prettyDecSites(missing)}")] end; +function checkAllEqDeps +[Message] ::= + vs::[FlowVertex] flowDefs::[FlowDef] + config::Decorated CmdArgs prodName::String flowEnv::FlowEnv realEnv::Env +{ + -- If a shared tree is missing an inherited equation, then the equation is also + -- missing for the sharing decoration site vertex on which it depends. + -- We want to suppress reporting the error again on the decoration site vertex, + -- since that error wouldn't list the original vertex as a place where the + -- attribute could be supplied. + local alreadyReported::[FlowVertex] = do { + v :: FlowVertex <- vs; + refInh::(VertexType, String) <- + case v of + | rhsInhVertex(sigName, attrName) -> [(rhsVertexType(sigName), attrName)] + | localInhVertex(fName, attrName) -> [(localVertexType(fName), attrName)] + | anonInhVertex(fName, attrName) -> [(anonVertexType(fName), attrName)] + | _ -> [] + end; + decSite::VertexType <- lookupRefDecSite(prodName, refInh.1, flowEnv); + if resolveInhEq(prodName, refInh.1, refInh.2, flowEnv, realEnv) == alwaysDec() + then [] + else [decSite.inhVertex(refInh.2)]; + }; + local anonResolve::[(String, Location)] = collectAnonOrigin(flowDefs); + return flatMap( + checkEqDeps(_, anonResolve, config, prodName, flowEnv, realEnv), + removeAll(alreadyReported, vs)); +} + {-- - Look up flow types, either from the flow environment (for a nonterminal) or the occurs-on contexts (for a type var). - @param syn A synthesized attribute's full name @@ -168,7 +196,7 @@ top::AGDcl ::= 'global' id::Name '::' cl::ConstraintList '=>' t::TypeExpr '=' e: top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, fName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) + then checkAllEqDeps(transitiveDeps, e.flowDefs, top.config, fName, top.flowEnv, top.env) else []; } @@ -179,7 +207,7 @@ top::ClassBodyItem ::= id::Name '::' cl::ConstraintList '=>' ty::TypeExpr '=' e: top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, fName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) + then checkAllEqDeps(transitiveDeps, e.flowDefs, top.config, fName, top.flowEnv, top.env) else []; } @@ -190,7 +218,7 @@ top::InstanceBodyItem ::= id::QName '=' e::Expr ';' top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, id.lookupValue.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) + then checkAllEqDeps(transitiveDeps, e.flowDefs, top.config, id.lookupValue.fullName, top.flowEnv, top.env) else []; } @@ -208,7 +236,7 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr top.errors <- if dl.found && attr.found && top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ + then checkAllEqDeps(transitiveDeps, e.flowDefs, top.config, top.frame.fullName, top.flowEnv, top.env) ++ if null(lhsInhExceedsFlowType) then [] else [mwdaWrnFromOrigin(top, "Synthesized equation " ++ attr.name ++ " exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsFlowType))] else []; @@ -278,7 +306,7 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) + then checkAllEqDeps(transitiveDeps, e.flowDefs, top.config, top.frame.fullName, top.flowEnv, top.env) else []; top.errors <- if top.config.warnMissingInh && dl.name == "forward" && !null(lhsInhExceedsForwardFlowType) @@ -338,7 +366,7 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr top.errors <- if dl.found && attr.found && top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ + then checkAllEqDeps(transitiveDeps, e.flowDefs, top.config, top.frame.fullName, top.flowEnv, top.env) ++ if null(lhsInhExceedsFlowType) then [] else [mwdaWrnFromOrigin(top, "Synthesized equation " ++ attr.name ++ " exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsFlowType))] else []; @@ -357,7 +385,7 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr top.errors <- if dl.found && attr.found && top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ + then checkAllEqDeps(transitiveDeps, e.flowDefs, top.config, top.frame.fullName, top.flowEnv, top.env) ++ if null(lhsInhExceedsFlowType) then [] else [mwdaWrnFromOrigin(top, "Synthesized equation " ++ attr.name ++ " exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsFlowType))] else []; @@ -383,7 +411,7 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ + then checkAllEqDeps(transitiveDeps, e.flowDefs, top.config, top.frame.fullName, top.flowEnv, top.env) ++ if dl.name != "forward" || null(lhsInhExceedsForwardFlowType) then [] else [mwdaWrnFromOrigin(top, "Forward inherited equation for " ++ dl.inhAttrName ++ " exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsForwardFlowType))] else []; @@ -409,7 +437,7 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ + then checkAllEqDeps(transitiveDeps, e.flowDefs, top.config, top.frame.fullName, top.flowEnv, top.env) ++ if dl.name != "forward" || null(lhsInhExceedsForwardFlowType) then [] else [mwdaWrnFromOrigin(top, "Forward inherited equation exceeds for " ++ dl.inhAttrName ++ " flow type with dependencies on " ++ implode(", ", lhsInhExceedsForwardFlowType))] else []; @@ -430,7 +458,7 @@ top::ProductionStmt ::= 'forwards' 'to' e::Expr ';' top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ + then checkAllEqDeps(transitiveDeps, e.flowDefs, top.config, top.frame.fullName, top.flowEnv, top.env) ++ if null(lhsInhExceedsFlowType) then [] else [mwdaWrnFromOrigin(top, "Forward equation exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsFlowType))] else []; @@ -458,7 +486,7 @@ top::ForwardInh ::= lhs::ForwardLHSExpr '=' e::Expr ';' top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) ++ + then checkAllEqDeps(transitiveDeps, e.flowDefs, top.config, top.frame.fullName, top.flowEnv, top.env) ++ if null(lhsInhExceedsFlowType) then [] else [mwdaWrnFromOrigin(top, "Forward inherited equation exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsFlowType))] else []; @@ -473,7 +501,7 @@ top::ProductionStmt ::= @val::QName e::Expr -- check transitive deps only. No worries about flow types. top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) + then checkAllEqDeps(transitiveDeps, e.flowDefs, top.config, top.frame.fullName, top.flowEnv, top.env) else []; } @@ -485,7 +513,7 @@ top::ProductionStmt ::= 'return' e::Expr ';' top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) + then checkAllEqDeps(transitiveDeps, e.flowDefs, top.config, top.frame.fullName, top.flowEnv, top.env) else []; } @@ -497,7 +525,7 @@ top::ProductionStmt ::= 'attachNote' e::Expr ';' top.errors <- if top.config.warnMissingInh - then checkAllEqDeps(transitiveDeps, top.config, top.frame.fullName, top.flowEnv, top.env, collectAnonOrigin(e.flowDefs)) + then checkAllEqDeps(transitiveDeps, e.flowDefs, top.config, top.frame.fullName, top.flowEnv, top.env) else []; } diff --git a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv index 3d8f00cf1..3f78964dc 100644 --- a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv @@ -422,22 +422,13 @@ fun addDefEqs | localVertexType(fName) -> !isForwardProdAttr(fName, realEnv) | _ -> true end -> - let decSiteTree::DecSiteTree = - findDecSites(prod, decSite, [(prod, ref)], flowEnv, realEnv) - in filterMap( + filterMap( \ attr::String -> - -- There is an override equation, so the attribute isn't supplied through sharing if vertexHasInhEq(prod, ref, attr, flowEnv) - -- The sharing decoration site fails to supply the attribute. - -- This will be a missing transitive dep error for ref, don't add the edge to avoid - -- an additional spurious error on decSite, which might be inaccurate if attr should - -- really have an equation on ref. - || isAlwaysDec && - resolveDecSiteInhEq(attr, decSiteTree, flowEnv) != alwaysDec() + -- There is an override equation, so the attribute isn't supplied through sharing then nothing() else just((ref.inhVertex(attr), decSite.inhVertex(attr))), getInhAndInhOnTransAttrsOn(nt, realEnv)) - end | _ -> [] end; From 250bcfbb6f7ffd2973c5e02a703cfb2694539726 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Sat, 20 Apr 2024 16:23:48 -0500 Subject: [PATCH 245/283] Build flow graphs for dispatch signatures, make projection stitch points work for them, add flow check for inh override eqs on forwarding extension impl prods --- .../compiler/analysis/warnings/flow/Inh.sv | 49 ++++++++++++++- .../silver/compiler/definition/env/Defs.sv | 17 +++++- .../silver/compiler/definition/env/Env.sv | 16 ++++- .../compiler/definition/flow/ast/Flow.sv | 5 +- .../definition/flow/driver/ProductionGraph.sv | 60 ++++++++++++++----- .../definition/flow/driver/StitchPoint.sv | 2 +- .../compiler/definition/flow/env/Expr.sv | 4 +- .../silver/compiler/driver/util/FlowTypes.sv | 8 ++- test/flow/RefSiteProj.sv | 2 +- 9 files changed, 132 insertions(+), 31 deletions(-) diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index ad791752e..27135a371 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -263,12 +263,11 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr inhDepsForSyn("forward", top.frame.lhsNtName, myFlow)))); -- Make sure we aren't introducing any hidden transitive dependencies. - -- TODO: Revisit these checks with dispatch sharing. local refDecSiteInhDepsLhsInh :: Maybe> = case filter( - notSharedInputVertex(_, top.env), - lookupRefPossibleDecSites(top.frame.fullName, dl.defLHSVertex, top.flowEnv)) of + notSharedInputVertex(_, top.env), + lookupRefPossibleDecSites(top.frame.fullName, dl.defLHSVertex, top.flowEnv)) of | [] -> nothing() | vs -> just(onlyLhsInh(expandGraph( dl.defLHSVertex.eqVertex ++ @@ -290,6 +289,31 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr end | _ -> nothing() end; + + local ns :: NamedSignature = + case getValueDcl(top.frame.fullName, top.env) of + | dcl :: _ -> dcl.namedSignature + | _ -> error("didn't find a decl for prod " ++ top.frame.fullName) + end; + local implementedSig :: Maybe = + case getValueDcl(top.frame.fullName, top.env) of + | dcl :: _ -> dcl.implementedSignature + | _ -> nothing() + end; + local myGraphs :: EnvTree = head(searchEnvTree(top.grammarName, top.compiledGrammars)).productionFlowGraphs; + local dispatchHostSigInhDepsLhsInh :: Maybe> = + case dl.defLHSVertex, implementedSig of + | rhsVertexType(sigName), just(sig) + when lookupSignatureInputElem(sigName, ns).elementShared -> + just(onlyLhsInh(expandGraph( + [rhsInhVertex( + head(drop(positionOf(sigName, ns.inputNames), sig.inputNames)), + attr.attrDcl.fullName)], + findProductionGraph(sig.fullName, myGraphs)))) + | _, _ -> nothing() + end; + + -- TODO: translation attributes on a dispatch signature -- problem = lhsinh deps - inh deps on dec site local lhsInhExceedsRefDecSiteDeps :: [String] = @@ -304,6 +328,12 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr | _ -> [] end; + local lhsInhExceedsDispatchHostSigInhDeps :: [String] = + case dispatchHostSigInhDepsLhsInh of + | just(deps) -> set:toList(set:difference(lhsInhDeps, deps)) + | _ -> [] + end; + top.errors <- if top.config.warnMissingInh then checkAllEqDeps(transitiveDeps, e.flowDefs, top.config, top.frame.fullName, top.flowEnv, top.env) @@ -338,6 +368,19 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr s"${transAttr}.${attr.attrDcl.fullName} on some reference to ${v.vertexPP} may be expected to depend ${transBaseRefDecSiteInhDepsLhsInhStr}")] | _ -> [] end; + local dispatchHostSigInhDepsLhsInhStr::String = + case set:toList(dispatchHostSigInhDepsLhsInh.fromJust) of + | [] -> "on no attributes" + | deps -> "only on " ++ implode(", ", deps) + end; + top.errors <- + case implementedSig of + | just(sig) when top.config.warnMissingInh && !null(lhsInhExceedsDispatchHostSigInhDeps) -> + [mwdaWrnFromOrigin(top, + s"Inherited override equation exceeds the allowed dependencies for an extension implementation production, with dependencies on ${implode(", ", lhsInhExceedsDispatchHostSigInhDeps)}; " ++ + s"${attr.attrDcl.fullName} on child ${head(drop(positionOf(dl.name, top.frame.signature.inputNames), sig.inputNames))} of signature ${sig.fullName} may be expected to depend ${dispatchHostSigInhDepsLhsInhStr}")] + | _ -> [] + end; } fun notSharedInputVertex Boolean ::= v::VertexType env::Env = diff --git a/grammars/silver/compiler/definition/env/Defs.sv b/grammars/silver/compiler/definition/env/Defs.sv index 0e0bd421a..0762bfc3f 100644 --- a/grammars/silver/compiler/definition/env/Defs.sv +++ b/grammars/silver/compiler/definition/env/Defs.sv @@ -1,6 +1,6 @@ grammar silver:compiler:definition:env; -nonterminal Defs with defs, typeList, valueList, attrList, instList, prodOccursList, prodDclList, filterItems, filterOnly, filterHiding, withRenames, renamed, pfx, prepended; +nonterminal Defs with defs, typeList, valueList, attrList, instList, prodOccursList, prodDclList, dispatchDclList, filterItems, filterOnly, filterHiding, withRenames, renamed, pfx, prepended; -- The standard namespaces synthesized attribute typeList :: [EnvItem]; @@ -15,6 +15,7 @@ synthesized attribute prodOccursList :: [ProductionAttrDclInfo]; -- Extra space for production list synthesized attribute prodDclList :: [ValueDclInfo]; +synthesized attribute dispatchDclList :: [TypeDclInfo]; -- Transformations on lists of Def -- This is to support computing the defs introduced by qualified imports @@ -37,6 +38,7 @@ top::Defs ::= top.prodOccursList = []; top.prodDclList = []; + top.dispatchDclList = []; top.filterOnly = top; top.filterHiding = top; @@ -55,6 +57,7 @@ top::Defs ::= e1::Def e2::Defs top.prodOccursList = e1.prodOccursList ++ e2.prodOccursList; top.prodDclList = e1.prodDclList ++ e2.prodDclList; + top.dispatchDclList = e1.dispatchDclList ++ e2.dispatchDclList; top.filterOnly = if e1.filterIncludeOnly then consDefs(e1, e2.filterOnly) else e2.filterOnly; top.filterHiding = if e1.filterIncludeHiding then consDefs(e1, e2.filterHiding) else e2.filterHiding; @@ -63,7 +66,7 @@ top::Defs ::= e1::Def e2::Defs -------------------------------------------------------------------------------- closed nonterminal Def with - typeList, valueList, attrList, instList, prodOccursList, prodDclList, + typeList, valueList, attrList, instList, prodOccursList, prodDclList, dispatchDclList, filterItems, filterIncludeOnly, filterIncludeHiding, withRenames, renamed, pfx, prepended, compareTo, isEqual; @@ -80,12 +83,20 @@ top::Def ::= top.prodOccursList = []; top.prodDclList = []; + top.dispatchDclList = []; } abstract production typeDef top::Def ::= d::EnvItem { top.typeList = [d]; } +abstract production dispatchDclDef +top::Def ::= d::EnvItem +{ + top.typeList = [d]; + -- unlike normal typeDef, also affect dispatch lookups: + top.dispatchDclList = [d.dcl]; +} abstract production valueDef top::Def ::= d::EnvItem { @@ -152,7 +163,7 @@ fun typeAliasDef Def ::= sg::String sl::Location fn::String mentionedAliases::[String] bound::[TyVar] ty::Type = typeDef(defaultEnvItem(typeAliasDcl(fn,mentionedAliases,bound,ty,sourceGrammar=sg,sourceLocation=sl))); fun dispatchDef Def ::= sg::String sl::Location sig::NamedSignature = - typeDef(defaultEnvItem(dispatchDcl(sig,sourceGrammar=sg,sourceLocation=sl))); + dispatchDclDef(defaultEnvItem(dispatchDcl(sig,sourceGrammar=sg,sourceLocation=sl))); fun synDef Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type = attrDef(defaultEnvItem(synDcl(fn,bound,ty,sourceGrammar=sg,sourceLocation=sl))); fun inhDef Def ::= sg::String sl::Location fn::String bound::[TyVar] ty::Type = diff --git a/grammars/silver/compiler/definition/env/Env.sv b/grammars/silver/compiler/definition/env/Env.sv index ee5da3f06..ce3057300 100644 --- a/grammars/silver/compiler/definition/env/Env.sv +++ b/grammars/silver/compiler/definition/env/Env.sv @@ -13,7 +13,9 @@ grammar silver:compiler:definition:env; -- getProdAttrs [DclInfo] ::= prod::String e::Env -data nonterminal Env with typeTree, valueTree, attrTree, instTree, prodOccursTree, occursTree, prodsForNtTree; +data nonterminal Env with + typeTree, valueTree, attrTree, instTree, prodOccursTree, occursTree, prodsForNtTree, + prodDclList, dispatchDclList; synthesized attribute typeTree :: [EnvTree]; -- Expr is type tau synthesized attribute valueTree :: [EnvTree]; -- x has type tau @@ -41,6 +43,9 @@ top::Env ::= top.occursTree = emptyEnvTree(); top.prodsForNtTree = [emptyEnvTree()]; + + top.prodDclList = []; + top.dispatchDclList = []; } fun toEnv Env ::= d::[Def] od::[OccursDclInfo] = occursEnv(od, newScopeEnv(d, emptyEnv())); @@ -68,6 +73,9 @@ top::Env ::= e1::Env e2::Env top.occursTree = appendEnvTree(e1.occursTree, e2.occursTree); top.prodsForNtTree = e1.prodsForNtTree ++ e2.prodsForNtTree; + + top.prodDclList = e1.prodDclList ++ e2.prodDclList; + top.dispatchDclList = e1.dispatchDclList ++ e2.dispatchDclList; } {-- @@ -88,6 +96,9 @@ top::Env ::= ds::[Def] e::Env top.prodsForNtTree = directBuildTree(map(\ di::ValueDclInfo -> (di.namedSignature.outputElement.typerep.typeName, di), d.prodDclList)) :: e.prodsForNtTree; + + top.prodDclList = d.prodDclList ++ e.prodDclList; + top.dispatchDclList = d.dispatchDclList ++ e.dispatchDclList; } {-- @@ -106,6 +117,9 @@ top::Env ::= d::[OccursDclInfo] e::Env top.occursTree = consEnvTree(mapFullnameDcls(d), e.occursTree); top.prodsForNtTree = e.prodsForNtTree; + + top.prodDclList = e.prodDclList; + top.dispatchDclList = e.dispatchDclList; } ---------------------------------------------------------------------------------------------------- diff --git a/grammars/silver/compiler/definition/flow/ast/Flow.sv b/grammars/silver/compiler/definition/flow/ast/Flow.sv index f99e91c03..1cc86e64f 100644 --- a/grammars/silver/compiler/definition/flow/ast/Flow.sv +++ b/grammars/silver/compiler/definition/flow/ast/Flow.sv @@ -436,7 +436,7 @@ data PatternVarProjection - @param sigName the name of the child under which this term appears -} abstract production subtermDecEq -top::FlowDef ::= prod::String parent::VertexType termProd::String sigName::String +top::FlowDef ::= prod::String parent::VertexType termProd::String nt::String sigName::String { top.prodGraphContribs := [(prod, top)]; top.flowEdges = []; @@ -464,13 +464,14 @@ top::FlowDef ::= prod::String nt::String ref::VertexType decSite::VertexType - A tree that is shared in the application of a production/dispatch signature - - @param prod the full name of the production/dispatch signature + - @param nt the full name of the nonterminal - @param sigName the name of the shared child in prod - @param sourceProd the full name of the (dispatching) production that forwarded to prod - @param source the vertex type of the shared tree supplied by sourceProd as the shared child - @param parent the vertex type of where prod is decorated in sourceProd - should always be forward or a forward prod attr. -} abstract production sigShareSite -top::FlowDef ::= prod::String sigName::String sourceProd::String source::VertexType parent::VertexType +top::FlowDef ::= prod::String nt::String sigName::String sourceProd::String source::VertexType parent::VertexType { top.prodGraphContribs := [(prod, top)]; top.flowEdges = []; diff --git a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv index 3f78964dc..2402ecbe0 100644 --- a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv @@ -104,9 +104,11 @@ fun computeAllProductionGraphs -------------------------------------------------------------------------------- -- Below, we have various means of constructing a production graph. --- Two types are used as part of inference: +-- Three types are used as part of inference: -- 1. `constructProductionGraph` builds a graph for a normal production. -- 2. `constructPhantomProductionGraph` builds a "phantom graph" to guide inference. +-- 3. `constructDispatchGraph` builds a graph for a dispatch signature, +-- to make projection stitch points work for them. -- -- There are more types of "production" graphs, used NOT for inference, but -- for error checking behaviors: @@ -362,6 +364,26 @@ ProductionGraph ::= nt::String flowEnv::FlowEnv realEnv::Env return productionGraph("Phantom for " ++ nt, nt, flowTypeVertexes, initialGraph, suspectEdges, stitchPoints).transitiveClosure; } +function constructDispatchGraph +ProductionGraph ::= ns::NamedSignature flowEnv::FlowEnv realEnv::Env +{ + local dispatch :: String = ns.fullName; + local nt :: NtName = ns.outputElement.typerep.typeName; + local implProds :: [String] = getImplementingProds(dispatch, flowEnv); + + -- The graph has no normal edges, only projection stitch points! + local normalEdges :: [(FlowVertex, FlowVertex)] = []; + + local stitchPoints :: [StitchPoint] = + flatMap(dispatchStitchPoints(ns, flowEnv, realEnv, _), implProds); + + local flowTypeVertexes :: [FlowVertex] = []; -- Doesn't (directly) affect flow types + local initialGraph :: g:Graph = createFlowGraph(normalEdges); + local suspectEdges :: [(FlowVertex, FlowVertex)] = []; + + return productionGraph(dispatch, nt, flowTypeVertexes, initialGraph, suspectEdges, stitchPoints).transitiveClosure; +} + fun getPhantomEdge (FlowVertex, FlowVertex) ::= at::String = (lhsSynVertex(at), forwardEqVertex()); @@ -491,31 +513,39 @@ fun patVarStitchPoints [StitchPoint] ::= matchProd::String scrutinee::VertexTyp fun subtermDecSiteStitchPoints [StitchPoint] ::= flowEnv::FlowEnv realEnv::Env defs::[FlowDef] = flatMap(\ d::FlowDef -> case d of - | subtermDecEq(prodName, parent, termProdName, sigName) -> - map(\ prodDcl::ValueDclInfo -> - projectionStitchPoint( + | subtermDecEq(prodName, parent, termProdName, nt, sigName) -> + [projectionStitchPoint( termProdName, subtermVertexType(parent, termProdName, sigName), parent, rhsVertexType(sigName), - getInhAndInhOnTransAttrsOn( - lookupSignatureInputElem(sigName, prodDcl.namedSignature).typerep.typeName, - realEnv)), - getValueDcl(termProdName, realEnv)) + getInhAndInhOnTransAttrsOn(nt, realEnv))] | _ -> [] end, defs); fun sigSharingStitchPoints [StitchPoint] ::= flowEnv::FlowEnv realEnv::Env defs::[FlowDef] = flatMap(\ d::FlowDef -> case d of - | sigShareSite(_, sigName, sourceProd, vt, parent) -> - map(\ prodDcl::ValueDclInfo -> - projectionStitchPoint( + | sigShareSite(_, nt, sigName, sourceProd, vt, parent) -> + [projectionStitchPoint( sourceProd, rhsVertexType(sigName), lhsVertexType, vt, - getInhAndInhOnTransAttrsOn( - lookupSignatureInputElem(sigName, prodDcl.namedSignature).typerep.typeName, - realEnv)), - getValueDcl(sourceProd, realEnv)) + getInhAndInhOnTransAttrsOn(nt, realEnv))] | _ -> [] end, defs); +fun dispatchStitchPoints [StitchPoint] ::= dispatch::NamedSignature flowEnv::FlowEnv realEnv::Env prod::String = + case getValueDcl(prod, realEnv) of + | dcl :: _ -> + flatMap(\ ie::NamedSignatureElement -> + if ie.elementDclType.isNonterminal -- Dispatch sigs can't have occurs-on constraints + then [projectionStitchPoint( + prod, rhsVertexType(ie.elementName), lhsVertexType, + rhsVertexType( + head(drop(positionOf(ie.elementName, dispatch.inputNames), dcl.namedSignature.inputNames))), + getInhAndInhOnTransAttrsOn( + lookupSignatureInputElem(ie.elementName, dispatch).typerep.typeName, + realEnv))] + else [], + dispatch.inputElements) + | _ -> [] + end; ---- End helpers for figuring our stitch points -------------------------------- diff --git a/grammars/silver/compiler/definition/flow/driver/StitchPoint.sv b/grammars/silver/compiler/definition/flow/driver/StitchPoint.sv index da635b1bb..acf2cd075 100644 --- a/grammars/silver/compiler/definition/flow/driver/StitchPoint.sv +++ b/grammars/silver/compiler/definition/flow/driver/StitchPoint.sv @@ -31,7 +31,7 @@ top::StitchPoint ::= nt::String vertexType::VertexType - For example, if 'prod' has (rhs1, env) -> (lhs, env), - then here we would emit (patvar23, env) -> (e, env). - - - @param prod The production we're projecting + - @param prod The production (or dispatch signature) we're projecting - @param sourceType The "vertexType" of this stitchPoint - @param targetType The "vertexType" of where this stitchPoint should proxy to - @param prodType The "vertexType" in the other production to use diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index 5f27da6f3..902a34e13 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -240,7 +240,7 @@ top::AppExpr ::= e::Expr top.flowDefs <- case e.decSiteVertexInfo of | just(subtermVertexType(parent, prodName, sigName)) -> - [subtermDecEq(top.frame.fullName, parent, prodName, sigName)] + [subtermDecEq(top.frame.fullName, parent, prodName, e.typerep.typeName, sigName)] | _ -> [] end; e.decSiteVertexInfo = @@ -277,7 +277,7 @@ top::AppExpr ::= e::Expr top.frame.fullName, e.typerep.typeName, v, subtermVertexType(parent, ns.fullName, sigName), true) :: if inputSigIsShared then [] - else [sigShareSite(ns.fullName, sigName, top.frame.fullName, v, parent)] + else [sigShareSite(ns.fullName, e.typerep.typeName, sigName, top.frame.fullName, v, parent)] | _, _, _ -> [] end; } diff --git a/grammars/silver/compiler/driver/util/FlowTypes.sv b/grammars/silver/compiler/driver/util/FlowTypes.sv index 716749983..3f8004532 100644 --- a/grammars/silver/compiler/driver/util/FlowTypes.sv +++ b/grammars/silver/compiler/driver/util/FlowTypes.sv @@ -26,14 +26,16 @@ top::Compilation ::= g::Grammars r::Grammars buildGrammars::[String] benv::Bu local allRealEnv :: Env = toEnv(allRealDefs, allRealOccursDefs); -- List of all productions - local allProds :: [ValueDclInfo] = foldr(consDefs, nilDefs(), allRealDefs).prodDclList; + local allProds :: [ValueDclInfo] = allRealEnv.prodDclList; local allNts :: [String] = nub(map(getProdNt, allProds)); + local allDispatchSigs :: [NamedSignature] = map((.dispatchSignature), allRealEnv.dispatchDclList); -- Construct production graphs. production prodGraph :: [ProductionGraph] = computeAllProductionGraphs(allProds, allFlowEnv, allRealEnv) ++ - -- Add in phantom graphs - map(constructPhantomProductionGraph(_, allFlowEnv, allRealEnv), allNts); + -- Add in phantom and dispatch graphs + map(constructPhantomProductionGraph(_, allFlowEnv, allRealEnv), allNts) ++ + map(constructDispatchGraph(_, allFlowEnv, allRealEnv), allDispatchSigs); local initialFT :: EnvTree = computeInitialFlowTypes(allSpecDefs); diff --git a/test/flow/RefSiteProj.sv b/test/flow/RefSiteProj.sv index 886d1bf30..be5fae34e 100644 --- a/test/flow/RefSiteProj.sv +++ b/test/flow/RefSiteProj.sv @@ -134,7 +134,7 @@ top::RSExpr ::= e::RSExpr local e1::RSExpr = @e; e1.env2 = top.env2; - top.errors1 = e1.errors1; + top.errors1 = e.errors1; top.errors2 = e.errors2; } From 202ca99ed8ddb5e058b40c6cd328ef6d15d0e135 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 22 Apr 2024 11:40:20 -0500 Subject: [PATCH 246/283] FIx minor bug with inh overrides on translation attributes on shared trees --- runtime/java/src/common/DecoratedNode.java | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/runtime/java/src/common/DecoratedNode.java b/runtime/java/src/common/DecoratedNode.java index 038fdd5fc..4704f9745 100644 --- a/runtime/java/src/common/DecoratedNode.java +++ b/runtime/java/src/common/DecoratedNode.java @@ -224,18 +224,28 @@ public DecoratedNode decorate(final DecoratedNode parent, final Lazy[] inhs, fin } else { inheritedAttributes = inheritedAttributes.clone(); // Avoid modifying the static inh array from the original parent Node } - for(int i = 0; i < inhs.length; i++) { - final int attribute = i; - if(inhs[attribute] != null && inheritedAttributes[attribute] == null) { - inheritedAttributes[attribute] = inhs[attribute].withContext(parent); - } - } + copyInhOverrides(parent, inheritedAttributes, inhs); } decorationSite = decSite != null? decSite.withContext(parent) : null; } return this; } + private void copyInhOverrides(final DecoratedNode parent, final Lazy[] inhs, final Lazy[] newInhs) { + assert inhs.length == newInhs.length; + for(int i = 0; i < inhs.length; i++) { + if(newInhs[i] != null) { + Lazy newInh = newInhs[i].withContext(parent); + if(inhs[i] == null) { + inhs[i] = newInh; + } else if (inhs[i] instanceof TransInhs) { + assert newInhs[i] instanceof TransInhs; + copyInhOverrides(parent, ((TransInhs)inhs[i]).inhs, ((TransInhs)newInh).inhs); + } + } + } + } + /** * Decorate this node with a forward parent. * This has no effect if the node already has a forward parent. From abfed4506d2e847cd38154a259551c0bb9b564c5 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 22 Apr 2024 14:13:40 -0500 Subject: [PATCH 247/283] Refactor/finish hidding transitive dep check on inh override eqs --- .../compiler/analysis/warnings/flow/Inh.sv | 98 ++++++++++--------- test/flow/RefSiteProj.sv | 14 +-- 2 files changed, 59 insertions(+), 53 deletions(-) diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index 27135a371..5e3797573 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -289,31 +289,6 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr end | _ -> nothing() end; - - local ns :: NamedSignature = - case getValueDcl(top.frame.fullName, top.env) of - | dcl :: _ -> dcl.namedSignature - | _ -> error("didn't find a decl for prod " ++ top.frame.fullName) - end; - local implementedSig :: Maybe = - case getValueDcl(top.frame.fullName, top.env) of - | dcl :: _ -> dcl.implementedSignature - | _ -> nothing() - end; - local myGraphs :: EnvTree = head(searchEnvTree(top.grammarName, top.compiledGrammars)).productionFlowGraphs; - local dispatchHostSigInhDepsLhsInh :: Maybe> = - case dl.defLHSVertex, implementedSig of - | rhsVertexType(sigName), just(sig) - when lookupSignatureInputElem(sigName, ns).elementShared -> - just(onlyLhsInh(expandGraph( - [rhsInhVertex( - head(drop(positionOf(sigName, ns.inputNames), sig.inputNames)), - attr.attrDcl.fullName)], - findProductionGraph(sig.fullName, myGraphs)))) - | _, _ -> nothing() - end; - - -- TODO: translation attributes on a dispatch signature -- problem = lhsinh deps - inh deps on dec site local lhsInhExceedsRefDecSiteDeps :: [String] = @@ -327,7 +302,44 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr | just(deps) -> set:toList(set:difference(lhsInhDeps, deps)) | _ -> [] end; + + -- Extension productions that implement a dispatch signature + + local ns :: NamedSignature = -- top.frame.signature might have aspect sig names that don't match the flow env + case getValueDcl(top.frame.fullName, top.env) of + | dcl :: _ -> dcl.namedSignature + | _ -> error("didn't find a decl for prod " ++ top.frame.fullName) + end; + local implementedSig :: Maybe = + case getValueDcl(top.frame.fullName, top.env) of + | dcl :: _ -> dcl.implementedSignature + | _ -> nothing() + end; + local myGraphs :: EnvTree = head(searchEnvTree(top.grammarName, top.compiledGrammars)).productionFlowGraphs; + local dispatchHostSigInhDepsLhsInh :: Maybe> = + case implementedSig of + | just(dispatchSig) -> + case dl.defLHSVertex of + | rhsVertexType(sigName) + when lookupSignatureInputElem(sigName, ns).elementShared -> + just(onlyLhsInh(expandGraph( + [rhsInhVertex( + head(drop(positionOf(sigName, ns.inputNames), dispatchSig.inputNames)), + attr.attrDcl.fullName)], + findProductionGraph(dispatchSig.fullName, myGraphs)))) + | transAttrVertexType(rhsVertexType(sigName), transAttr) + when lookupSignatureInputElem(sigName, ns).elementShared -> + just(onlyLhsInh(expandGraph( + [rhsInhVertex( + head(drop(positionOf(sigName, ns.inputNames), dispatchSig.inputNames)), + transAttr ++ "." ++ attr.attrDcl.fullName)], + findProductionGraph(dispatchSig.fullName, myGraphs)))) + | _ -> nothing() + end + | _ -> nothing() + end; + -- problem = lhsinh deps - inh deps on host implementation prods local lhsInhExceedsDispatchHostSigInhDeps :: [String] = case dispatchHostSigInhDepsLhsInh of | just(deps) -> set:toList(set:difference(lhsInhDeps, deps)) @@ -342,47 +354,41 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr if top.config.warnMissingInh && dl.name == "forward" && !null(lhsInhExceedsForwardFlowType) then [mwdaWrnFromOrigin(top, "Forward inherited equation for " ++ dl.inhAttrName ++ " exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsForwardFlowType))] else []; - local refDecSiteInhDepsLhsInhStr::String = - case set:toList(refDecSiteInhDepsLhsInh.fromJust) of - | [] -> "on no attributes" - | deps -> "only on " ++ implode(", ", deps) - end; top.errors <- if top.config.warnMissingInh && !null(lhsInhExceedsRefDecSiteDeps) then [mwdaWrnFromOrigin(top, - s"Inherited override equation may exceed a flow type with hidden transitive dependencies on ${implode(", ", lhsInhExceedsRefDecSiteDeps)}; " ++ - s"${attr.attrDcl.fullName} on some reference to ${dl.defLHSVertex.vertexPP} may be expected to depend ${refDecSiteInhDepsLhsInhStr}")] + s"Inherited override equation for ${attr.attrDcl.fullName} on ${dl.defLHSVertex.vertexPP} may exceed a flow type " ++ + s"with hidden transitive dependencies on ${implode(", ", lhsInhExceedsRefDecSiteDeps)}; " ++ + s"on some reference to this tree, this attribute may be expected to depend ${depListStr(refDecSiteInhDepsLhsInh.fromJust)}")] else []; - local transBaseRefDecSiteInhDepsLhsInhStr::String = - case set:toList(transBaseRefDecSiteInhDepsLhsInh.fromJust) of - | [] -> "on no attributes" - | deps -> "only on " ++ implode(", ", deps) - end; top.errors <- case dl.defLHSVertex of | transAttrVertexType(v, transAttr) when top.config.warnMissingInh && !null(lhsInhExceedsTransBaseRefDecSiteDeps) -> [mwdaWrnFromOrigin(top, - s"Inherited override equation may exceed a flow type with hidden transitive dependencies on ${implode(", ", lhsInhExceedsTransBaseRefDecSiteDeps)}; " ++ - s"${transAttr}.${attr.attrDcl.fullName} on some reference to ${v.vertexPP} may be expected to depend ${transBaseRefDecSiteInhDepsLhsInhStr}")] + s"Inherited override equation for ${transAttr}.${attr.attrDcl.fullName} on ${v.vertexPP} may exceed a flow type " ++ + s"with hidden transitive dependencies on ${implode(", ", lhsInhExceedsTransBaseRefDecSiteDeps)}; " ++ + s"on some reference to this tree, this attribute may be expected to depend ${depListStr(transBaseRefDecSiteInhDepsLhsInh.fromJust)}")] | _ -> [] end; - local dispatchHostSigInhDepsLhsInhStr::String = - case set:toList(dispatchHostSigInhDepsLhsInh.fromJust) of - | [] -> "on no attributes" - | deps -> "only on " ++ implode(", ", deps) - end; top.errors <- case implementedSig of | just(sig) when top.config.warnMissingInh && !null(lhsInhExceedsDispatchHostSigInhDeps) -> [mwdaWrnFromOrigin(top, - s"Inherited override equation exceeds the allowed dependencies for an extension implementation production, with dependencies on ${implode(", ", lhsInhExceedsDispatchHostSigInhDeps)}; " ++ - s"${attr.attrDcl.fullName} on child ${head(drop(positionOf(dl.name, top.frame.signature.inputNames), sig.inputNames))} of signature ${sig.fullName} may be expected to depend ${dispatchHostSigInhDepsLhsInhStr}")] + s"Inherited override equation for ${attr.attrDcl.fullName} on ${dl.defLHSVertex.vertexPP} may exceed a flow type " ++ + s"with hidden transitive dependencies on ${implode(", ", lhsInhExceedsDispatchHostSigInhDeps)}; " ++ + s"on some reference to this tree, this attribute may be expected to depend ${depListStr(dispatchHostSigInhDepsLhsInh.fromJust)}")] | _ -> [] end; } +fun depListStr String ::= deps::set:Set = + case set:toList(deps) of + | [] -> "on no left-side inherited attributes" + | deps -> "only on " ++ implode(", ", deps) + end; + fun notSharedInputVertex Boolean ::= v::VertexType env::Env = case v of | subtermVertexType(_, prodName, sigName) -> diff --git a/test/flow/RefSiteProj.sv b/test/flow/RefSiteProj.sv index be5fae34e..1e5a04074 100644 --- a/test/flow/RefSiteProj.sv +++ b/test/flow/RefSiteProj.sv @@ -151,7 +151,7 @@ top::RSExpr ::= e::RSExpr } } -warnCode "override equation may exceed a flow type with hidden transitive dependencies" { +warnCode "may exceed a flow type with hidden transitive dependencies" { production remoteExceedsOverride top::RSExpr ::= e::RSExpr { @@ -179,7 +179,7 @@ top::RSExpr ::= e::RSExpr } } -warnCode "override equation may exceed a flow type with hidden transitive dependencies" { +warnCode "may exceed a flow type with hidden transitive dependencies" { production uselessOverrideWithinFT top::RSExpr ::= e::RSExpr { @@ -192,7 +192,7 @@ top::RSExpr ::= e::RSExpr } } -warnCode "override equation may exceed a flow type with hidden transitive dependencies" { +warnCode "may exceed a flow type with hidden transitive dependencies" { production fwrdDecSiteExceedsFT top::RSExpr ::= e::RSExpr { @@ -201,7 +201,7 @@ top::RSExpr ::= e::RSExpr } } -warnCode "override equation may exceed a flow type with hidden transitive dependencies" { +warnCode "may exceed a flow type with hidden transitive dependencies" { production projExceedsFT top::RSExpr ::= e::RSExpr { @@ -211,7 +211,7 @@ top::RSExpr ::= e::RSExpr } } -warnCode "override equation may exceed a flow type with hidden transitive dependencies" { +warnCode "may exceed a flow type with hidden transitive dependencies" { production condDecExceedsFT top::RSExpr ::= e::RSExpr { @@ -229,7 +229,7 @@ top::RSExpr ::= e::RSExpr if top.env1 == [] then copy12From2(@e) else base(); } -warnCode "override equation may exceed a flow type with hidden transitive dependencies" { +warnCode "may exceed a flow type with hidden transitive dependencies" { production overrideNotInRefSet top::RSExpr ::= e::RSExpr { @@ -290,7 +290,7 @@ top::RSExpr ::= e::RSExpr top.errors2 = e.errors2; } -warnCode "override equation may exceed a flow type with hidden transitive dependencies" { +warnCode "may exceed a flow type with hidden transitive dependencies" { production anonDecOverrideExceedsFT top::RSExpr ::= e::RSExpr { From c8e1f4259034c40740d2b661a59c200fe44f3ac9 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 22 Apr 2024 17:06:40 -0500 Subject: [PATCH 248/283] Extend duplicate equation check to handle sig sharing, may have bugs --- .../warnings/flow/OrphanedEquation.sv | 45 ++++--------------- .../compiler/definition/flow/ast/Flow.sv | 4 +- .../compiler/definition/flow/env/DecSites.sv | 12 +---- .../compiler/definition/flow/env/FlowEnv.sv | 36 +++++++++++++++ test/flow/RefSiteProj.sv | 2 + 5 files changed, 50 insertions(+), 49 deletions(-) diff --git a/grammars/silver/compiler/analysis/warnings/flow/OrphanedEquation.sv b/grammars/silver/compiler/analysis/warnings/flow/OrphanedEquation.sv index 76b6f8453..f67bdae4b 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/OrphanedEquation.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/OrphanedEquation.sv @@ -40,10 +40,10 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr && !isExportedBy(top.grammarName, exportedBy, top.compiledGrammars) then [mwdaWrnFromOrigin(top, "Orphaned equation: " ++ attr.name ++ " (occurs from " ++ attr.dcl.sourceGrammar ++ ") in production " ++ top.frame.fullName)] else []; - + -- Duplicate equation check top.errors <- - if length(dl.lookupEqDefLHS) > 1 + if dl.found && attr.found && countVertexEqs(top.frame.fullName, dl.defLHSVertex, attr.attrDcl.fullName, top.flowEnv, top.env) > 1 then [mwdaWrnFromOrigin(top, "Duplicate equation for " ++ attr.name ++ " in production " ++ top.frame.fullName)] else []; } @@ -73,9 +73,9 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr then [mwdaWrnFromOrigin(top, "Orphaned equation: " ++ attr.name ++ " on " ++ dl.name ++ " (occurs from " ++ attr.dcl.sourceGrammar ++ ") in production " ++ top.frame.fullName)] -- Now, check for duplicate equations! else []; - + top.errors <- - if length(dl.lookupEqDefLHS) > 1 || contains(dl.inhAttrName, getMinRefSet(dl.typerep, top.env)) + if dl.found && attr.found && countVertexEqs(top.frame.fullName, dl.defLHSVertex, attr.attrDcl.fullName, top.flowEnv, top.env) > 1 then [mwdaWrnFromOrigin(top, "Duplicate equation for " ++ attr.name ++ " on " ++ dl.name ++ " in production " ++ top.frame.fullName)] else []; } @@ -98,10 +98,10 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr && !isExportedBy(top.grammarName, exportedBy, top.compiledGrammars) then [mwdaWrnFromOrigin(top, "Orphaned equation: " ++ attr.name ++ " (occurs from " ++ attr.dcl.sourceGrammar ++ ") in production " ++ top.frame.fullName)] else []; - + -- Duplicate equation check top.errors <- - if length(dl.lookupEqDefLHS) > 1 + if dl.found && attr.found && countVertexEqs(top.frame.fullName, dl.defLHSVertex, attr.attrDcl.fullName, top.flowEnv, top.env) > 1 then [mwdaWrnFromOrigin(top, "Duplicate equation for " ++ attr.name ++ " in production " ++ top.frame.fullName)] else []; } @@ -130,9 +130,9 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr then [mwdaWrnFromOrigin(top, "Orphaned equation: " ++ attr.name ++ " on " ++ dl.name ++ " (occurs from " ++ attr.dcl.sourceGrammar ++ ") in production " ++ top.frame.fullName)] -- Now, check for duplicate equations! else []; - + top.errors <- - if length(dl.lookupEqDefLHS) > 1 || contains(dl.inhAttrName, getMinRefSet(dl.typerep, top.env)) + if dl.found && attr.found && countVertexEqs(top.frame.fullName, dl.defLHSVertex, attr.attrDcl.fullName, top.flowEnv, top.env) > 1 then [mwdaWrnFromOrigin(top, "Duplicate equation for " ++ attr.name ++ " on " ++ dl.name ++ " in production " ++ top.frame.fullName)] else []; } @@ -146,32 +146,3 @@ top::ExprLHSExpr ::= attr::QNameAttrOccur then [mwdaWrnFromOrigin(top, "Duplicate equation for " ++ attr.name)] else []; } - ---- For our DefLHSs: - -{-- - - A lookup for other instances of this equation on this DefLHS. - -} -synthesized attribute lookupEqDefLHS :: [FlowDef] occurs on DefLHS; -flowtype lookupEqDefLHS {decorate} on DefLHS; - -aspect lookupEqDefLHS on top::DefLHS of - -- prod, child, attr -| childDefLHS(q) -> lookupInh(top.frame.fullName, q.lookupValue.fullName, top.defLHSattr.attrDcl.fullName, top.flowEnv) - -- prod, child, trans attr, attr -| childTransAttrDefLHS(q, attr) -> lookupInh(top.frame.fullName, q.lookupValue.fullName, s"${attr.attrDcl.fullName}.${top.defLHSattr.attrDcl.fullName}", top.flowEnv) - -- prod, attr -| lhsDefLHS(q) -> lookupSyn(top.frame.fullName, top.defLHSattr.attrDcl.fullName, top.flowEnv) - -- prod, local, attr -| localDefLHS(q) -> lookupLocalInh(top.frame.fullName, q.lookupValue.fullName, top.defLHSattr.attrDcl.fullName, top.flowEnv) - -- prod, local, trans attr, attr -| localTransAttrDefLHS(q, attr) -> lookupLocalInh(top.frame.fullName, q.lookupValue.fullName, s"${attr.attrDcl.fullName}.${top.defLHSattr.attrDcl.fullName}", top.flowEnv) - -- prod, attr -| forwardDefLHS(q) -> lookupFwdInh(top.frame.fullName, top.defLHSattr.attrDcl.fullName, top.flowEnv) - -- nt, attr -| defaultLhsDefLHS(q) -> lookupDef(top.frame.lhsNtName, top.defLHSattr.attrDcl.fullName, top.flowEnv) - -| errorDefLHS(q) -> [] -| errorTransAttrDefLHS(_, _) -> [] -| parserAttributeDefLHS(q) -> [] -- TODO: maybe error? -end; diff --git a/grammars/silver/compiler/definition/flow/ast/Flow.sv b/grammars/silver/compiler/definition/flow/ast/Flow.sv index 1cc86e64f..da59f6a93 100644 --- a/grammars/silver/compiler/definition/flow/ast/Flow.sv +++ b/grammars/silver/compiler/definition/flow/ast/Flow.sv @@ -69,11 +69,11 @@ monoid attribute hostSynTreeContribs :: [(String, FlowDef)]; {-- A list of attributes for a production that are non-suspect -} monoid attribute nonSuspectContribs :: [Pair]; -{-- lookup dec site to find places that a unique reference to this ref site *might be* decorated. +{-- lookup dec site to find places that a shared reference to this tree *might be* decorated. - This includes e.g. unique reference sites that appear in an if/else branch. -} monoid attribute refPossibleDecSiteContribs :: [(String, VertexType)]; -{-- lookup dec site to find places that a unique reference to this ref site are *unconditionally* decorated. -} +{-- lookup dec site to find places that a shared reference to this tree are *unconditionally* decorated. -} monoid attribute refDecSiteContribs :: [(String, VertexType)]; {-- lookup (prod, sig) to find source production and vertex type where sig was previously decorated -} diff --git a/grammars/silver/compiler/definition/flow/env/DecSites.sv b/grammars/silver/compiler/definition/flow/env/DecSites.sv index 268ccf6b2..a2d73a1fa 100644 --- a/grammars/silver/compiler/definition/flow/env/DecSites.sv +++ b/grammars/silver/compiler/definition/flow/env/DecSites.sv @@ -56,17 +56,9 @@ DecSiteTree ::= prodName::String vt::VertexType seen::[(String, VertexType)] flo -- Via signature/dispatch sharing | rhsVertexType(sigName) when lookupSignatureInputElem(sigName, ns).elementShared -> foldAllDecSite(unzipWith(recurse, - -- places where this child was decorated in a production forwarding to this one - lookupSigShareSites(prodName, sigName, flowEnv) ++ + -- places where this child was decorated in a production forwarding to this one, -- or in a dispatch signature that this production implements - case getValueDcl(prodName, realEnv) of - | dcl :: _ when dcl.implementedSignature matches just(sig) -> - lookupSigShareSites( - sig.fullName, - head(drop(positionOf(sigName, dcl.namedSignature.inputNames), sig.inputNames)), - flowEnv) - | _ -> [] - end)) + lookupAllSigShareSites(prodName, sigName, flowEnv, realEnv))) | _ -> neverDec() end ++ -- Via direct sharing diff --git a/grammars/silver/compiler/definition/flow/env/FlowEnv.sv b/grammars/silver/compiler/definition/flow/env/FlowEnv.sv index adab9d172..5f0e6c9c9 100644 --- a/grammars/silver/compiler/definition/flow/env/FlowEnv.sv +++ b/grammars/silver/compiler/definition/flow/env/FlowEnv.sv @@ -110,6 +110,19 @@ fun lookupRefDecSite [VertexType] ::= prod::String v::VertexType e::FlowEnv = fun lookupSigShareSites [(String, VertexType)] ::= prod::String sigName::String e::FlowEnv = searchEnvTree(crossnames(prod, sigName), e.sigShareTree); +fun lookupAllSigShareSites [(String, VertexType)] ::= prod::String sigName::String e::FlowEnv realEnv::Env = + -- places where this child was decorated in a production forwarding to this one + lookupSigShareSites(prod, sigName, e) ++ + -- or in a dispatch signature that this production implements + case getValueDcl(prod, realEnv) of + | dcl :: _ when dcl.implementedSignature matches just(sig) -> + lookupSigShareSites( + sig.fullName, + head(drop(positionOf(sigName, dcl.namedSignature.inputNames), sig.inputNames)), + e) + | _ -> [] + end; + -- inherited equation for some arbitrary vertex type fun vertexHasInhEq Boolean ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv = case vt of @@ -131,6 +144,29 @@ fun vertexHasInhEq Boolean ::= prodName::String vt::VertexType attrName::Strin | forwardVertexType_real() -> false -- Same as LHS, but we can check this if e.g. forwarding to a child. end; +-- used for duplicate equations checks +fun countVertexEqs Integer ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv realEnv::Env = + case vt of + | rhsVertexType(sigName) -> + length(lookupInh(prodName, sigName, attrName, flowEnv)) + + let sites :: [(String, VertexType)] = + lookupAllSigShareSites(prodName, sigName, flowEnv, realEnv) + in + if !null(sites) && all(unzipWith(vertexHasInhEq(_, _, attrName, flowEnv), sites)) + then 1 else 0 + end + | localVertexType(fName) -> length(lookupLocalInh(prodName, fName, attrName, flowEnv)) + | transAttrVertexType(rhsVertexType(sigName), transAttr) -> + length(lookupInh(prodName, sigName, s"${transAttr}.${attrName}", flowEnv)) + | transAttrVertexType(localVertexType(fName), transAttr) -> + length(lookupLocalInh(prodName, fName, s"${transAttr}.${attrName}", flowEnv)) + | transAttrVertexType(_, _) -> 0 + | anonVertexType(fName) -> length(lookupLocalInh(prodName, fName, attrName, flowEnv)) + | subtermVertexType(_, remoteProdName, sigName) -> 0 + | lhsVertexType_real() -> length(lookupSyn(prodName, attrName, flowEnv)) + | forwardVertexType_real() -> length(lookupFwdInh(prodName, attrName, flowEnv)) + end; + -- default set of inherited attributes required/assumed to exist for references fun getInhsForNtRef [[String]] ::= nt::String e::FlowEnv = searchEnvTree(nt, e.refTree); diff --git a/test/flow/RefSiteProj.sv b/test/flow/RefSiteProj.sv index 1e5a04074..2b2d75557 100644 --- a/test/flow/RefSiteProj.sv +++ b/test/flow/RefSiteProj.sv @@ -244,6 +244,7 @@ top::RSExpr ::= e::RSExpr dispatch UnaryOp = RSExpr ::= @e::RSExpr; +warnCode "Duplicate equation for env2 on e in production flow:implProd" { production implProd implements UnaryOp top::RSExpr ::= @e::RSExpr { @@ -251,6 +252,7 @@ top::RSExpr ::= @e::RSExpr top.errors1 = e.errors1; top.errors2 = e.errors2; } +} production dispatchOverrideKnownProd top::RSExpr ::= e::RSExpr From de71b1c33f4c94836036d1b2aa15a4c44b7da61a Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 24 Apr 2024 17:52:22 -0500 Subject: [PATCH 249/283] Fix up stitch points for dispatch/signature sharing, handle forwarding directly to an impl prod --- .../compiler/analysis/warnings/flow/Inh.sv | 27 +++++--- .../compiler/definition/flow/ast/Flow.sv | 2 +- .../definition/flow/driver/ProductionGraph.sv | 66 ++++++++++++------- .../compiler/definition/flow/env/DecSites.sv | 30 ++++++++- .../compiler/definition/flow/env/Expr.sv | 9 ++- test/flow/RefSiteProj.sv | 4 +- 6 files changed, 96 insertions(+), 42 deletions(-) diff --git a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv index 5e3797573..60d99420d 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Inh.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Inh.sv @@ -265,8 +265,8 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr -- Make sure we aren't introducing any hidden transitive dependencies. local refDecSiteInhDepsLhsInh :: Maybe> = - case filter( - notSharedInputVertex(_, top.env), + case filter(\ v::VertexType -> + resolvePossibleInhEq(top.frame.fullName, v, attr.attrDcl.fullName, top.flowEnv, top.env) == alwaysDec(), lookupRefPossibleDecSites(top.frame.fullName, dl.defLHSVertex, top.flowEnv)) of | [] -> nothing() | vs -> just(onlyLhsInh(expandGraph( @@ -278,13 +278,13 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr local transBaseRefDecSiteInhDepsLhsInh :: Maybe> = case dl.defLHSVertex of | transAttrVertexType(v, transAttr) -> - case filter( - notSharedInputVertex(_, top.env), - lookupRefPossibleDecSites(top.frame.fullName, dl.defLHSVertex, top.flowEnv)) of + case filter(\ v::VertexType -> + resolvePossibleInhEq(top.frame.fullName, v, dl.inhAttrName, top.flowEnv, top.env) == alwaysDec(), + lookupRefPossibleDecSites(top.frame.fullName, v, top.flowEnv)) of | [] -> nothing() | vs -> just(onlyLhsInh(expandGraph( v.eqVertex ++ - map(\ v::VertexType -> v.inhVertex(transAttr ++ "." ++ attr.attrDcl.fullName), vs), + map(\ v::VertexType -> v.inhVertex(dl.inhAttrName), vs), top.frame.flowGraph))) end | _ -> nothing() @@ -360,7 +360,8 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr [mwdaWrnFromOrigin(top, s"Inherited override equation for ${attr.attrDcl.fullName} on ${dl.defLHSVertex.vertexPP} may exceed a flow type " ++ s"with hidden transitive dependencies on ${implode(", ", lhsInhExceedsRefDecSiteDeps)}; " ++ - s"on some reference to this tree, this attribute may be expected to depend ${depListStr(refDecSiteInhDepsLhsInh.fromJust)}")] + s"on some reference to this tree, this attribute may be expected to depend ${depListStr(refDecSiteInhDepsLhsInh.fromJust)}" ++ + s" (from ${implode(", ", map((.vertexPP), lookupRefPossibleDecSites(top.frame.fullName, dl.defLHSVertex, top.flowEnv)))})")] else []; top.errors <- case dl.defLHSVertex of @@ -369,7 +370,8 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr [mwdaWrnFromOrigin(top, s"Inherited override equation for ${transAttr}.${attr.attrDcl.fullName} on ${v.vertexPP} may exceed a flow type " ++ s"with hidden transitive dependencies on ${implode(", ", lhsInhExceedsTransBaseRefDecSiteDeps)}; " ++ - s"on some reference to this tree, this attribute may be expected to depend ${depListStr(transBaseRefDecSiteInhDepsLhsInh.fromJust)}")] + s"on some reference to this tree, this attribute may be expected to depend ${depListStr(transBaseRefDecSiteInhDepsLhsInh.fromJust)}" ++ + s" (from ${implode(", ", map((.vertexPP), lookupRefPossibleDecSites(top.frame.fullName, v, top.flowEnv)))})")] | _ -> [] end; top.errors <- @@ -378,7 +380,8 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr [mwdaWrnFromOrigin(top, s"Inherited override equation for ${attr.attrDcl.fullName} on ${dl.defLHSVertex.vertexPP} may exceed a flow type " ++ s"with hidden transitive dependencies on ${implode(", ", lhsInhExceedsDispatchHostSigInhDeps)}; " ++ - s"on some reference to this tree, this attribute may be expected to depend ${depListStr(dispatchHostSigInhDepsLhsInh.fromJust)}")] + s"on some reference to this tree, this attribute may be expected to depend ${depListStr(dispatchHostSigInhDepsLhsInh.fromJust)}" ++ + s" (from ${sig.fullName})")] | _ -> [] end; } @@ -389,7 +392,7 @@ fun depListStr String ::= deps::set:Set = | deps -> "only on " ++ implode(", ", deps) end; -fun notSharedInputVertex Boolean ::= v::VertexType env::Env = +fun vertexHasPossibleInhEq Boolean ::= v::VertexType env::Env = case v of | subtermVertexType(_, prodName, sigName) -> case getTypeDcl(prodName, env), getValueDcl(prodName, env) of @@ -464,6 +467,8 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr if dl.name != "forward" || null(lhsInhExceedsForwardFlowType) then [] else [mwdaWrnFromOrigin(top, "Forward inherited equation for " ++ dl.inhAttrName ++ " exceeds flow type with dependencies on " ++ implode(", ", lhsInhExceedsForwardFlowType))] else []; + + -- TOOD: Hidden transitive deps check? } aspect production inhAppendColAttributeDef top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr @@ -490,6 +495,8 @@ top::ProductionStmt ::= @dl::DefLHS @attr::QNameAttrOccur e::Expr if dl.name != "forward" || null(lhsInhExceedsForwardFlowType) then [] else [mwdaWrnFromOrigin(top, "Forward inherited equation exceeds for " ++ dl.inhAttrName ++ " flow type with dependencies on " ++ implode(", ", lhsInhExceedsForwardFlowType))] else []; + + -- TOOD: Hidden transitive deps check? } ------ END AWFUL COPY & PASTE SESSION diff --git a/grammars/silver/compiler/definition/flow/ast/Flow.sv b/grammars/silver/compiler/definition/flow/ast/Flow.sv index da59f6a93..e0e5acc5c 100644 --- a/grammars/silver/compiler/definition/flow/ast/Flow.sv +++ b/grammars/silver/compiler/definition/flow/ast/Flow.sv @@ -152,7 +152,7 @@ abstract production implFlowDef top::FlowDef ::= dispatchSig::String prod::String { top.implTreeContribs := [(dispatchSig, prod)]; - top.prodGraphContribs := []; + top.prodGraphContribs := [(dispatchSig, top)]; top.flowEdges = error("Internal compiler error: this sort of def should not be in a context where edges are requested."); } diff --git a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv index 2402ecbe0..b1743f730 100644 --- a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv @@ -147,12 +147,7 @@ ProductionGraph ::= dcl::ValueDclInfo flowEnv::FlowEnv realEnv::Env -- The name of this production local prod :: String = dcl.fullName; -- The flow defs for this production - local defs :: [FlowDef] = - getGraphContribsFor(prod, flowEnv) ++ - case dcl.implementedSignature of - | just(sig) -> getGraphContribsFor(sig.fullName, flowEnv) - | nothing() -> [] - end; + local defs :: [FlowDef] = getGraphContribsFor(prod, flowEnv); -- The LHS nonterminal full name local nt :: NtName = dcl.namedSignature.outputElement.typerep.typeName; -- Just synthesized attributes. @@ -194,7 +189,14 @@ ProductionGraph ::= dcl::ValueDclInfo flowEnv::FlowEnv realEnv::Env localStitchPoints(realEnv, nt, defs) ++ patternStitchPoints(realEnv, defs) ++ subtermDecSiteStitchPoints(flowEnv, realEnv, defs) ++ - sigSharingStitchPoints(flowEnv, realEnv, defs); + sigSharingStitchPoints(flowEnv, realEnv, defs) ++ + case dcl.implementedSignature of + | just(sig) -> concat(zipWith( + implementedSigStitchPoints(realEnv, _, sig.fullName, _), + dcl.namedSignature.inputElements, + sig.inputElements)) + | nothing() -> [] + end; local flowTypeVertexesOverall :: [FlowVertex] = (if nonForwarding then [] else [forwardEqVertex()]) ++ @@ -369,13 +371,14 @@ ProductionGraph ::= ns::NamedSignature flowEnv::FlowEnv realEnv::Env { local dispatch :: String = ns.fullName; local nt :: NtName = ns.outputElement.typerep.typeName; - local implProds :: [String] = getImplementingProds(dispatch, flowEnv); + local defs :: [FlowDef] = getGraphContribsFor(dispatch, flowEnv); -- The graph has no normal edges, only projection stitch points! local normalEdges :: [(FlowVertex, FlowVertex)] = []; local stitchPoints :: [StitchPoint] = - flatMap(dispatchStitchPoints(ns, flowEnv, realEnv, _), implProds); + sigSharingStitchPoints(flowEnv, realEnv, defs) ++ -- where this dispatch is applied + dispatchStitchPoints(flowEnv, realEnv, ns, defs); -- impls of this dispatch local flowTypeVertexes :: [FlowVertex] = []; -- Doesn't (directly) affect flow types local initialGraph :: g:Graph = createFlowGraph(normalEdges); @@ -510,6 +513,7 @@ fun patVarStitchPoints [StitchPoint] ::= matchProd::String scrutinee::VertexTyp getInhAndInhOnTransAttrsOn(typeName, realEnv)) :: nonterminalStitchPoints(realEnv, typeName, anonVertexType(patternVar)) end; +-- deps for subterm vertex of applied prod fun subtermDecSiteStitchPoints [StitchPoint] ::= flowEnv::FlowEnv realEnv::Env defs::[FlowDef] = flatMap(\ d::FlowDef -> case d of @@ -520,6 +524,7 @@ fun subtermDecSiteStitchPoints [StitchPoint] ::= flowEnv::FlowEnv realEnv::Env | _ -> [] end, defs); +-- deps for prod/dispatch sig, from prods that forwarded to it fun sigSharingStitchPoints [StitchPoint] ::= flowEnv::FlowEnv realEnv::Env defs::[FlowDef] = flatMap(\ d::FlowDef -> case d of @@ -530,22 +535,33 @@ fun sigSharingStitchPoints [StitchPoint] ::= flowEnv::FlowEnv realEnv::Env def | _ -> [] end, defs); -fun dispatchStitchPoints [StitchPoint] ::= dispatch::NamedSignature flowEnv::FlowEnv realEnv::Env prod::String = - case getValueDcl(prod, realEnv) of - | dcl :: _ -> - flatMap(\ ie::NamedSignatureElement -> - if ie.elementDclType.isNonterminal -- Dispatch sigs can't have occurs-on constraints - then [projectionStitchPoint( - prod, rhsVertexType(ie.elementName), lhsVertexType, - rhsVertexType( - head(drop(positionOf(ie.elementName, dispatch.inputNames), dcl.namedSignature.inputNames))), - getInhAndInhOnTransAttrsOn( - lookupSignatureInputElem(ie.elementName, dispatch).typerep.typeName, - realEnv))] - else [], - dispatch.inputElements) - | _ -> [] - end; +-- deps for child of prod, from dispatch sig that prod implements +fun implementedSigStitchPoints [StitchPoint] ::= realEnv::Env ie::NamedSignatureElement prod::String se::NamedSignatureElement = + if ie.typerep.isNonterminal + then [projectionStitchPoint( + prod, rhsVertexType(ie.elementName), lhsVertexType, + rhsVertexType(se.elementName), + getInhAndInhOnTransAttrsOn(ie.typerep.typeName, realEnv))] + else []; +-- deps for dispatch sig, from prods that implement it +fun dispatchStitchPoints [StitchPoint] ::= flowEnv::FlowEnv realEnv::Env dispatch::NamedSignature defs::[FlowDef] = + flatMap(\ d::FlowDef -> + case d of + | implFlowDef(_, prod) when getValueDcl(prod, realEnv) matches dcl :: _ -> + flatMap(\ ie::NamedSignatureElement -> + if ie.elementDclType.isNonterminal -- Dispatch sigs can't have occurs-on constraints + then [projectionStitchPoint( + prod, rhsVertexType(ie.elementName), lhsVertexType, + rhsVertexType( + head(drop(positionOf(ie.elementName, dispatch.inputNames), dcl.namedSignature.inputNames))), + getInhAndInhOnTransAttrsOn( + lookupSignatureInputElem(ie.elementName, dispatch).typerep.typeName, + realEnv))] + else [], + dispatch.inputElements) + | _ -> [] + end, + defs); ---- End helpers for figuring our stitch points -------------------------------- diff --git a/grammars/silver/compiler/definition/flow/env/DecSites.sv b/grammars/silver/compiler/definition/flow/env/DecSites.sv index a2d73a1fa..489cb30b3 100644 --- a/grammars/silver/compiler/definition/flow/env/DecSites.sv +++ b/grammars/silver/compiler/definition/flow/env/DecSites.sv @@ -75,6 +75,8 @@ DecSiteTree ::= prodName::String vt::VertexType seen::[(String, VertexType)] flo getHostSynsFor(ntName, flowEnv))); } +-- Flatten a resolved decision tree, to determine the minimal places where an +-- equation is needed. strategy attribute reduceDecSite = innermost( -- TODO: Avoid forcing the entire tree if the first dec site is supplied? rule on DecSiteTree of | altDec(alwaysDec(), d) -> alwaysDec() @@ -104,6 +106,9 @@ top::DecSiteTree ::= _ d::DecSiteTree } attribute flowEnv occurs on DecSiteTree; + +-- Resolve the decision tree for a particular attribute, replacing decoration +-- sites known to be supplied with alwaysDec(). strategy attribute resolveDecSite = allTopDown( rule on top::DecSiteTree of | directDec(prodName, vt) @@ -122,7 +127,16 @@ strategy attribute resolveDecSite = allTopDown( ) <* reduceDecSite occurs on DecSiteTree; -propagate flowEnv, reduceDecSite, resolveDecSite on DecSiteTree; +-- If one is interested in whether an attribute might possibly be supplied +-- rather than if it is always present, replace all instances of bothDec with altDec. +strategy attribute asPossibleDec = allTopDown( + rule on DecSiteTree of + | bothDec(d1, d2) -> altDec(d1, d2) + end +) occurs on DecSiteTree; + +propagate flowEnv, reduceDecSite, resolveDecSite, asPossibleDec + on DecSiteTree; {-- - Determine if some decoration site has some inherited attribute supplied. @@ -155,6 +169,20 @@ fun resolveInhEq DecSiteTree ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv realEnv::Env = resolveDecSiteInhEq(attrName, findDecSites(prodName, vt, [], flowEnv, realEnv), flowEnv); +{-- + - Determine if some flow vertex type in a production might have an inherited attribute supplied. + - + - @param prodName The name of the production containing the vertex. + - @param vt The vertex type to check. + - @param attrName The name of the inherited attribute. + - @param flowEnv The flow environment. + - @return alwaysDec(), if the attribute is ever present, + - or else the places where it could be supplied. + -} +fun resolvePossibleInhEq +DecSiteTree ::= prodName::String vt::VertexType attrName::String flowEnv::FlowEnv realEnv::Env = + resolveDecSiteInhEq(attrName, findDecSites(prodName, vt, [], flowEnv, realEnv).asPossibleDec, flowEnv); + -- Helper for checking multiple inh attributes function decSitesMissingInhEqs [(DecSiteTree, [String])] ::= prodName::String vt::VertexType attrNames::[String] flowEnv::FlowEnv realEnv::Env diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index 902a34e13..c7ae10df4 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -232,7 +232,7 @@ aspect production presentAppExpr top::AppExpr ::= e::Expr { production sigIndex::Integer = top.appExprIndex + top.appIndexOffset; - production sigName::String = + production sigName::String = -- Name of the corresponding child of the production/dispatch being applied case top.appProd of | just(ns) when sigIndex < length(ns.inputNames) -> head(drop(sigIndex, ns.inputNames)) | _ -> "err" @@ -245,7 +245,10 @@ top::AppExpr ::= e::Expr end; e.decSiteVertexInfo = case top.decSiteVertexInfo, top.appProd of - | just(parent), just(ns) when isDecorable(e.finalType, top.env) -> + | just(parent), just(ns) + when isDecorable( + if sigIsShared then e.finalType.decoratedType else e.finalType, + top.env) -> just(subtermVertexType(parent, ns.fullName, sigName)) | _, _ -> nothing() end; @@ -275,7 +278,7 @@ top::AppExpr ::= e::Expr | just(parent), just(ns), just(v) when sigIsShared && isForwardParam -> refDecSiteEq( top.frame.fullName, e.typerep.typeName, v, - subtermVertexType(parent, ns.fullName, sigName), true) :: + subtermVertexType(parent, ns.fullName, sigName), top.alwaysDecorated) :: if inputSigIsShared then [] else [sigShareSite(ns.fullName, e.typerep.typeName, sigName, top.frame.fullName, v, parent)] | _, _, _ -> [] diff --git a/test/flow/RefSiteProj.sv b/test/flow/RefSiteProj.sv index 2b2d75557..18cc2c779 100644 --- a/test/flow/RefSiteProj.sv +++ b/test/flow/RefSiteProj.sv @@ -258,7 +258,7 @@ production dispatchOverrideKnownProd top::RSExpr ::= e::RSExpr { e.env1 = top.env1; - e.env2 = top.env2; + e.env2 = top.env1 ++ top.env2; forwards to implProd(e); } @@ -266,7 +266,7 @@ production dispatchOverrideUnknownProd top::RSExpr ::= e::RSExpr { e.env1 = top.env1; - e.env2 = top.env2; + e.env2 = top.env1 ++ top.env2; local implProdRef::UnaryOp = implProd; forwards to implProdRef(e); } From f184eb5ffbefa66f11113f05985be9a75ba44ba4 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 25 Apr 2024 10:26:50 -0500 Subject: [PATCH 250/283] Refactor and update orphaned sharing checks, tests passing --- .../compiler/analysis/uniqueness/Expr.sv | 76 +++++++++++-------- .../flow/{SigSharing.sv => Sharing.sv} | 45 ++++++++++- test/flow/Dispatch.sv | 56 +++++++++----- 3 files changed, 127 insertions(+), 50 deletions(-) rename grammars/silver/compiler/analysis/warnings/flow/{SigSharing.sv => Sharing.sv} (51%) diff --git a/grammars/silver/compiler/analysis/uniqueness/Expr.sv b/grammars/silver/compiler/analysis/uniqueness/Expr.sv index d61e3e166..35e3a8cc8 100644 --- a/grammars/silver/compiler/analysis/uniqueness/Expr.sv +++ b/grammars/silver/compiler/analysis/uniqueness/Expr.sv @@ -16,45 +16,20 @@ top::Expr ::= '@' e::Expr | nothing() -> [] end; - -- Grammars that can validly share this vertex - local vertexGrammars::[String] = - case e.flowVertexInfo of - | just(rhsVertexType(_)) -> [top.frame.sourceGrammar] - | just(localVertexType(fName)) when getValueDcl(fName, top.env) matches valDcl :: _ -> [valDcl.sourceGrammar] - | just(transAttrVertexType(rhsVertexType(sigName), transAttr)) -> - top.frame.sourceGrammar :: - case lookup(sigName, zip(top.frame.signature.inputNames, top.frame.signature.inputTypes)) of - | just(t) when getOccursDcl(transAttr, t.typeName, top.env) matches dcl :: _ -> - [dcl.sourceGrammar] - | _ -> [] - end - | just(transAttrVertexType(localVertexType(fName), transAttr)) -> - implode(":", init(explode(":", fName))) :: - case getValueDcl(fName, top.env) of - | valDcl :: _ when getOccursDcl(transAttr, valDcl.typeScheme.monoType.typeName, top.env) matches dcl :: _ -> - [dcl.sourceGrammar] - | _ -> [] - end - | _ -> [] - end; - top.errors <- case e.flowVertexInfo of + -- These are errors because we assume these checks in the translation: | just(lhsVertexType_real()) -> [errFromOrigin(e, s"Cannot share the production LHS.")] | just(forwardVertexType_real()) -> [errFromOrigin(e, s"Cannot share the forward tree.")] - | just(anonVertexType(_)) -> [errFromOrigin(e, s"Cannot share an anonymously decorated tree.")] -- TODO: Not too hard to support? + | just(anonVertexType(_)) -> [errFromOrigin(e, s"Cannot share an anonymously decorated tree.")] -- TODO: I think this works now? | just(v) -> - -- Check that we are exported by the decoration site. - if !isExportedBy(top.grammarName, vertexGrammars, top.compiledGrammars) - then [errFromOrigin(top, s"Orphaned sharing of ${v.vertexPP} in production ${top.frame.fullName}.")] - -- Check that there is at most one unique reference taken to this decoration site. - else + -- Check that this tree is shared in at most one non-mutually-exclusive place. case lookupSharedRefs(top.frame.fullName, v, top.flowEnv) of | [] -> [] -- Not possible? | [_] -> [] | srs -> [errFromOrigin(top, s"Tree ${v.vertexName} in production ${top.frame.fullName} is shared in multiple places:\n" ++ - implode("\n", map(\ sr::SharedRefSite -> sr.sourceGrammar ++ ":" ++ sr.sourceLocation.unparse ++ "\n", srs)))] + flatMap(\ sr::SharedRefSite -> "\t" ++ sr.sourceGrammar ++ ":" ++ sr.sourceLocation.unparse ++ "\n", srs))] end | nothing() -> [errFromOrigin(e, s"This is not something that can be shared; shared trees must correspond to a known decoration site.")] end; @@ -71,7 +46,48 @@ top::Expr ::= '@' e::Expr aspect production presentAppExpr top::AppExpr ::= e::Expr { - -- TODO: Handle signature sharing + -- This mirrors the above, but for signature sharing: + top.sharedRefs <- + case e.flowVertexInfo of + | just(v) when sigIsShared && isForwardParam -> + [(top.frame.fullName ++ ":" ++ v.vertexName, + sharedRefSite( + sourceGrammar=top.grammarName, + sourceLocation=getParsedOriginLocationOrFallback(top) + ))] + | _ -> [] + end; + + top.errors <- + if sigIsShared && isForwardParam then + case e.flowVertexInfo of + -- These are errors because we assume these checks in the translation: + | just(lhsVertexType_real()) -> [errFromOrigin(e, s"Cannot share the production LHS.")] + | just(forwardVertexType_real()) -> [errFromOrigin(e, s"Cannot share the forward tree.")] + | just(anonVertexType(_)) -> [errFromOrigin(e, s"Cannot share an anonymously decorated tree.")] -- TODO: I think this works now? + | just(v) -> + -- Check that this tree is shared in at most one non-mutually-exclusive place. + case lookupSharedRefs(top.frame.fullName, v, top.flowEnv) of + | [] -> [] -- Not possible? + | [_] -> [] + | srs -> [errFromOrigin(top, + s"Tree ${v.vertexName} in production ${top.frame.fullName} is shared in multiple places:\n" ++ + flatMap(\ sr::SharedRefSite -> "\t" ++ sr.sourceGrammar ++ ":" ++ sr.sourceLocation.unparse ++ "\n", srs))] + end + | nothing() -> [errFromOrigin(e, s"This is not something that can be shared; shared trees must correspond to a known decoration site.")] + end + else []; + + top.errors <- + case e.flowVertexInfo of + | just(transAttrVertexType(v, transAttr)) when sigIsShared && isForwardParam -> + case lookupSharedRefs(top.frame.fullName, v, top.flowEnv) of + | sr :: _ -> + [errFromOrigin(e, s"Cannot share ${v.vertexName}.${transAttr} in production ${top.frame.fullName}, because ${v.vertexPP} is also shared (at ${sr.sourceGrammar}:${sr.sourceLocation.unparse}).")] + | _ -> [] + end + | _ -> [] + end; } aspect production ifThenElse diff --git a/grammars/silver/compiler/analysis/warnings/flow/SigSharing.sv b/grammars/silver/compiler/analysis/warnings/flow/Sharing.sv similarity index 51% rename from grammars/silver/compiler/analysis/warnings/flow/SigSharing.sv rename to grammars/silver/compiler/analysis/warnings/flow/Sharing.sv index 84030797d..4f84db6b8 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/SigSharing.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Sharing.sv @@ -22,7 +22,22 @@ Either ::= args::[String] flagParser=flag(warnSharingFlag))]; } +aspect production decorationSiteExpr +top::Expr ::= '@' e::Expr +{ + -- Check that we are exported by the decoration site. + top.errors <- + case e.flowVertexInfo of + | just(v) when + top.config.warnSharing && + !isExportedBy(top.grammarName, vertexGrammars(v, top.frame, top.env), top.compiledGrammars) -> + [mwdaWrnFromOrigin(top, s"Orphaned sharing of ${v.vertexPP} in production ${top.frame.fullName}.")] + | _ -> [] + end; +} + -- TODO: Handle dependencies for inh overrides on forward/forward prod attrs +-- TODO: I forgot what the above TODO was about aspect production productionReference top::Expr ::= @q::QName { @@ -55,10 +70,36 @@ top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs aspect production presentAppExpr top::AppExpr ::= e::Expr { + -- Check that we are exported by the decoration site. top.errors <- case e.flowVertexInfo of - | nothing() when top.config.warnSharing && sigIsShared -> - [mwdaWrnFromOrigin(e, "Shared tree must correspond to a known decoration site")] + | just(v) when + top.config.warnSharing && + sigIsShared && isForwardParam && + !isExportedBy(top.grammarName, vertexGrammars(v, top.frame, top.env), top.compiledGrammars) -> + [mwdaWrnFromOrigin(top, s"Orphaned sharing of ${v.vertexPP} in production ${top.frame.fullName}.")] | _ -> [] end; } + +-- Grammars that can validly share a vertex +fun vertexGrammars [String] ::= v::VertexType frame::BlockContext env::Env = + case v of + | rhsVertexType(_) -> [frame.sourceGrammar] + | localVertexType(fName) when getValueDcl(fName, env) matches valDcl :: _ -> [valDcl.sourceGrammar] + | transAttrVertexType(rhsVertexType(sigName), transAttr) -> + frame.sourceGrammar :: + case lookup(sigName, zip(frame.signature.inputNames, frame.signature.inputTypes)) of + | just(t) when getOccursDcl(transAttr, t.typeName, env) matches dcl :: _ -> + [dcl.sourceGrammar] + | _ -> [] + end + | transAttrVertexType(localVertexType(fName), transAttr) -> + implode(":", init(explode(":", fName))) :: + case getValueDcl(fName, env) of + | valDcl :: _ when getOccursDcl(transAttr, valDcl.typeScheme.monoType.typeName, env) matches dcl :: _ -> + [dcl.sourceGrammar] + | _ -> [] + end + | _ -> [] + end; diff --git a/test/flow/Dispatch.sv b/test/flow/Dispatch.sv index de6c4715f..7a2859533 100644 --- a/test/flow/Dispatch.sv +++ b/test/flow/Dispatch.sv @@ -5,17 +5,45 @@ synthesized attribute errors2::Boolean; nonterminal UDExpr with env1, env2, errors1, errors2; -production overloadThing +production directOverloadThing top::UDExpr ::= e::UDExpr { e.env1 = top.env1; - e.env2 = []; - forwards to dispatchThing(e); + top.errors2 = e.errors2; + forwards to shareThing(e); } -production dispatchThing +production indirectOverloadThing +top::UDExpr ::= e::UDExpr +{ + e.env1 = top.env1; + top.errors2 = e.errors2; + local prod::DispatchOp = if e.errors1 then dispatchThing1 else dispatchThing2; + forwards to prod(e); +} + +production shareThing +top::UDExpr ::= @e::UDExpr +{ + e.env2 = top.env2; + top.errors1 = e.errors1; + top.errors2 = !null(e.env1); +} + +dispatch DispatchOp = UDExpr ::= @e1::UDExpr; + +production dispatchThing1 implements DispatchOp top::UDExpr ::= @e::UDExpr { + e.env2 = top.env2; + top.errors1 = e.errors1; + top.errors2 = !null(e.env1); +} + +production dispatchThing2 implements DispatchOp +top::UDExpr ::= @e::UDExpr +{ + e.env2 = top.env1; top.errors1 = e.errors1; top.errors2 = !null(e.env1); } @@ -26,12 +54,12 @@ top::UDExpr ::= e::UDExpr { local otherRef::UDExpr = @e; e.env1 = top.env1; - forwards to dispatchThing(e); + forwards to shareThing(e); } } -wrongFlowCode "Tree e in production flow:dispatchThing is shared in multiple places" { -aspect production dispatchThing +wrongFlowCode "Tree e in production flow:shareThing2 is shared in multiple places" { +production shareThing2 top::UDExpr ::= @e::UDExpr { local otherRef::UDExpr = @e; @@ -39,19 +67,11 @@ top::UDExpr ::= @e::UDExpr } } -warnCode "Duplicate equation for env2 on e in production flow:alreadyDec" { -production alreadyDec -top::UDExpr ::= @e::UDExpr -{ - e.env2 = []; -} -} - -wrongFlowCode "Unique reference to flow:uniqueReturn:e taken outside of a unique context. The return of flow:uniqueReturn is not a unique context as this function has no unique parameters." { -function uniqueReturn +warnCode "Production shareThing has shared children in its signature, and can only be applied in the root position of a forward or forward production attribute equation" { +function dispatchFunction UDExpr ::= e::UDExpr { e.env1 = []; - return dispatchThing(e); + return shareThing(e); } } From f4b5aa60998fff12bf8cd0250f2574d371a43aab Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 25 Apr 2024 14:23:48 -0500 Subject: [PATCH 251/283] Implement undecoration behavior for implementation productions --- .../compiler/translation/java/core/ProductionDcl.sv | 4 +++- runtime/java/src/common/DecoratedNode.java | 13 +++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv index 9a8da6b41..968970a1e 100644 --- a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv +++ b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv @@ -185,7 +185,9 @@ ${flatMap(makeInhOccursContextAccess(namedSig.freeVariables, namedSig.contextInh ${if isData then "" else s""" @Override public common.Node evalUndecorate(final common.DecoratedNode context) { - ${if !null(decorableChildren) + ${if any(map((.elementShared), namedSig.inputElements)) + then "return context.getForwardParent().undecorate();" + else if !null(decorableChildren) then s"return new ${className}(${implode(", ", -- An implicitly undecorated production node has the same origin as the original node. -- This will be overidden by duplicate when calling new(). diff --git a/runtime/java/src/common/DecoratedNode.java b/runtime/java/src/common/DecoratedNode.java index 4704f9745..b03c9d1d4 100644 --- a/runtime/java/src/common/DecoratedNode.java +++ b/runtime/java/src/common/DecoratedNode.java @@ -278,6 +278,19 @@ public final Node getNode() { return self; } + /** + * Accessor function to access the tree that forwarded to this one. + * This is currently only used in undecorating productions with shared children. + * + * @return The parent of this DecoratedNode. + */ + public final DecoratedNode getForwardParent() { + if (forwardParent == null) { + throw new SilverInternalError("Attempted to access forwardParent of " + getDebugID() + ", which is not a forward tree."); + } + return forwardParent; + } + /** * Returns the child of this DecoratedNode, decorating it if needed. * From 35e6dd155a8236edd9cced560b0c1cbf3b039819 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 25 Apr 2024 14:24:11 -0500 Subject: [PATCH 252/283] Updating tests --- .../{UniqueDec.sv => TreeSharing.sv} | 31 ++++------ test/silver_features/UndecoratesTo.sv | 56 ------------------- 2 files changed, 11 insertions(+), 76 deletions(-) rename test/silver_features/{UniqueDec.sv => TreeSharing.sv} (72%) delete mode 100644 test/silver_features/UndecoratesTo.sv diff --git a/test/silver_features/UniqueDec.sv b/test/silver_features/TreeSharing.sv similarity index 72% rename from test/silver_features/UniqueDec.sv rename to test/silver_features/TreeSharing.sv index 21ecae532..1bfbabbd8 100644 --- a/test/silver_features/UniqueDec.sv +++ b/test/silver_features/TreeSharing.sv @@ -20,9 +20,8 @@ top::UDExpr ::= e::UDExpr } production udOp1Impl -top::UDExpr ::= e::Decorated! UDExpr with {env1} +top::UDExpr ::= @e::UDExpr { - undecorates to udOp1(e); e.env2 = top.env2; top.errors1 = e.errors1; top.errors2 = e.errors2; @@ -36,10 +35,9 @@ top::UDExpr ::= e::UDExpr } production udOp2Impl -top::UDExpr ::= e::Decorated! UDExpr with {env1} +top::UDExpr ::= @e::UDExpr { - undecorates to udOp2(e); - local e2::Decorated! UDExpr with {env1} = e; + local e2::UDExpr = @e; e2.env2 = top.env2; top.errors1 = e2.errors1; top.errors2 = e2.errors2; @@ -54,32 +52,29 @@ top::UDExpr ::= e::UDExpr } production udOp3Impl -top::UDExpr ::= e::Decorated! UDExpr with {env1} +top::UDExpr ::= @e::UDExpr { - undecorates to udOp3(e); - local e2::Decorated UDExpr = decorate withEnv1(e) with {env2 = top.env2;}; + --local e2::Decorated UDExpr = decorate @e with {env2 = top.env2;}; -- TODO + local e1::UDExpr = @e; + e1.env2 = top.env2; + local e2::UDExpr = @e1; top.errors1 = e2.errors1; top.errors2 = e2.errors2; } -function withEnv1 -Decorated! UDExpr with {env1} ::= x::Decorated! UDExpr with {env1} -{ return x; } - production udOp4 top::UDExpr ::= e::UDExpr { e.env1 = top.env1; - local e2::Decorated! UDExpr with {env1} = e; + local e2::UDExpr = @e; e2.env2 = top.env2; forwards to udOp4Impl(e2); } production udOp4Impl -top::UDExpr ::= e::Decorated! UDExpr +top::UDExpr ::= @e::UDExpr { - undecorates to udOp4(e); - local e2::Decorated! UDExpr = e; + local e2::UDExpr = @e; top.errors1 = e2.errors1; top.errors2 = e2.errors2; } @@ -91,7 +86,3 @@ equalityTest(decorate udTerm with { env1 = ["foo"]; env2 = []; }.errors1, false, equalityTest(decorate udTerm with { env1 = ["foo"]; env2 = []; }.errors2, true, Boolean, silver_tests); equalityTest(decorate udTerm with { env1 = []; env2 = ["foo"]; }.errors1, true, Boolean, silver_tests); equalityTest(decorate udTerm with { env1 = []; env2 = ["foo"]; }.errors2, true, Boolean, silver_tests); - -wrongCode "Cannot specialize" { - global uniqueRefId::(Decorated! UDExpr ::= Decorated! UDExpr) = id; -} diff --git a/test/silver_features/UndecoratesTo.sv b/test/silver_features/UndecoratesTo.sv deleted file mode 100644 index 64e207e56..000000000 --- a/test/silver_features/UndecoratesTo.sv +++ /dev/null @@ -1,56 +0,0 @@ -grammar silver_features; - -nonterminal UndecNT with compareTo, isEqual; -flowtype UndecNT = decorate {}; -propagate compareTo, isEqual on UndecNT; - -production fork1UNT -top::UndecNT ::= a::Decorated! UndecNT b::UndecNT -{ - undecorates to fork2UNT(a, b); -} - -production fork2UNT -top::UndecNT ::= a::UndecNT b::UndecNT -{ -} - -production leafUNT -top::UndecNT ::= -{} - -production wrapUNT -top::UndecNT ::= a::Decorated! UndecNT -{ - undecorates to a; -} - -equalityTest(fork2UNT(leafUNT(), leafUNT()), fork2UNT(leafUNT(), leafUNT()), UndecNT, silver_tests); - -function mkUNT1 -Decorated UndecNT ::= -{ - local a::UndecNT = leafUNT(); - local res::UndecNT = fork1UNT(a, leafUNT()); - return res; -} -equalityTest(new(mkUNT1()), fork2UNT(leafUNT(), leafUNT()), UndecNT, silver_tests); - -function mkUNT2 -Decorated UndecNT ::= -{ - local a::UndecNT = leafUNT(); - local res::UndecNT = wrapUNT(a); - return res; -} -equalityTest(new(mkUNT2()), leafUNT(), UndecNT, silver_tests); - -function mkUNT3 -Decorated UndecNT ::= -{ - local a::UndecNT = leafUNT(); - local res1::UndecNT = wrapUNT(a); - local res2::UndecNT = fork2UNT(fork1UNT(res1, leafUNT()), leafUNT()); - return res2; -} -equalityTest(new(mkUNT3()), fork2UNT(fork2UNT(leafUNT(), leafUNT()), leafUNT()), UndecNT, silver_tests); From 231b6a86a08155057dc5312a270a9babf0f998bd Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 25 Apr 2024 15:29:29 -0500 Subject: [PATCH 253/283] comment about flow errors in tests --- test/silver_features/TreeSharing.sv | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/silver_features/TreeSharing.sv b/test/silver_features/TreeSharing.sv index 1bfbabbd8..d1977b44c 100644 --- a/test/silver_features/TreeSharing.sv +++ b/test/silver_features/TreeSharing.sv @@ -27,6 +27,8 @@ top::UDExpr ::= @e::UDExpr top.errors2 = e.errors2; } +-- These work, but have flow errors since we don't do reverse sharing through locals: + production udOp2 top::UDExpr ::= e::UDExpr { From b432313dc8c6bcf89756065e8ae7c00ca8d78a70 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 25 Apr 2024 15:29:49 -0500 Subject: [PATCH 254/283] Fix cycle in implicit monads ext --- .../compiler/extension/implicit_monads/ProductionBody.sv | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv b/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv index 5d3d0c27b..4ac04576f 100644 --- a/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv +++ b/grammars/silver/compiler/extension/implicit_monads/ProductionBody.sv @@ -13,7 +13,7 @@ concrete production emptyAttributeDef top::ProductionStmt ::= 'implicit' dl::DefLHS '.' attr::QNameAttrOccur '=' ';' { top.unparse = "\timplicit " ++ dl.unparse ++ "." ++ attr.unparse ++ " = ;"; - propagate grammarName, compiledGrammars, config, frame, env, flowEnv, finalSubst; + propagate grammarName, compiledGrammars, config, frame, env, flowEnv; top.productionAttributes := []; top.defs := []; @@ -52,7 +52,7 @@ concrete production implicitAttributeDef top::ProductionStmt ::= 'implicit' dl::DefLHS '.' attr::QNameAttrOccur '=' e::Expr ';' { top.unparse = "\timplicit" ++ dl.unparse ++ "." ++ attr.unparse ++ " = ;"; - propagate grammarName, compiledGrammars, config, frame, env, flowEnv, finalSubst; + propagate grammarName, compiledGrammars, config, frame, env, flowEnv; top.productionAttributes := []; top.defs := []; @@ -92,7 +92,7 @@ top::ProductionStmt ::= 'restricted' dl::DefLHS '.' attr::QNameAttrOccur '=' e:: { e.downSubst = top.downSubst; top.unparse = "\trestricted" ++ dl.unparse ++ "." ++ attr.unparse ++ " = ;"; - propagate grammarName, compiledGrammars, config, frame, env, flowEnv, finalSubst; + propagate grammarName, compiledGrammars, config, frame, env, flowEnv; top.productionAttributes := []; top.defs := []; @@ -131,7 +131,7 @@ concrete production unrestrictedAttributeDef top::ProductionStmt ::= 'unrestricted' dl::DefLHS '.' attr::QNameAttrOccur '=' e::Expr ';' { top.unparse = "\tunrestricted" ++ dl.unparse ++ "." ++ attr.unparse ++ " = ;"; - propagate grammarName, compiledGrammars, config, frame, env, flowEnv, finalSubst; + propagate grammarName, compiledGrammars, config, frame, env, flowEnv; top.productionAttributes := []; top.defs := []; From 3811009cf94691b25bbb67f864d718088bf979dd Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Sat, 27 Apr 2024 12:22:45 -0500 Subject: [PATCH 255/283] Fix grammar for trans-on-local in orphaned sharing check --- .../silver/compiler/analysis/warnings/flow/Sharing.sv | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/grammars/silver/compiler/analysis/warnings/flow/Sharing.sv b/grammars/silver/compiler/analysis/warnings/flow/Sharing.sv index 4f84db6b8..aa1e41b44 100644 --- a/grammars/silver/compiler/analysis/warnings/flow/Sharing.sv +++ b/grammars/silver/compiler/analysis/warnings/flow/Sharing.sv @@ -94,11 +94,11 @@ fun vertexGrammars [String] ::= v::VertexType frame::BlockContext env::Env = [dcl.sourceGrammar] | _ -> [] end - | transAttrVertexType(localVertexType(fName), transAttr) -> - implode(":", init(explode(":", fName))) :: - case getValueDcl(fName, env) of - | valDcl :: _ when getOccursDcl(transAttr, valDcl.typeScheme.monoType.typeName, env) matches dcl :: _ -> - [dcl.sourceGrammar] + | transAttrVertexType(localVertexType(fName), transAttr) + when getValueDcl(fName, env) matches valDcl :: _ -> + valDcl.sourceGrammar :: + case getOccursDcl(transAttr, valDcl.typeScheme.monoType.typeName, env) of + | dcl :: _ -> [dcl.sourceGrammar] | _ -> [] end | _ -> [] From dda3268f4503b29d95547d4cd6acbd7c8a4995ca Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Sat, 27 Apr 2024 12:23:09 -0500 Subject: [PATCH 256/283] Purge remaining references to unique references in error messages/comments --- grammars/silver/compiler/definition/flow/ast/Flow.sv | 4 ++-- grammars/silver/compiler/extension/implicit_monads/Expr.sv | 2 +- grammars/silver/compiler/extension/rewriting/Expr.sv | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/grammars/silver/compiler/definition/flow/ast/Flow.sv b/grammars/silver/compiler/definition/flow/ast/Flow.sv index e0e5acc5c..6e249f62b 100644 --- a/grammars/silver/compiler/definition/flow/ast/Flow.sv +++ b/grammars/silver/compiler/definition/flow/ast/Flow.sv @@ -70,7 +70,7 @@ monoid attribute hostSynTreeContribs :: [(String, FlowDef)]; monoid attribute nonSuspectContribs :: [Pair]; {-- lookup dec site to find places that a shared reference to this tree *might be* decorated. - - This includes e.g. unique reference sites that appear in an if/else branch. -} + - This includes e.g. sharing sites that appear in an if/else branch. -} monoid attribute refPossibleDecSiteContribs :: [(String, VertexType)]; {-- lookup dec site to find places that a shared reference to this tree are *unconditionally* decorated. -} @@ -449,7 +449,7 @@ top::FlowDef ::= prod::String parent::VertexType termProd::String nt::String - @param nt the full name of the nonterminal - @param ref the vertex type of the shared tree - @param decSite the vertex type that is supplying the attributes - - @param alwaysDec is this decoration uncondtional (as opposed to e.g. a unique reference appearing in an if/else branch) + - @param alwaysDec is this decoration unconditional (as opposed to e.g. sharing in an if/else branch) -} abstract production refDecSiteEq top::FlowDef ::= prod::String nt::String ref::VertexType decSite::VertexType alwaysDec::Boolean diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index 2dca5bd43..21b89011d 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -1230,7 +1230,7 @@ top::Expr ::= '@' e::Expr errCheck1 = check(e.typerep, decoratedType(freshType(), inhSetType([]))); top.merrors <- if errCheck1.typeerror - then [errFromOrigin(top, "Operand to @ must be a unique reference with no inherited attributes. Instead it is of type " ++ errCheck1.leftpp)] + then [errFromOrigin(top, "Operand to @ must be a reference with no inherited attributes. Instead it is of type " ++ errCheck1.leftpp)] else []; } diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index 69585e7c5..456a9aff4 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -551,7 +551,7 @@ aspect production fullList top::Expr ::= '[' es::Exprs ']' { -- TODO: Consider refactoring listtrans on Exprs to decorate the expressions here - -- before forwarding via unique references. + -- before forwarding via translation attributes. local decEs::Exprs = es; decEs.downSubst = top.downSubst; decEs.finalSubst = top.finalSubst; From ae0aa2cb36c4842d5d5cfa7e53d4ef7cf0ae8391 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 29 Apr 2024 18:48:40 -0500 Subject: [PATCH 257/283] Support direct application of curried dispatch application, as expected --- .../silver/compiler/definition/core/Expr.sv | 30 +++++++++++++++++-- .../compiler/definition/flow/env/Expr.sv | 13 ++++++++ test/flow/Dispatch.sv | 15 ++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index d7f088fcc..1262b33c5 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -285,7 +285,7 @@ top::Expr ::= e::Expr '(' es::AppExprs ',' anns::AnnoAppExprs ')' then [] else if length(t.inputTypes) > es.appExprSize then [errFromOrigin(top, "Too few arguments provided to function '" ++ e.unparse ++ "'")] - else if length(t.inputTypes) < es.appExprSize + else if length(t.inputTypes) < es.appExprSize && case t.outputType of dispatchType(_) -> false | _ -> true end then [errFromOrigin(top, "Too many arguments provided to function '" ++ e.unparse ++ "'")] else []; @@ -335,10 +335,15 @@ top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs top.unparse = e.unparse ++ "(" ++ es.unparse ++ "," ++ anns.unparse ++ ")"; top.freeVars := e.freeVars ++ es.freeVars ++ anns.freeVars; + local t :: Type = performSubstitution(e.typerep, e.upSubst); forwards to (if es.isPartial || anns.isPartial then partialApplication - else functionInvocation)(e, es, anns); + else + case t.outputType of + | dispatchType(_) when es.appExprSize > length(t.inputTypes) -> curriedDispatchApplication + | _ -> functionInvocation + end)(e, es, anns); } abstract production functionInvocation implements Application @@ -364,6 +369,27 @@ top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs es.missingTypereps ++ anns.partialAnnoTypereps ++ map(snd, anns.missingAnnotations) ++ [ety.outputType]); } +abstract production curriedDispatchApplication implements Application +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs +{ + top.unparse = e.unparse ++ "(" ++ es.unparse ++ "," ++ anns.unparse ++ ")"; + + local t :: Type = performSubstitution(e.typerep, e.upSubst); + local extraArgs::[Expr] = drop(es.appExprSize - length(t.inputTypes), es.rawExprs); + local dispatchArgs::[Expr] = take(es.appExprSize - length(t.inputTypes), es.rawExprs); + + forwards to application( + application( + @e, '(', + foldl(snocAppExprs(_, ',', _), emptyAppExprs(), + map(presentAppExpr, extraArgs)), + ',', emptyAnnoAppExprs(), ')'), + '(', + foldl(snocAppExprs(_, ',', _), emptyAppExprs(), + map(presentAppExpr, dispatchArgs)), + ',', @anns, ')'); +} + abstract production dispatchApplication implements Application top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index c7ae10df4..dedb6b7f2 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -203,6 +203,19 @@ top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs es.alwaysDecorated = false; } +aspect production curriedDispatchApplication +top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs +{ + es.appProd = + case e of + | productionReference(q) -> just(q.lookupValue.dcl.namedSignature) + | _ -> nothing() + end; + es.appIndexOffset = 0; + es.decSiteVertexInfo = top.decSiteVertexInfo; + es.alwaysDecorated = top.alwaysDecorated; +} + aspect production dispatchApplication top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { diff --git a/test/flow/Dispatch.sv b/test/flow/Dispatch.sv index 7a2859533..347b4232d 100644 --- a/test/flow/Dispatch.sv +++ b/test/flow/Dispatch.sv @@ -48,6 +48,21 @@ top::UDExpr ::= @e::UDExpr top.errors2 = !null(e.env1); } +production dispatchThing3 implements DispatchOp +top::UDExpr ::= @e::UDExpr i::Integer b::Boolean +{ + top.errors1 = b; + top.errors2 = i > 0; +} + +global dt3::DispatchOp = dispatchThing3(3, false); + +production dispatchThing4 implements DispatchOp +top::UDExpr ::= @e::UDExpr +{ + forwards to dispatchThing3(e, 42, true); +} + wrongFlowCode "Tree e in production flow:overloadThing2 is shared in multiple places" { production overloadThing2 top::UDExpr ::= e::UDExpr From b5fd602b034d135e041ab80c07df76feb747eb5e Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 30 Apr 2024 12:34:13 -0500 Subject: [PATCH 258/283] Add comments, tweak error message --- .../compiler/definition/concrete_syntax/ProductionDcl.sv | 2 +- grammars/silver/compiler/definition/core/Expr.sv | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/grammars/silver/compiler/definition/concrete_syntax/ProductionDcl.sv b/grammars/silver/compiler/definition/concrete_syntax/ProductionDcl.sv index 5cfb17bf2..984045855 100644 --- a/grammars/silver/compiler/definition/concrete_syntax/ProductionDcl.sv +++ b/grammars/silver/compiler/definition/concrete_syntax/ProductionDcl.sv @@ -145,7 +145,7 @@ top::ProductionRHSElem ::= ms::MaybeShared id::Name '::' t::TypeExpr if t.typerep.permittedInConcreteSyntax then [] else [errFromOrigin(t, t.unparse ++ " is not permitted on concrete productions. Only terminals and nonterminals (without type variables) can appear here")]; top.concreteSyntaxTypeErrors <- - if ms.isShared then [errFromOrigin(ms, "Sharing is not permitted in concrete productions.")] + if ms.isShared then [errFromOrigin(ms, "Sharing is not permitted in concrete production signatures.")] else []; } diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index 1262b33c5..6e43df0c4 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -369,6 +369,10 @@ top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs es.missingTypereps ++ anns.partialAnnoTypereps ++ map(snd, anns.missingAnnotations) ++ [ety.outputType]); } +-- Dispatch productions with extra arguments are partially curried, +-- e.g. lexicalLocalReference has type (Reference ::= Maybe [FlowVertex]). +-- This exists to permit all arguments to be supplied directly, +-- e.g. lexicalLocalReference(q, fi, fd) instead of lexicalLocalReference(fi, fd)(q). abstract production curriedDispatchApplication implements Application top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs { From 1f8822b6d5c43b7374902753b9eda1b95ec7595b Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 30 Apr 2024 14:24:25 -0500 Subject: [PATCH 259/283] Fix forward prod attr check when looking up for another prod --- grammars/silver/compiler/definition/env/Defs.sv | 4 +++- grammars/silver/compiler/definition/env/Env.sv | 3 +++ .../compiler/definition/flow/driver/ProductionGraph.sv | 3 ++- grammars/silver/compiler/definition/flow/env/DecSites.sv | 5 ++++- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/grammars/silver/compiler/definition/env/Defs.sv b/grammars/silver/compiler/definition/env/Defs.sv index 0762bfc3f..3084831b6 100644 --- a/grammars/silver/compiler/definition/env/Defs.sv +++ b/grammars/silver/compiler/definition/env/Defs.sv @@ -1,6 +1,8 @@ grammar silver:compiler:definition:env; -nonterminal Defs with defs, typeList, valueList, attrList, instList, prodOccursList, prodDclList, dispatchDclList, filterItems, filterOnly, filterHiding, withRenames, renamed, pfx, prepended; +nonterminal Defs with + defs, typeList, valueList, attrList, instList, prodOccursList, prodDclList, dispatchDclList, + filterItems, filterOnly, filterHiding, withRenames, renamed, pfx, prepended; -- The standard namespaces synthesized attribute typeList :: [EnvItem]; diff --git a/grammars/silver/compiler/definition/env/Env.sv b/grammars/silver/compiler/definition/env/Env.sv index ce3057300..6e178d399 100644 --- a/grammars/silver/compiler/definition/env/Env.sv +++ b/grammars/silver/compiler/definition/env/Env.sv @@ -357,6 +357,9 @@ Maybe<[String]> ::= t::Type e::Env end; } +-- Check if a production attribute is a forward production attribute. +-- Note this expects the local env for the production! +-- If looking up in another prod, need to get the prod attr defs for the prod. fun isForwardProdAttr Boolean ::= a::String e::Env = case getValueDclAll(a, e) of | d :: _ -> d.hasForward diff --git a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv index b1743f730..1e5331f47 100644 --- a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv @@ -444,7 +444,8 @@ fun addDefEqs case d of | refDecSiteEq(prod, nt, ref, decSite, isAlwaysDec) when case ref of - | localVertexType(fName) -> !isForwardProdAttr(fName, realEnv) + | localVertexType(fName) -> !isForwardProdAttr(fName, + newScopeEnv(flatMap((.prodDefs), getProdAttrs(prod, realEnv)), emptyEnv())) | _ -> true end -> filterMap( diff --git a/grammars/silver/compiler/definition/flow/env/DecSites.sv b/grammars/silver/compiler/definition/flow/env/DecSites.sv index 489cb30b3..ca42a829b 100644 --- a/grammars/silver/compiler/definition/flow/env/DecSites.sv +++ b/grammars/silver/compiler/definition/flow/env/DecSites.sv @@ -45,7 +45,10 @@ DecSiteTree ::= prodName::String vt::VertexType seen::[(String, VertexType)] flo -- Via forwarding | forwardVertexType_real() -> forwardDec() | localVertexType("forward") -> forwardDec() -- TODO: Not sure if this is actually possible? - | localVertexType(fName) when isForwardProdAttr(fName, realEnv) -> forwardDec() + | localVertexType(fName) when + isForwardProdAttr(fName, + newScopeEnv(flatMap((.prodDefs), getProdAttrs(prodName, realEnv)), emptyEnv())) -> + forwardDec() -- Via projected remote equation | subtermVertexType(_, prodOrSig, sigName) -> foldAllDecSite( From d6283424d4ef05b45edfd9c62ed79a1081b25203 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 30 Apr 2024 16:45:38 -0500 Subject: [PATCH 260/283] Fix inherited completeness check handling of translation attributes --- .../silver/compiler/definition/flow/env/DecSites.sv | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/grammars/silver/compiler/definition/flow/env/DecSites.sv b/grammars/silver/compiler/definition/flow/env/DecSites.sv index ca42a829b..9d9cacad7 100644 --- a/grammars/silver/compiler/definition/flow/env/DecSites.sv +++ b/grammars/silver/compiler/definition/flow/env/DecSites.sv @@ -42,6 +42,8 @@ DecSiteTree ::= prodName::String vt::VertexType seen::[(String, VertexType)] flo then directDec(prodName, vt) else neverDec()) ++ case vt of + -- Via flow type + | transAttrVertexType(lhsVertexType_real(), attrName) -> alwaysDec() -- Via forwarding | forwardVertexType_real() -> forwardDec() | localVertexType("forward") -> forwardDec() -- TODO: Not sure if this is actually possible? @@ -66,14 +68,15 @@ DecSiteTree ::= prodName::String vt::VertexType seen::[(String, VertexType)] flo end ++ -- Via direct sharing foldAnyDecSite(map(recurse(prodName, _), lookupRefDecSite(prodName, vt, flowEnv))) ++ - -- Via translation attributes + -- Via translation attribute sharing foldAnyDecSite( - filterMap( + flatMap( \ attrName -> case getAttrDcl(attrName, realEnv) of | dcl :: _ when dcl.isTranslation -> - just(transAttrDec(attrName, recurse(prodName, transAttrVertexType(vt, attrName)))) - | _ -> nothing() + map(\ transDecSite -> transAttrDec(attrName, recurse(prodName, transDecSite)), + lookupRefDecSite(prodName, transAttrVertexType(vt, attrName), flowEnv)) + | _ -> [] end, getHostSynsFor(ntName, flowEnv))); } From a49d855ee11085616c7903ba5cd0a5b350166f21 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 1 May 2024 15:51:46 -0500 Subject: [PATCH 261/283] Fix handling of forwarding for translation attributes --- runtime/java/src/common/DecoratedNode.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/runtime/java/src/common/DecoratedNode.java b/runtime/java/src/common/DecoratedNode.java index b03c9d1d4..365beab86 100644 --- a/runtime/java/src/common/DecoratedNode.java +++ b/runtime/java/src/common/DecoratedNode.java @@ -560,10 +560,6 @@ public DecoratedNode translation(final int attribute, final int inhsAttribute, f * @return The decorated value of the translation attribute. */ private final DecoratedNode evalTrans(final int attribute, final int inhsAttribute, final int decSiteAttribute) { - if(forwardParent != null && isProdForward) { - return forwardParent.translation(attribute, inhsAttribute, decSiteAttribute); - } - Lazy l = self.getSynthesized(attribute); Decorable d; if(l != null) { @@ -574,7 +570,7 @@ private final DecoratedNode evalTrans(final int attribute, final int inhsAttribu } } else if(self.hasForward()) { try { - d = forward().evalTrans(attribute, inhsAttribute, decSiteAttribute); + d = forward().translation(attribute, inhsAttribute, decSiteAttribute); } catch(Throwable t) { throw new TraceException("While evaling trans '" + self.getNameOfSynAttr(attribute) + "' via forward in " + getDebugID(), t); } @@ -599,6 +595,9 @@ private final DecoratedNode evalTrans(final int attribute, final int inhsAttribu } } Lazy decSite = inheritedAttributes == null? null : inheritedAttributes[decSiteAttribute]; + if(decSite == null && forwardParent != null && isProdForward) { + decSite = (context) -> forwardParent.translation(attribute, inhsAttribute, decSiteAttribute); + } return d.decorate(parent, inhs, decSite); } From 4034d8090054d75270c77c1ec6fe269ff334e921 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 1 May 2024 17:16:29 -0500 Subject: [PATCH 262/283] Fix handling of translation attribute override equations and forwarding --- .../definition/flow/ast/DecSiteTree.sv | 12 ++++++-- .../definition/flow/ast/VertexType.sv | 2 +- .../compiler/definition/flow/env/DecSites.sv | 28 +++++++++++++------ runtime/java/src/common/DecoratedNode.java | 2 +- 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/grammars/silver/compiler/definition/flow/ast/DecSiteTree.sv b/grammars/silver/compiler/definition/flow/ast/DecSiteTree.sv index 9806a2b80..12663a0c8 100644 --- a/grammars/silver/compiler/definition/flow/ast/DecSiteTree.sv +++ b/grammars/silver/compiler/definition/flow/ast/DecSiteTree.sv @@ -72,12 +72,18 @@ top::DecSiteTree ::= prodName::String vt::VertexType {-- - An attribute can be supplied via forwarding. - - This does *not* include inherited attributes of translation attributes. + - Inherited attributes on a translation attribute are only supplied if this is + - the forward of the production (not a forward prod attr), and there is no + - override equation for the translation attribute. -} production forwardDec -top::DecSiteTree ::= +top::DecSiteTree ::= prodName::String prodAttrName::Maybe { - top.decSitePP = "via forwarding"; + top.decSitePP = + case prodAttrName of + | just(attrName) -> s"via forward production attribute ${attrName} of production ${prodName}" + | _ -> s"via forward of production ${prodName}" + end; } {-- diff --git a/grammars/silver/compiler/definition/flow/ast/VertexType.sv b/grammars/silver/compiler/definition/flow/ast/VertexType.sv index 1c80e2821..e9814f015 100644 --- a/grammars/silver/compiler/definition/flow/ast/VertexType.sv +++ b/grammars/silver/compiler/definition/flow/ast/VertexType.sv @@ -102,7 +102,7 @@ top::VertexType ::= { top.vertexName = "forward"; top.vertexPP = "forward"; - top.isInhDefVertex = false; + top.isInhDefVertex = true; top.synVertex = forwardSynVertex; top.inhVertex = forwardInhVertex; top.fwdVertex = forwardSynVertex("forward"); diff --git a/grammars/silver/compiler/definition/flow/env/DecSites.sv b/grammars/silver/compiler/definition/flow/env/DecSites.sv index 9d9cacad7..d2069d9d7 100644 --- a/grammars/silver/compiler/definition/flow/env/DecSites.sv +++ b/grammars/silver/compiler/definition/flow/env/DecSites.sv @@ -43,14 +43,15 @@ DecSiteTree ::= prodName::String vt::VertexType seen::[(String, VertexType)] flo else neverDec()) ++ case vt of -- Via flow type + | lhsVertexType_real() -> alwaysDec() -- Shouldn't actually be consulted | transAttrVertexType(lhsVertexType_real(), attrName) -> alwaysDec() -- Via forwarding - | forwardVertexType_real() -> forwardDec() - | localVertexType("forward") -> forwardDec() -- TODO: Not sure if this is actually possible? + | forwardVertexType_real() -> forwardDec(prodName, nothing()) + | localVertexType("forward") -> forwardDec(prodName, nothing()) | localVertexType(fName) when isForwardProdAttr(fName, newScopeEnv(flatMap((.prodDefs), getProdAttrs(prodName, realEnv)), emptyEnv())) -> - forwardDec() + forwardDec(prodName, just(fName)) -- Via projected remote equation | subtermVertexType(_, prodOrSig, sigName) -> foldAllDecSite( @@ -118,12 +119,21 @@ attribute flowEnv occurs on DecSiteTree; strategy attribute resolveDecSite = allTopDown( rule on top::DecSiteTree of | directDec(prodName, vt) - when vertexHasInhEq(prodName, vt, top.attrToResolve, top.flowEnv) -> - alwaysDec() - | forwardDec() -> - if splitTransAttrInh(top.attrToResolve).isJust - then neverDec() - else alwaysDec() + when vertexHasInhEq(prodName, vt, top.attrToResolve, top.flowEnv) -> + alwaysDec() + | forwardDec(_, just(_)) -> + if splitTransAttrInh(top.attrToResolve).isJust + then neverDec() + else alwaysDec() + | forwardDec(prodName, nothing()) -> + case splitTransAttrInh(top.attrToResolve) of + | just((transAttr, inhAttr)) + when !null(lookupSyn(prodName, transAttr, top.flowEnv)) -> + -- transAttr has an override equation, so trans.inh supplied on lhs + -- isn't supplied to trans on forward: + neverDec() + | _ -> alwaysDec() + end | transAttrDec(attrName, d) when case splitTransAttrInh(top.attrToResolve) of | just((transAttr, inhAttr)) -> transAttr != attrName diff --git a/runtime/java/src/common/DecoratedNode.java b/runtime/java/src/common/DecoratedNode.java index 365beab86..bc2dfe721 100644 --- a/runtime/java/src/common/DecoratedNode.java +++ b/runtime/java/src/common/DecoratedNode.java @@ -595,7 +595,7 @@ private final DecoratedNode evalTrans(final int attribute, final int inhsAttribu } } Lazy decSite = inheritedAttributes == null? null : inheritedAttributes[decSiteAttribute]; - if(decSite == null && forwardParent != null && isProdForward) { + if(decSite == null && forwardParent != null && isProdForward && forwardParent.synthesizedValues[attribute] == null) { decSite = (context) -> forwardParent.translation(attribute, inhsAttribute, decSiteAttribute); } return d.decorate(parent, inhs, decSite); From 46c2337fff06a0a3b46f96e3284c45c44b62d92a Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 2 May 2024 13:20:32 -0500 Subject: [PATCH 263/283] Fix indentation when unparsing terminals that span multiple lines --- grammars/silver/langutil/unparse/Unparse.sv | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/grammars/silver/langutil/unparse/Unparse.sv b/grammars/silver/langutil/unparse/Unparse.sv index 3bbaa0692..2bfac7faf 100644 --- a/grammars/silver/langutil/unparse/Unparse.sv +++ b/grammars/silver/langutil/unparse/Unparse.sv @@ -38,10 +38,10 @@ Document ::= origText::String tree::a local postLayout::String = substring(parseTree.originLoc.endIndex, length(origText), origText); return - layoutPP(0, preLayout) ++ + blobPP(0, preLayout) ++ maybeNest(parseTree.indent, ast.unparseWithLayout ++ - layoutPP(parseTree.indent, postLayout)); + blobPP(parseTree.indent, postLayout)); } @{-- @@ -181,7 +181,7 @@ top::AST ::= terminalName::String lexeme::String location::Location { top.originLoc = location; - top.unparseWithLayout = ppImplode(realLine(), map(text, explode("\n", lexeme))); + top.unparseWithLayout = blobPP(top.indent, lexeme); -- Map of terminal names to default layout after the terminal production attribute termPreLayout::[(String, Document)] with ++; @@ -201,7 +201,7 @@ top::ASTs ::= h::AST t::ASTs top.origLayoutPP = case t of | consAST(h2, _) -> - layoutPP(h2.indent, + blobPP(h2.indent, substring(h.originLoc.endIndex, h2.originLoc.index, top.origText)) | nilAST() -> pp"" end; @@ -282,9 +282,9 @@ top::ASTs ::= -- Count the number of spaces at the start of a line fun countIndent Integer ::= s::String = length(takeWhile(eq(" ", _), explode("", s))); -fun layoutPP Document ::= indent::Integer layoutStr::String = +fun blobPP Document ::= indent::Integer str::String = concat( - case explode("\n", layoutStr) of + case explode("\n", str) of | [] -> [] | pre :: lines -> text(pre) :: map(\ l::String -> From 5a1e979445bf05ccf60200426381e92e715cb839 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 2 May 2024 14:22:14 -0500 Subject: [PATCH 264/283] Avoid boxing when code contains syntactic newlines --- grammars/silver/langutil/unparse/Unparse.sv | 3 +++ 1 file changed, 3 insertions(+) diff --git a/grammars/silver/langutil/unparse/Unparse.sv b/grammars/silver/langutil/unparse/Unparse.sv index 2bfac7faf..dca132dcc 100644 --- a/grammars/silver/langutil/unparse/Unparse.sv +++ b/grammars/silver/langutil/unparse/Unparse.sv @@ -181,6 +181,9 @@ top::AST ::= terminalName::String lexeme::String location::Location { top.originLoc = location; + -- If there is a *syntactic* newline, then force anything enclosing this to not be boxed. + top.indents <- if indexOf("\n", lexeme) != -1 then [-1] else []; + top.unparseWithLayout = blobPP(top.indent, lexeme); -- Map of terminal names to default layout after the terminal From 984980ea18e9e856605097072a9a9deb1f5972b5 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 2 May 2024 15:11:30 -0500 Subject: [PATCH 265/283] Refactor to use concise functions in a few more places --- .../silver/compiler/composed/Default/Main.sv | 7 +-- .../modification/concisefunctions/DclInfo.sv | 14 ++--- .../translation/java/core/ProductionDcl.sv | 2 +- grammars/silver/langutil/pp/Document.sv | 55 ++++++++----------- 4 files changed, 30 insertions(+), 48 deletions(-) diff --git a/grammars/silver/compiler/composed/Default/Main.sv b/grammars/silver/compiler/composed/Default/Main.sv index 9aab052ee..6a26764be 100644 --- a/grammars/silver/compiler/composed/Default/Main.sv +++ b/grammars/silver/compiler/composed/Default/Main.sv @@ -6,9 +6,4 @@ parser svParse::Root { silver:compiler:host; } --- TODO: Change to a concise function -function main -IOVal ::= args::[String] ioin::IOToken -{ - return evalIO(cmdLineRun(args, svParse), ioin); -} +fun main IO ::= args::[String] = cmdLineRun(args, svParse); diff --git a/grammars/silver/compiler/modification/concisefunctions/DclInfo.sv b/grammars/silver/compiler/modification/concisefunctions/DclInfo.sv index 340aec11b..b9012cfdd 100644 --- a/grammars/silver/compiler/modification/concisefunctions/DclInfo.sv +++ b/grammars/silver/compiler/modification/concisefunctions/DclInfo.sv @@ -29,14 +29,8 @@ top::ValueDclInfo ::= fn::String ty::Type top.transDefLHSDispatcher = errorTransAttrDefLHS; } -function shortFunDef -Def ::= sg::String sl::Location ns::NamedSignature -{ - return valueDef(defaultEnvItem(shortFunDcl(ns,sourceGrammar=sg,sourceLocation=sl))); -} +fun shortFunDef Def ::= sg::String sl::Location ns::NamedSignature = + valueDef(defaultEnvItem(shortFunDcl(ns,sourceGrammar=sg,sourceLocation=sl))); -function shortFunParamDef -Def ::= sg::String sl::Location fn::String ty::Type -{ - return valueDef(defaultEnvItem(shortFunParamDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); -} +fun shortFunParamDef Def ::= sg::String sl::Location fn::String ty::Type = + valueDef(defaultEnvItem(shortFunParamDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); diff --git a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv index 2888d8488..c8287bfb3 100644 --- a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv +++ b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv @@ -189,7 +189,7 @@ ${flatMap(makeInhOccursContextAccess(namedSig.freeVariables, namedSig.contextInh ${if isData then "" else s""" @Override public common.Node evalUndecorate(final common.DecoratedNode context) { - ${if !null(body.undecorateExpr) + ${if !null(body.undecorateExpr) then s"return (common.Node)${head(body.undecorateExpr).translation};" else if !null(decorableChildren) then s"return new ${className}(${implode(", ", diff --git a/grammars/silver/langutil/pp/Document.sv b/grammars/silver/langutil/pp/Document.sv index d350054f9..4ec7d017a 100644 --- a/grammars/silver/langutil/pp/Document.sv +++ b/grammars/silver/langutil/pp/Document.sv @@ -286,35 +286,28 @@ top::Document ::= -------------------------------------------------------------------------------- -function prune -Pair> [Boolean]> ::= p::Integer q::dq:Deque> -{ - return if dq:isEmpty(q) then (q, []) - else let h::Pair = dq:head(q) - in if p <= h.fst then (q, []) - else let recur::Pair> [Boolean]> = prune(p, dq:tail(q)) - in (recur.fst, false :: (h.snd ++ recur.snd)) - end - end; -} - -function enter -dq:Deque> ::= p::Integer q::dq:Deque> -{ - return dq:snoc(q, (p, [])); -} - -function leave -Pair> [Boolean]> ::= p::Integer q::dq:Deque> -{ - return if dq:isEmpty(q) then (q, []) - else let h1::Pair = dq:last(q), - t1::dq:Deque> = dq:init(q) - in if dq:isEmpty(t1) then (t1, true :: h1.snd) - else let h2::Pair = dq:last(t1), - t2::dq:Deque> = dq:init(t1) - in (dq:snoc(t2, (h2.fst, h2.snd ++ [p <= h1.fst] ++ h1.snd)), []) - end - end; -} +fun prune +Pair> [Boolean]> ::= p::Integer q::dq:Deque> = + if dq:isEmpty(q) then (q, []) + else let h::Pair = dq:head(q) + in if p <= h.fst then (q, []) + else let recur::Pair> [Boolean]> = prune(p, dq:tail(q)) + in (recur.fst, false :: (h.snd ++ recur.snd)) + end + end; + +fun enter dq:Deque> ::= p::Integer q::dq:Deque> = + dq:snoc(q, (p, [])); + +fun leave +Pair> [Boolean]> ::= p::Integer q::dq:Deque> = + if dq:isEmpty(q) then (q, []) + else let h1::Pair = dq:last(q), + t1::dq:Deque> = dq:init(q) + in if dq:isEmpty(t1) then (t1, true :: h1.snd) + else let h2::Pair = dq:last(t1), + t2::dq:Deque> = dq:init(t1) + in (dq:snoc(t2, (h2.fst, h2.snd ++ [p <= h1.fst] ++ h1.snd)), []) + end + end; From db106051708117e7f8105dc3f64a76e427788e20 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 6 May 2024 15:46:17 -0500 Subject: [PATCH 266/283] Add support for non-decorated local/production attributes --- .../typechecking/core/ProductionBody.sv | 12 +++++ .../compiler/definition/core/DclInfo.sv | 18 ++++++- .../silver/compiler/definition/core/Expr.sv | 16 ++++-- .../definition/core/ProductionBody.sv | 46 +++++++++++++++-- .../compiler/definition/core/Terminals.sv | 1 + .../silver/compiler/definition/env/DclInfo.sv | 29 +++++++++-- .../silver/compiler/definition/env/Defs.sv | 8 ++- .../compiler/definition/flow/env/Expr.sv | 18 ++++--- .../convenience/ShortLocalProdAttrDeclDef.sv | 50 +++++++++++++++++++ .../extension/implicit_monads/Expr.sv | 12 +++++ .../compiler/extension/rewriting/Expr.sv | 6 +++ .../compiler/langserver/ReferenceLocations.sv | 2 + .../modification/collection/DclInfo.sv | 2 +- .../modification/copper/ActionCode.sv | 2 +- .../compiler/translation/java/core/DclInfo.sv | 20 +++++++- .../compiler/translation/java/core/Expr.sv | 10 ++++ .../translation/java/core/ProductionBody.sv | 22 ++++++++ 17 files changed, 252 insertions(+), 22 deletions(-) diff --git a/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv b/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv index 097aa80d5..f897687b3 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/ProductionBody.sv @@ -163,6 +163,18 @@ top::ProductionStmt ::= 'production' 'attribute' a::Name '::' te::TypeExpr ';' top.errors <- te.errorsKindStar; } +aspect production nondecLocalAttributeDcl +top::ProductionStmt ::= 'nondecorated' 'local' 'attribute' a::Name '::' te::TypeExpr ';' +{ + top.errors <- te.errorsKindStar; +} + +aspect production nondecProductionAttributeDcl +top::ProductionStmt ::= 'nondecorated' 'production' 'attribute' a::Name '::' te::TypeExpr ';' +{ + top.errors <- te.errorsKindStar; +} + aspect production localValueDef top::ProductionStmt ::= @val::QName e::Expr { diff --git a/grammars/silver/compiler/definition/core/DclInfo.sv b/grammars/silver/compiler/definition/core/DclInfo.sv index 8f30a8bcd..bc52d1b6d 100644 --- a/grammars/silver/compiler/definition/core/DclInfo.sv +++ b/grammars/silver/compiler/definition/core/DclInfo.sv @@ -61,7 +61,23 @@ top::ValueDclInfo ::= fn::String ty::Type top.transDefLHSDispatcher = errorTransAttrDefLHS; } aspect production localDcl -top::ValueDclInfo ::= fn::String ty::Type _ +top::ValueDclInfo ::= fn::String ty::Type +{ + top.refDispatcher = localReference; + top.defDispatcher = localValueDef; + top.defLHSDispatcher = localDefLHS; + top.transDefLHSDispatcher = localTransAttrDefLHS; +} +aspect production nondecLocalDcl +top::ValueDclInfo ::= fn::String ty::Type +{ + top.refDispatcher = nondecLocalReference; + top.defDispatcher = localValueDef; + top.defLHSDispatcher = errorDefLHS; + top.transDefLHSDispatcher = errorTransAttrDefLHS; +} +aspect production forwardLocalDcl +top::ValueDclInfo ::= fn::String ty::Type { top.refDispatcher = localReference; top.defDispatcher = localValueDef; diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index 6e43df0c4..816f4a0bd 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -140,9 +140,19 @@ top::Expr ::= @q::QName top.unparse = q.unparse; top.freeVars <- ts:fromList([q.name]); - top.typerep = if isDecorable(q.lookupValue.typeScheme.monoType, top.env) - then q.lookupValue.typeScheme.asNtOrDecType - else q.lookupValue.typeScheme.monoType; + top.typerep = + if isDecorable(q.lookupValue.typeScheme.monoType, top.env) + then q.lookupValue.typeScheme.asNtOrDecType + else q.lookupValue.typeScheme.monoType; +} + +abstract production nondecLocalReference implements Reference +top::Expr ::= @q::QName +{ + top.unparse = q.unparse; + top.freeVars <- ts:fromList([q.name]); + + top.typerep = q.lookupValue.typeScheme.monoType; } abstract production forwardReference implements Reference diff --git a/grammars/silver/compiler/definition/core/ProductionBody.sv b/grammars/silver/compiler/definition/core/ProductionBody.sv index 9eb2ecb31..ed70a2dd6 100644 --- a/grammars/silver/compiler/definition/core/ProductionBody.sv +++ b/grammars/silver/compiler/definition/core/ProductionBody.sv @@ -160,7 +160,7 @@ top::ProductionStmt ::= 'local' 'attribute' a::Name '::' te::TypeExpr ';' production attribute fName :: String; fName = s"${top.frame.fullName}:local:${top.grammarName}:${implode("_", filter(isAlpha, explode(".", a.nameLoc.filename)))}:${toString(a.nameLoc.line)}:${toString(a.nameLoc.column)}:${a.name}"; - top.defs := [localDef(top.grammarName, a.nameLoc, fName, te.typerep, false)]; + top.defs := [localDef(top.grammarName, a.nameLoc, fName, te.typerep)]; top.errors <- if length(getValueDclInScope(a.name, top.env)) > 1 @@ -180,7 +180,47 @@ top::ProductionStmt ::= 'production' 'attribute' a::Name '::' te::TypeExpr ';' production attribute fName :: String; fName = top.frame.fullName ++ ":local:" ++ top.grammarName ++ ":" ++ a.name; - top.productionAttributes := [localDef(top.grammarName, a.nameLoc, fName, te.typerep, false)]; + top.productionAttributes := [localDef(top.grammarName, a.nameLoc, fName, te.typerep)]; + + top.errors <- + if length(getValueDclAll(fName, top.env)) > 1 + then [errFromOrigin(a, "Value '" ++ fName ++ "' is already bound.")] + else []; + + top.errors <- if !top.frame.permitProductionAttributes + then [errFromOrigin(top, "Production attributes are not valid in this context.")] + else []; +} + +concrete production nondecLocalAttributeDcl +top::ProductionStmt ::= 'nondecorated' 'local' 'attribute' a::Name '::' te::TypeExpr ';' +{ + top.unparse = "\tnondec local attribute " ++ a.unparse ++ "::" ++ te.unparse ++ ";"; + + production attribute fName :: String; + fName = s"${top.frame.fullName}:local:${top.grammarName}:${implode("_", filter(isAlpha, explode(".", a.nameLoc.filename)))}:${toString(a.nameLoc.line)}:${toString(a.nameLoc.column)}:${a.name}"; + + top.defs := [nondecLocalDef(top.grammarName, a.nameLoc, fName, te.typerep)]; + + top.errors <- + if length(getValueDclInScope(a.name, top.env)) > 1 + then [errFromOrigin(a, "Value '" ++ a.name ++ "' is already bound.")] + else []; + + top.errors <- if !top.frame.permitLocalAttributes + then [errFromOrigin(top, "Local attributes are not valid in this context.")] + else []; +} + +concrete production nondecProductionAttributeDcl +top::ProductionStmt ::= 'nondecorated' 'production' 'attribute' a::Name '::' te::TypeExpr ';' +{ + top.unparse = "\tnondec production attribute " ++ a.unparse ++ "::" ++ te.unparse ++ ";"; + + production attribute fName :: String; + fName = top.frame.fullName ++ ":local:" ++ top.grammarName ++ ":" ++ a.name; + + top.productionAttributes := [nondecLocalDef(top.grammarName, a.nameLoc, fName, te.typerep)]; top.errors <- if length(getValueDclAll(fName, top.env)) > 1 @@ -200,7 +240,7 @@ top::ProductionStmt ::= 'forward' 'production' 'attribute' a::Name ';' production attribute fName :: String; fName = top.frame.fullName ++ ":local:" ++ top.grammarName ++ ":" ++ a.name; - top.productionAttributes := [localDef(top.grammarName, a.nameLoc, fName, top.frame.signature.outputElement.typerep, true)]; + top.productionAttributes := [forwardLocalDef(top.grammarName, a.nameLoc, fName, top.frame.signature.outputElement.typerep)]; top.errors <- if length(getValueDclAll(fName, top.env)) > 1 diff --git a/grammars/silver/compiler/definition/core/Terminals.sv b/grammars/silver/compiler/definition/core/Terminals.sv index db42c20cc..5c9d6c830 100644 --- a/grammars/silver/compiler/definition/core/Terminals.sv +++ b/grammars/silver/compiler/definition/core/Terminals.sv @@ -50,6 +50,7 @@ terminal Implements_kwd 'implements' lexer classes {KEYWORD,RESERVED}; terminal Inherited_kwd 'inherited' lexer classes {KEYWORD,RESERVED}; terminal Instance_kwd 'instance' lexer classes {KEYWORD}; terminal Local_kwd 'local' lexer classes {KEYWORD,RESERVED}; +terminal Nondec_kwd 'nondecorated' lexer classes {KEYWORD,RESERVED}; terminal NonTerminal_kwd 'nonterminal' lexer classes {KEYWORD,RESERVED}; terminal Occurs_kwd 'occurs' lexer classes {KEYWORD,RESERVED}; terminal On_kwd 'on' lexer classes {KEYWORD,RESERVED}; diff --git a/grammars/silver/compiler/definition/env/DclInfo.sv b/grammars/silver/compiler/definition/env/DclInfo.sv index d350b8d4b..23431a60e 100644 --- a/grammars/silver/compiler/definition/env/DclInfo.sv +++ b/grammars/silver/compiler/definition/env/DclInfo.sv @@ -32,6 +32,7 @@ synthesized attribute definedMembers :: [String]; synthesized attribute namedSignature :: NamedSignature; synthesized attribute implementedSignature :: Maybe; synthesized attribute isShared :: Boolean; +synthesized attribute isNondec :: Boolean; synthesized attribute hasForward :: Boolean; -- occurs @@ -53,7 +54,7 @@ inherited attribute givenSubstitution :: Substitution; closed nonterminal ValueDclInfo with sourceGrammar, sourceLocation, fullName, compareTo, isEqual, - typeScheme, namedSignature, implementedSignature, isShared, hasForward, substitutedDclInfo, givenSubstitution; + typeScheme, namedSignature, implementedSignature, isShared, isNondec, hasForward, substitutedDclInfo, givenSubstitution; propagate isEqual on ValueDclInfo excluding globalValueDcl, classMemberDcl; aspect default production @@ -63,6 +64,7 @@ top::ValueDclInfo ::= top.namedSignature = bogusNamedSignature(); top.implementedSignature = nothing(); top.isShared = false; + top.isNondec = false; top.hasForward = false; top.substitutedDclInfo = error("Internal compiler error: must be defined for all value declarations that are production attributes"); @@ -87,14 +89,33 @@ top::ValueDclInfo ::= fn::String ty::Type -- ValueDclInfos that CAN appear in interface files, but only via "production attributes:" abstract production localDcl -top::ValueDclInfo ::= fn::String ty::Type isForward::Boolean +top::ValueDclInfo ::= fn::String ty::Type +{ + top.fullName = fn; + + top.typeScheme = monoType(ty); + + top.substitutedDclInfo = localDcl( fn, performRenaming(ty, top.givenSubstitution), sourceGrammar=top.sourceGrammar, sourceLocation=top.sourceLocation); +} +abstract production nondecLocalDcl +top::ValueDclInfo ::= fn::String ty::Type +{ + top.fullName = fn; + + top.typeScheme = monoType(ty); + + top.isNondec = true; + top.substitutedDclInfo = nondecLocalDcl( fn, performRenaming(ty, top.givenSubstitution), sourceGrammar=top.sourceGrammar, sourceLocation=top.sourceLocation); +} +abstract production forwardLocalDcl +top::ValueDclInfo ::= fn::String ty::Type { top.fullName = fn; top.typeScheme = monoType(ty); - top.hasForward = isForward; - top.substitutedDclInfo = localDcl( fn, performRenaming(ty, top.givenSubstitution), isForward, sourceGrammar=top.sourceGrammar, sourceLocation=top.sourceLocation); + top.hasForward = true; + top.substitutedDclInfo = forwardLocalDcl( fn, performRenaming(ty, top.givenSubstitution), sourceGrammar=top.sourceGrammar, sourceLocation=top.sourceLocation); } abstract production forwardDcl top::ValueDclInfo ::= ty::Type diff --git a/grammars/silver/compiler/definition/env/Defs.sv b/grammars/silver/compiler/definition/env/Defs.sv index 3084831b6..e99ee4a47 100644 --- a/grammars/silver/compiler/definition/env/Defs.sv +++ b/grammars/silver/compiler/definition/env/Defs.sv @@ -137,8 +137,12 @@ fun childDef Def ::= sg::String sl::Location fn::String ty::Type s::Boolean valueDef(defaultEnvItem(childDcl(fn,ty,s,sourceGrammar=sg,sourceLocation=sl))); fun lhsDef Def ::= sg::String sl::Location fn::String ty::Type = valueDef(defaultEnvItem(lhsDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); -fun localDef Def ::= sg::String sl::Location fn::String ty::Type isForward::Boolean = - valueDef(defaultEnvItem(localDcl(fn,ty,isForward,sourceGrammar=sg,sourceLocation=sl))); +fun localDef Def ::= sg::String sl::Location fn::String ty::Type = + valueDef(defaultEnvItem(localDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); +fun nondecLocalDef Def ::= sg::String sl::Location fn::String ty::Type = + valueDef(defaultEnvItem(nondecLocalDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); +fun forwardLocalDef Def ::= sg::String sl::Location fn::String ty::Type = + valueDef(defaultEnvItem(forwardLocalDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl))); fun prodDef Def ::= sg::String sl::Location ns::NamedSignature dispatch::Maybe hasForward::Boolean = prodDclDef(defaultEnvItem(prodDcl(ns,dispatch,hasForward,sourceGrammar=sg,sourceLocation=sl))); fun funDef Def ::= sg::String sl::Location ns::NamedSignature = diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index dedb6b7f2..428eca718 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -58,8 +58,7 @@ attribute flowVertexInfo occurs on Expr; propagate flowDeps on Expr, ExprInhs, ExprInh, Exprs, AppExprs, AppExpr, AnnoAppExprs, AnnoExpr excluding - childReference, lhsReference, localReference, forwardReference, forwardAccess, - synDecoratedAccessHandler, inhDecoratedAccessHandler, transDecoratedAccessHandler, + forwardAccess, synDecoratedAccessHandler, inhDecoratedAccessHandler, transDecoratedAccessHandler, decorateExprWith, letp, lexicalLocalReference, matchPrimitiveReal; propagate flowDefs, flowEnv on Expr, ExprInhs, ExprInh, Exprs, AppExprs, AppExpr, AnnoAppExprs, AnnoExpr; @@ -82,7 +81,7 @@ top::Expr ::= @q::QName -- isDecorable on that indeed tells us whether it's something autodecorated. production refSet::Maybe<[String]> = getMaxRefSet(top.finalType, top.env); production origRefSet::[String] = getMinRefSet(q.lookupValue.typeScheme.monoType, top.env); - top.flowDeps := + top.flowDeps <- if isDecorable(q.lookupValue.typeScheme.monoType, top.env) && top.finalType.isDecorated then map(rhsVertexType(q.lookupValue.fullName).inhVertex, removeAll(origRefSet, fromMaybe([], refSet))) else []; @@ -96,7 +95,7 @@ top::Expr ::= @q::QName { -- Always a decorable type, so just check how it's being used: production refSet::Maybe<[String]> = getMaxRefSet(top.finalType, top.env); - top.flowDeps := + top.flowDeps <- if top.finalType.isDecorated then map(lhsVertexType.inhVertex, fromMaybe([], refSet)) else []; @@ -111,7 +110,7 @@ top::Expr ::= @q::QName -- Again, q give the actual type written. production refSet::Maybe<[String]> = getMaxRefSet(top.finalType, top.env); production origRefSet::[String] = getMinRefSet(q.lookupValue.typeScheme.monoType, top.env); - top.flowDeps := [localEqVertex(q.lookupValue.fullName)] ++ + top.flowDeps <- localEqVertex(q.lookupValue.fullName) :: if isDecorable(q.lookupValue.typeScheme.monoType, top.env) && top.finalType.isDecorated then map(localVertexType(q.lookupValue.fullName).inhVertex, removeAll(origRefSet, fromMaybe([], refSet))) else []; @@ -120,12 +119,19 @@ top::Expr ::= @q::QName then just(localVertexType(q.lookupValue.fullName)) else nothing(); } +aspect production nondecLocalReference +top::Expr ::= @q::QName +{ + -- Never decorated - just the equation vertex. + top.flowDeps <- [localEqVertex(q.lookupValue.fullName)]; + top.flowVertexInfo = nothing(); +} aspect production forwardReference top::Expr ::= @q::QName { -- Again, always a decorable type. production refSet::Maybe<[String]> = getMaxRefSet(top.finalType, top.env); - top.flowDeps := [forwardEqVertex()]++ + top.flowDeps <- forwardEqVertex() :: if top.finalType.isDecorated then map(forwardVertexType.inhVertex, fromMaybe([], refSet)) else []; diff --git a/grammars/silver/compiler/extension/convenience/ShortLocalProdAttrDeclDef.sv b/grammars/silver/compiler/extension/convenience/ShortLocalProdAttrDeclDef.sv index 06d151423..66008ca72 100644 --- a/grammars/silver/compiler/extension/convenience/ShortLocalProdAttrDeclDef.sv +++ b/grammars/silver/compiler/extension/convenience/ShortLocalProdAttrDeclDef.sv @@ -40,6 +40,56 @@ top::ProductionStmt ::= pk::'production' ak::'attribute' valueEq(qNameId(a), eq, v, sm)); } +concrete production shortNondecDecl +top::ProductionStmt ::= nk::'nondecorated' a::Name ht::'::' te::TypeExpr + eq::'=' v::Expr sm::';' +{ + forwards to + productionStmtAppend( + nondecLocalAttributeDcl(nk, 'local', 'attribute', a, ht, te, sm), + valueEq(qNameId(a), eq, v, sm)); +} + +concrete production shortNondecLocalDecl +top::ProductionStmt ::= nk::'nondecorated' lk::'local' a::Name ht::'::' te::TypeExpr + eq::'=' v::Expr sm::';' +{ + forwards to + productionStmtAppend( + nondecLocalAttributeDcl(nk, lk, 'attribute', a, ht, te, sm), + valueEq(qNameId(a), eq, v, sm)); +} + +concrete production shortNondecLocalDeclwKwds +top::ProductionStmt ::= nk::'nondecorated' lk::'local' ak::'attribute' a::Name ht::'::' te::TypeExpr + eq::'=' v::Expr sm::';' +{ + forwards to + productionStmtAppend( + nondecLocalAttributeDcl(nk, lk, ak, a, ht, te, sm), + valueEq(qNameId(a), eq, v, sm)); +} + +concrete production shortNondecProductionDecl +top::ProductionStmt ::= nd::'nondecorated' pk::'production' a::Name ht::'::' te::TypeExpr + eq::'=' v::Expr sm::';' +{ + forwards to + productionStmtAppend( + nondecProductionAttributeDcl(nd, pk, 'attribute', a, ht, te, sm), + valueEq(qNameId(a), eq, v, sm)); +} + +concrete production shortNondecProductionDeclwKwds +top::ProductionStmt ::= nd::'nondecorated' pk::'production' ak::'attribute' a::Name ht::'::' te::TypeExpr + eq::'=' v::Expr sm::';' +{ + forwards to + productionStmtAppend( + nondecProductionAttributeDcl(nd, pk, ak, a, ht, te, sm), + valueEq(qNameId(a), eq, v, sm)); +} + concrete production shortForwardProductionDecl top::ProductionStmt ::= fk::'forward' a::Name eq::'=' v::Expr sm::';' diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index 21b89011d..b6b72f256 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -97,6 +97,18 @@ top::Expr ::= @q::QName top.monadRewritten = baseExpr(new(q)); } +aspect production nondecLocalReference +top::Expr ::= @q::QName +{ + top.merrors := []; + propagate mDownSubst, mUpSubst; + top.mtyperep = q.lookupValue.typeScheme.monoType; + top.monadicNames = if top.monadicallyUsed + then [baseExpr(new(q))] + else []; + top.monadRewritten = baseExpr(new(q)); +} + aspect production forwardReference top::Expr ::= @q::QName { diff --git a/grammars/silver/compiler/extension/rewriting/Expr.sv b/grammars/silver/compiler/extension/rewriting/Expr.sv index 456a9aff4..34a6760c0 100644 --- a/grammars/silver/compiler/extension/rewriting/Expr.sv +++ b/grammars/silver/compiler/extension/rewriting/Expr.sv @@ -102,6 +102,12 @@ top::Expr ::= @q::QName else antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr($QName{q}) }); } +aspect production nondecLocalReference +top::Expr ::= @q::QName +{ + top.transform = antiquoteASTExpr(Silver_Expr { silver:rewrite:anyASTExpr($QName{q}) }); +} + aspect production forwardReference top::Expr ::= @q::QName { diff --git a/grammars/silver/compiler/langserver/ReferenceLocations.sv b/grammars/silver/compiler/langserver/ReferenceLocations.sv index 637f852e4..4698e466b 100644 --- a/grammars/silver/compiler/langserver/ReferenceLocations.sv +++ b/grammars/silver/compiler/langserver/ReferenceLocations.sv @@ -103,6 +103,8 @@ end; aspect valueRefLocs on top::ProductionStmt using <- of | localAttributeDcl(_, _, n, _, _, _) -> map(\dcl :: ValueDclInfo -> (n.nameLoc, dcl), getValueDcl(n.name, top.env)) | productionAttributeDcl(_, _, n, _, _, _) -> map(\dcl :: ValueDclInfo -> (n.nameLoc, dcl), getValueDcl(n.name, top.env)) +| nondecLocalAttributeDcl(_, _, _, n, _, _, _) -> map(\dcl :: ValueDclInfo -> (n.nameLoc, dcl), getValueDcl(n.name, top.env)) +| nondecProductionAttributeDcl(_, _, _, n, _, _, _) -> map(\dcl :: ValueDclInfo -> (n.nameLoc, dcl), getValueDcl(n.name, top.env)) | forwardProductionAttributeDcl(_, _, _, n, _) -> map(\dcl :: ValueDclInfo -> (n.nameLoc, dcl), getValueDcl(n.name, top.env)) end; diff --git a/grammars/silver/compiler/modification/collection/DclInfo.sv b/grammars/silver/compiler/modification/collection/DclInfo.sv index 0b69c1333..1416aedac 100644 --- a/grammars/silver/compiler/modification/collection/DclInfo.sv +++ b/grammars/silver/compiler/modification/collection/DclInfo.sv @@ -101,7 +101,7 @@ top::ValueDclInfo ::= fn::String ty::Type o::Operation -- TODO: attrOccursIndex -- We shouldn't be forwarding here - forwards to localDcl(fn,ty,false,sourceGrammar=top.sourceGrammar,sourceLocation=top.sourceLocation); + forwards to localDcl(fn,ty,sourceGrammar=top.sourceGrammar,sourceLocation=top.sourceLocation); } -- Defs diff --git a/grammars/silver/compiler/modification/copper/ActionCode.sv b/grammars/silver/compiler/modification/copper/ActionCode.sv index e47a86d6a..07f23ea10 100644 --- a/grammars/silver/compiler/modification/copper/ActionCode.sv +++ b/grammars/silver/compiler/modification/copper/ActionCode.sv @@ -116,7 +116,7 @@ function hackTransformLocals { return case d of - | valueDef(item) when item.dcl matches localDcl(fn,ty,false,sourceGrammar=sg,sourceLocation=sl) -> [parserLocalDef(sg,sl,fn,ty)] + | valueDef(item) when item.dcl matches localDcl(fn,ty,sourceGrammar=sg,sourceLocation=sl) -> [parserLocalDef(sg,sl,fn,ty)] | _ -> [] -- TODO: possibly error?? end; } diff --git a/grammars/silver/compiler/translation/java/core/DclInfo.sv b/grammars/silver/compiler/translation/java/core/DclInfo.sv index 3c90edeef..3d21f400d 100644 --- a/grammars/silver/compiler/translation/java/core/DclInfo.sv +++ b/grammars/silver/compiler/translation/java/core/DclInfo.sv @@ -102,7 +102,25 @@ top::ValueDclInfo ::= } aspect production localDcl -top::ValueDclInfo ::= fn::String ty::Type _ +top::ValueDclInfo ::= fn::String ty::Type +{ + local attribute li :: Integer; + li = lastIndexOf(":local:", fn); + top.attrOccursIndexName = makeIdName(substring(li+7, length(fn), fn) ++ "__ON__" ++ substring(0,li,fn)); + top.attrOccursInitIndex = top.attrOccursIndex; + top.attrOccursIndex = makeName(top.sourceGrammar) ++ ".Init." ++ top.attrOccursIndexName; +} +aspect production nondecLocalDcl +top::ValueDclInfo ::= fn::String ty::Type +{ + local attribute li :: Integer; + li = lastIndexOf(":local:", fn); + top.attrOccursIndexName = makeIdName(substring(li+7, length(fn), fn) ++ "__ON__" ++ substring(0,li,fn)); + top.attrOccursInitIndex = top.attrOccursIndex; + top.attrOccursIndex = makeName(top.sourceGrammar) ++ ".Init." ++ top.attrOccursIndexName; +} +aspect production forwardLocalDcl +top::ValueDclInfo ::= fn::String ty::Type { local attribute li :: Integer; li = lastIndexOf(":local:", fn); diff --git a/grammars/silver/compiler/translation/java/core/Expr.sv b/grammars/silver/compiler/translation/java/core/Expr.sv index 33c9b738a..c62a713bc 100644 --- a/grammars/silver/compiler/translation/java/core/Expr.sv +++ b/grammars/silver/compiler/translation/java/core/Expr.sv @@ -114,6 +114,16 @@ top::Expr ::= @q::QName else s"context.localDecoratedLazy(${q.lookupValue.dcl.attrOccursIndex})"; } +aspect production nondecLocalReference +top::Expr ::= @q::QName +{ + top.translation = s"context.<${top.finalType.transType}>localAsIs(${q.lookupValue.dcl.attrOccursIndex})"; + + top.lazyTranslation = + if !top.frame.lazyApplication then top.translation + else s"context.localAsIsLazy(${q.lookupValue.dcl.attrOccursIndex})"; +} + aspect production lhsReference top::Expr ::= @q::QName { diff --git a/grammars/silver/compiler/translation/java/core/ProductionBody.sv b/grammars/silver/compiler/translation/java/core/ProductionBody.sv index b43fd6de0..6fdeb7de0 100644 --- a/grammars/silver/compiler/translation/java/core/ProductionBody.sv +++ b/grammars/silver/compiler/translation/java/core/ProductionBody.sv @@ -164,6 +164,28 @@ top::ProductionStmt ::= 'production' 'attribute' a::Name '::' te::TypeExpr ';' end; } +aspect production nondecLocalAttributeDcl +top::ProductionStmt ::= 'nondecorated' 'local' 'attribute' a::Name '::' te::TypeExpr ';' +{ + local attribute ugh_dcl_hack :: ValueDclInfo; + ugh_dcl_hack = head(getValueDclAll(fName, top.env)); -- TODO really, we should have a DclInfo for ourselves no problem. but out current approach of constructing it via localDef makes this annoyingly difficult. this suggests a probably environment refactoring... + + top.valueWeaving := s"public static final int ${ugh_dcl_hack.attrOccursIndexName} = ${top.frame.prodLocalCountName}++;\n"; + top.setupInh := s"\t\t${top.frame.className}.occurs_local[${ugh_dcl_hack.attrOccursInitIndex}] = \"${fName}\";\n"; + top.translation = ""; +} + +aspect production nondecProductionAttributeDcl +top::ProductionStmt ::= 'nondecorated' 'production' 'attribute' a::Name '::' te::TypeExpr ';' +{ + local attribute ugh_dcl_hack :: ValueDclInfo; + ugh_dcl_hack = head(getValueDclAll(fName, top.env)); -- TODO really, we should have a DclInfo for ourselves no problem. but out current approach of constructing it via localDef makes this annoyingly difficult. this suggests a probably environment refactoring... + + top.valueWeaving := s"public static final int ${ugh_dcl_hack.attrOccursIndexName} = ${top.frame.prodLocalCountName}++;\n"; + top.setupInh := s"\t\t${top.frame.className}.occurs_local[${ugh_dcl_hack.attrOccursInitIndex}] = \"${fName}\";\n"; + top.translation = ""; +} + aspect production forwardProductionAttributeDcl top::ProductionStmt ::= 'forward' 'production' 'attribute' a::Name ';' { From ddccd6c436517a3a4691ffc06b2291e4805cbb97 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 6 May 2024 16:29:39 -0500 Subject: [PATCH 267/283] Add tests --- test/silver_features/Locals.sv | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 test/silver_features/Locals.sv diff --git a/test/silver_features/Locals.sv b/test/silver_features/Locals.sv new file mode 100644 index 000000000..80f9a0ef1 --- /dev/null +++ b/test/silver_features/Locals.sv @@ -0,0 +1,40 @@ +grammar silver_features; + +inherited attribute stuff::[Integer]; + +nonterminal LocalThing with stuff; + +production localThing +top::LocalThing ::= +{ + nondecorated a :: Integer = 5; + nondecorated production b :: LocalThing = localThing(); + + local refA :: Integer = a; + local refB :: LocalThing = b; + refB.stuff = [1, 2, 3]; +} + +wrongCode "Cannot define attributes on b" { +aspect production localThing +top::LocalThing ::= +{ + b.stuff = [1, 2, 3]; +} +} + +wrongCode "Local refBDec has type Decorated silver_features:LocalThing with {silver_features:stuff} but the expression being assigned to it has type silver_features:LocalThing" { +aspect production localThing +top::LocalThing ::= +{ + local refBDec :: Decorated LocalThing = b; +} +} + +wrongCode "This is not something that can be shared" { +aspect production localThing +top::LocalThing ::= +{ + local shareB :: LocalThing = @b; +} +} From 490ac3f8ddf820fe3346b0ec3d52c5c86a7cc2c0 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 6 May 2024 17:07:12 -0500 Subject: [PATCH 268/283] Nondec local eqs are not valid sharing sites --- grammars/silver/compiler/definition/flow/env/ProductionBody.sv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/grammars/silver/compiler/definition/flow/env/ProductionBody.sv b/grammars/silver/compiler/definition/flow/env/ProductionBody.sv index b4066a5c0..4745ff8c6 100644 --- a/grammars/silver/compiler/definition/flow/env/ProductionBody.sv +++ b/grammars/silver/compiler/definition/flow/env/ProductionBody.sv @@ -204,7 +204,8 @@ top::ProductionStmt ::= @val::QName e::Expr if e.alwaysDecorated then just(localVertexType(val.lookupValue.fullName)) else nothing(); - e.alwaysDecorated = isDecorable(e.finalType, top.env); + e.alwaysDecorated = + isDecorable(e.finalType, top.env) && val.lookupValue.found && !val.lookupValue.dcl.isNondec; } -- FROM COLLECTIONS TODO From 291f7e8a9191a5bf4eec6531afc5abccce6cd846 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 7 May 2024 14:04:57 -0500 Subject: [PATCH 269/283] Check that sharing site has a known dec site, handle dec site for lexical local bindings, refactor flow types --- .../analysis/typechecking/core/Expr.sv | 2 + .../compiler/analysis/uniqueness/Expr.sv | 6 ++ .../silver/compiler/definition/core/Expr.sv | 15 +++- .../compiler/definition/flow/env/Expr.sv | 75 +++++++--------- .../extension/implicit_monads/Case.sv | 18 +++- .../extension/implicit_monads/Expr.sv | 7 +- .../compiler/extension/implicit_monads/Let.sv | 1 + .../implicit_monads/PrimitiveMatch.sv | 1 + .../implicit_monads/ProductionBody.sv | 4 + .../silver/compiler/extension/tuple/Tuple.sv | 1 + .../compiler/modification/let_fix/Let.sv | 4 + .../primitivepattern/PrimitiveMatch.sv | 1 + test/flow/RefSiteProj.sv | 85 +++++++++++++++++++ 13 files changed, 167 insertions(+), 53 deletions(-) diff --git a/grammars/silver/compiler/analysis/typechecking/core/Expr.sv b/grammars/silver/compiler/analysis/typechecking/core/Expr.sv index 31e3f5dc1..2929cf8da 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/Expr.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/Expr.sv @@ -4,6 +4,8 @@ import silver:compiler:definition:flow:env; attribute upSubst, downSubst, finalSubst occurs on Expr, ExprInhs, ExprInh, Exprs, AppExprs, AppExpr, AnnoExpr, AnnoAppExprs; +flowtype Expr = upSubst {forward}, finalType {forward}; + propagate upSubst, downSubst on Expr, ExprInhs, ExprInh, Exprs, AppExprs, AppExpr, AnnoExpr, AnnoAppExprs excluding diff --git a/grammars/silver/compiler/analysis/uniqueness/Expr.sv b/grammars/silver/compiler/analysis/uniqueness/Expr.sv index 35e3a8cc8..1f5f092f3 100644 --- a/grammars/silver/compiler/analysis/uniqueness/Expr.sv +++ b/grammars/silver/compiler/analysis/uniqueness/Expr.sv @@ -15,6 +15,12 @@ top::Expr ::= '@' e::Expr ))] | nothing() -> [] end; + + top.errors <- + case top.decSiteVertexInfo of + | just(_) -> [] + | nothing() -> [errFromOrigin(top, s"Cannot share a tree here; can only share in known positions of local, forward, and translation attribute equations.")] + end; top.errors <- case e.flowVertexInfo of diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index 6e43df0c4..9eecdfc8f 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -18,9 +18,9 @@ tracked nonterminal ExprLHSExpr with flowtype unparse {} on Expr, Exprs, ExprInhs, ExprInh, ExprLHSExpr; flowtype freeVars {frame} on Expr, Exprs, ExprInhs, ExprInh, ExprLHSExpr; flowtype Expr = - forward {grammarName, env, flowEnv, downSubst, finalSubst, frame, isRoot, compiledGrammars, config}, - decorate {forward, decSiteVertexInfo, alwaysDecorated, originRules}, - errors {forward, decSiteVertexInfo}; + forward {grammarName, env, flowEnv, downSubst, finalSubst, frame, isRoot, compiledGrammars, config, decSiteVertexInfo}, + decorate {forward, alwaysDecorated, originRules}, + errors {forward}, typerep {forward}; flowtype decorate {grammarName, env, flowEnv, downSubst, finalSubst, frame, originRules, compiledGrammars, config} on Exprs; flowtype decorate {grammarName, env, flowEnv, downSubst, finalSubst, frame, originRules, compiledGrammars, config, decoratingnt, allSuppliedInhs} on ExprInhs, ExprInh; @@ -977,6 +977,15 @@ flowtype AppExprs = tracked nonterminal AppExpr with config, grammarName, env, unparse, errors, freeVars, frame, compiledGrammars, exprs, rawExprs, isPartial, missingTypereps, appExprIndicies, appExprIndex, appExprTyperep, appExprApplied, originRules; +flowtype AppExpr = + decorate { + config, grammarName, env, frame, compiledGrammars, appExprIndex, appExprTyperep, appExprApplied, originRules, + downSubst, finalSubst, flowEnv, appIndexOffset + }, + errors { + config, grammarName, env, frame, compiledGrammars, appExprIndex, appExprTyperep, appExprApplied, + downSubst, finalSubst, flowEnv, decSiteVertexInfo, appProd, appIndexOffset + }; propagate config, grammarName, env, freeVars, frame, compiledGrammars, errors, originRules on AppExprs, AppExpr; propagate appExprApplied, exprs, rawExprs on AppExprs; diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index dedb6b7f2..a586d487b 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -52,16 +52,27 @@ inherited attribute decSiteVertexInfo :: Maybe; -} inherited attribute alwaysDecorated :: Boolean; +{-- + - Mappings of lexical local (let/pattern var) bindings referenced in this expression, + - to their decoration site vertices and whether they are always decorated. + -} +monoid attribute lexicalLocalDecSites :: [(String, Maybe)]; +monoid attribute lexicalLocalAlwaysDecorated :: [(String, Boolean)]; + -- flowDefs because expressions (decorate, patterns) can now generate stitchpoints -attribute flowDeps, flowDefs, flowEnv occurs on Expr, ExprInhs, ExprInh, Exprs, AppExprs, AppExpr, AnnoAppExprs, AnnoExpr; +attribute flowDeps, flowDefs, flowEnv, lexicalLocalDecSites, lexicalLocalAlwaysDecorated + occurs on Expr, ExprInhs, ExprInh, Exprs, AppExprs, AppExpr, AnnoAppExprs, AnnoExpr; attribute flowVertexInfo occurs on Expr; +flowtype flowVertexInfo {forward} on Expr; + propagate flowDeps on Expr, ExprInhs, ExprInh, Exprs, AppExprs, AppExpr, AnnoAppExprs, AnnoExpr excluding childReference, lhsReference, localReference, forwardReference, forwardAccess, synDecoratedAccessHandler, inhDecoratedAccessHandler, transDecoratedAccessHandler, decorateExprWith, letp, lexicalLocalReference, matchPrimitiveReal; -propagate flowDefs, flowEnv on Expr, ExprInhs, ExprInh, Exprs, AppExprs, AppExpr, AnnoAppExprs, AnnoExpr; +propagate flowDefs, flowEnv, lexicalLocalDecSites, lexicalLocalAlwaysDecorated + on Expr, ExprInhs, ExprInh, Exprs, AppExprs, AppExpr, AnnoAppExprs, AnnoExpr; attribute decSiteVertexInfo, alwaysDecorated occurs on Expr, AppExprs, AppExpr; propagate decSiteVertexInfo, alwaysDecorated on AppExprs; @@ -212,6 +223,7 @@ top::Expr ::= @e::Expr @es::AppExprs @anns::AnnoAppExprs | _ -> nothing() end; es.appIndexOffset = 0; + e.decSiteVertexInfo = nothing(); es.decSiteVertexInfo = top.decSiteVertexInfo; es.alwaysDecorated = top.alwaysDecorated; } @@ -312,6 +324,7 @@ top::Expr ::= e::Expr '.' q::QNameAttrOccur { propagate flowEnv; e.alwaysDecorated = false; + e.decSiteVertexInfo = nothing(); } aspect production accessBouncer @@ -319,6 +332,7 @@ top::Expr ::= e::Expr @q::QNameAttrOccur target::Access { propagate flowEnv; e.alwaysDecorated = false; + e.decSiteVertexInfo = nothing(); } aspect production forwardAccess @@ -334,16 +348,6 @@ top::Expr ::= e::Expr '.' 'forward' } -aspect production errorAccessHandler -top::Expr ::= @e::Expr @q::QNameAttrOccur -{ - e.decSiteVertexInfo = nothing(); -} -aspect production terminalAccessHandler -top::Expr ::= @e::Expr @q::QNameAttrOccur -{ - e.decSiteVertexInfo = nothing(); -} -- Note that below we IGNORE the flow deps of the lhs if we know what it is -- this is because by default the lhs will have 'taking ref' flow deps (see above) aspect production synDecoratedAccessHandler @@ -354,7 +358,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur | just(vertex) -> vertex.synVertex(q.attrDcl.fullName) :: vertex.eqVertex | nothing() -> e.flowDeps end; - e.decSiteVertexInfo = nothing(); } aspect production inhDecoratedAccessHandler top::Expr ::= @e::Expr @q::QNameAttrOccur @@ -364,7 +367,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur | just(vertex) -> vertex.inhVertex(q.attrDcl.fullName) :: vertex.eqVertex | nothing() -> e.flowDeps end; - e.decSiteVertexInfo = nothing(); } aspect production transDecoratedAccessHandler top::Expr ::= @e::Expr @q::QNameAttrOccur @@ -377,34 +379,6 @@ top::Expr ::= @e::Expr @q::QNameAttrOccur if top.finalType.isDecorated then map(vertex.inhVertex, fromMaybe([], refSet)) else [] | nothing() -> e.flowDeps end; - e.decSiteVertexInfo = nothing(); -} -aspect production annoAccessHandler -top::Expr ::= @e::Expr @q::QNameAttrOccur -{ - e.decSiteVertexInfo = nothing(); -} -aspect production synDataAccessHandler -top::Expr ::= @e::Expr @q::QNameAttrOccur -{ - -- No flow vertex, since there are never any inh deps - - e.decSiteVertexInfo = nothing(); -} -aspect production inhUndecoratedAccessErrorHandler -top::Expr ::= @e::Expr @q::QNameAttrOccur -{ - e.decSiteVertexInfo = nothing(); -} -aspect production transUndecoratedAccessErrorHandler -top::Expr ::= @e::Expr @q::QNameAttrOccur -{ - e.decSiteVertexInfo = nothing(); -} -aspect production unknownDclAccessHandler -top::Expr ::= @e::Expr @q::QNameAttrOccur -{ - e.decSiteVertexInfo = nothing(); } aspect production decorateExprWith @@ -521,11 +495,17 @@ top::Expr ::= params::LambdaRHS e::Expr attribute flowDefs, flowEnv occurs on AssignExpr; propagate flowDefs, flowEnv on AssignExpr; +inherited attribute bodyDecSites :: [(String, Maybe)] occurs on AssignExpr; +inherited attribute bodyAlwaysDecorated :: [(String, Boolean)] occurs on AssignExpr; +propagate bodyDecSites, bodyAlwaysDecorated on AssignExpr; + aspect production letp top::Expr ::= la::AssignExpr e::Expr { top.flowDeps := e.flowDeps; top.flowVertexInfo = e.flowVertexInfo; + la.bodyDecSites = e.lexicalLocalDecSites; + la.bodyAlwaysDecorated = e.lexicalLocalAlwaysDecorated; e.decSiteVertexInfo = top.decSiteVertexInfo; e.alwaysDecorated = top.alwaysDecorated; } @@ -533,8 +513,12 @@ top::Expr ::= la::AssignExpr e::Expr aspect production assignExpr top::AssignExpr ::= id::Name '::' t::TypeExpr '=' e::Expr { - e.decSiteVertexInfo = nothing(); - e.alwaysDecorated = false; + e.decSiteVertexInfo = + case nub(lookupAll(fName, top.bodyDecSites)) of + | [v] -> v + | _ -> nothing() + end; + e.alwaysDecorated = lookupAll(fName, top.bodyAlwaysDecorated) == [true]; } aspect production lexicalLocalReference @@ -559,6 +543,9 @@ top::Expr ::= @q::QName fi::Maybe fd::[FlowVertex] | nothing() -> fd -- we're actually being used as a ref-set-taking decorated var end; top.flowVertexInfo = fi; + + top.lexicalLocalDecSites <- [(q.lookupValue.fullName, top.decSiteVertexInfo)]; + top.lexicalLocalAlwaysDecorated <- [(q.lookupValue.fullName, top.alwaysDecorated)]; } diff --git a/grammars/silver/compiler/extension/implicit_monads/Case.sv b/grammars/silver/compiler/extension/implicit_monads/Case.sv index e87e38cd6..a21d1e2f1 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Case.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Case.sv @@ -103,6 +103,7 @@ top::Expr ::= 'case' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' monadLocal.downSubst = ml.mUpSubst; monadLocal.finalSubst = top.finalSubst; monadLocal.expectedMonad = top.expectedMonad; + monadLocal.decSiteVertexInfo = nothing(); monadLocal.alwaysDecorated = false; monadLocal.isRoot = false; top.monadRewritten = monadLocal.monadRewritten; @@ -117,7 +118,8 @@ top::Expr ::= 'case' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' decorate x.fst with {env=top.env; mDownSubst=top.mDownSubst; frame=top.frame; grammarName=top.grammarName; downSubst=top.mDownSubst; finalSubst=top.mDownSubst; compiledGrammars=top.compiledGrammars; - config=top.config; alwaysDecorated = false; flowEnv=top.flowEnv;expectedMonad=top.expectedMonad; + config=top.config; decSiteVertexInfo = nothing(); alwaysDecorated = false; + flowEnv=top.flowEnv; expectedMonad=top.expectedMonad; isRoot=top.isRoot;} in if isMonad(a.mtyperep, top.env) && monadsMatch(a.mtyperep, top.expectedMonad, top.mDownSubst).fst && !isMonad(performSubstitution(x.snd, top.mDownSubst), top.env) @@ -125,7 +127,8 @@ top::Expr ::= 'case' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' frame=top.frame; grammarName=top.grammarName; downSubst=top.mDownSubst; finalSubst=top.mDownSubst; compiledGrammars=top.compiledGrammars; config=top.config; flowEnv=top.flowEnv; monadicallyUsed=true; - expectedMonad=top.expectedMonad; alwaysDecorated = false; isRoot=top.isRoot;}.monadicNames + expectedMonad=top.expectedMonad; + decSiteVertexInfo = nothing(); alwaysDecorated = false; isRoot=top.isRoot;}.monadicNames else [] end ++ l, monadLocal.monadicNames, zipWith(\x::Expr y::Type -> (x,y), es.rawExprs, ml.patternTypeList)); @@ -407,6 +410,7 @@ top::Expr ::= 'case_any' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' downSubst = top.mDownSubst; finalSubst = top.mDownSubst; expectedMonad = top.expectedMonad; + decSiteVertexInfo = nothing(); alwaysDecorated = false; isRoot = top.isRoot; }.monadRewritten, @@ -422,7 +426,7 @@ top::Expr ::= 'case_any' es::Exprs 'of' vbar::Opt_Vbar_t ml::MRuleList 'end' {flowEnv = top.flowEnv; env = top.env; config=top.config; compiledGrammars=top.compiledGrammars; grammarName=top.grammarName; frame=top.frame; downSubst=top.mDownSubst; finalSubst=top.mDownSubst; - isRoot=top.isRoot; + decSiteVertexInfo = top.decSiteVertexInfo; isRoot=top.isRoot; }.typerep in if isMonad(ty, top.env) && monadsMatch(ty, top.expectedMonad, top.mDownSubst).fst @@ -475,7 +479,7 @@ Expr ::= exprs::[Expr] names::[String] base::Expr downSubst=sub; finalSubst=sub; compiledGrammars=cg; config=c; flowEnv=fe; expectedMonad=em; - isRoot = iR; alwaysDecorated = false; }.mtyperep + isRoot = iR; decSiteVertexInfo = nothing(); alwaysDecorated = false; }.mtyperep in if isMonad(ety, env) && fst(monadsMatch(ety, em, sub)) then buildApplication( @@ -579,6 +583,7 @@ top::MatchRule ::= pt::PatternList arr::Arrow_kwd e::Expr ne.frame = top.frame; ne.finalSubst = top.mDownSubst; ne.downSubst = top.mDownSubst; + ne.decSiteVertexInfo = nothing(); ne.alwaysDecorated = false; ne.isRoot = false; @@ -599,6 +604,7 @@ top::MatchRule ::= pt::PatternList 'when' cond::Expr arr::Arrow_kwd e::Expr ncond.frame = top.frame; ncond.finalSubst = top.mDownSubst; ncond.downSubst = top.mDownSubst; + ncond.decSiteVertexInfo = nothing(); ncond.alwaysDecorated = false; ncond.isRoot = false; local ne::Expr = e; @@ -610,6 +616,7 @@ top::MatchRule ::= pt::PatternList 'when' cond::Expr arr::Arrow_kwd e::Expr ne.frame = top.frame; ne.finalSubst = top.mDownSubst; ne.downSubst = top.mDownSubst; + ne.decSiteVertexInfo = nothing(); ne.alwaysDecorated = false; ne.isRoot = false; @@ -630,6 +637,7 @@ top::MatchRule ::= pt::PatternList 'when' cond::Expr 'matches' p::Pattern arr::A ncond.frame = top.frame; ncond.finalSubst = top.mDownSubst; ncond.downSubst = top.mDownSubst; + ncond.decSiteVertexInfo = nothing(); ncond.alwaysDecorated = false; ncond.isRoot = false; local ne::Expr = e; @@ -641,6 +649,7 @@ top::MatchRule ::= pt::PatternList 'when' cond::Expr 'matches' p::Pattern arr::A ne.frame = top.frame; ne.finalSubst = top.mDownSubst; ne.downSubst = top.mDownSubst; + ne.decSiteVertexInfo = nothing(); ne.alwaysDecorated = false; ne.isRoot = false; @@ -691,6 +700,7 @@ top::AbstractMatchRule ::= pl::[Decorated Pattern] cond::Maybe<(Expr, Maybe " ++ f.unparse ++ "end"; propagate config, grammarName, env, freeVars, frame, compiledGrammars, finalSubst, originRules, flowEnv; + e.decSiteVertexInfo = nothing(); e.isRoot = false; e.downSubst = top.downSubst; diff --git a/test/flow/RefSiteProj.sv b/test/flow/RefSiteProj.sv index 18cc2c779..f56b6f12c 100644 --- a/test/flow/RefSiteProj.sv +++ b/test/flow/RefSiteProj.sv @@ -56,6 +56,14 @@ top::RSExpr ::= e::RSExpr forwards to copy1(@e); } +production fork +top::RSExpr ::= e1::RSExpr e2::RSExpr +{ + propagate env1, env2; + top.errors1 = e1.errors1 || e2.errors1; + top.errors2 = e1.errors2 || e2.errors2; +} + warnCode "child e of production flow:copy1" { production proj2Missing top::RSExpr ::= e::RSExpr @@ -336,3 +344,80 @@ top::RSExpr ::= e::RSExpr forwards to if e.errors1 then base() else @fwrd; } + +production shareLetBinding +top::RSExpr ::= e::RSExpr +{ + top.errors1 = e.errors1; + forwards to + let e1::Decorated RSExpr with {} = e + in copy12(@e1) + end; +} + +production shareInLetBinding +top::RSExpr ::= e::RSExpr +{ + top.errors1 = e.errors1; + forwards to + let e1::RSExpr = copy12(@e) + in copy12(e1) + end; +} + +wrongFlowCode "Cannot share a tree here" { +production shareInLetBindingNotDecSite +top::RSExpr ::= e::RSExpr +{ + top.errors1 = e.errors1; + forwards to + let e1::RSExpr = copy12(@e) + in if hackUnparse(e1) == "" then new(e) else base() + end; +} +} + +production condShareInLetBinding +top::RSExpr ::= e::RSExpr +{ + forwards to + let e1::RSExpr = copy12(@e) + in if null(top.env1) then copy12(e1) else base() + end; +} + +warnCode "Equation requires inherited attribute flow:env1 be supplied to child e of production flow:condShareInLetBindingDep" { +production condShareInLetBindingDep +top::RSExpr ::= e::RSExpr +{ + top.errors1 = e.errors1; + forwards to + let e1::RSExpr = copy12(@e) + in if null(top.env1) then copy12(e1) else base() + end; +} +} + +wrongFlowCode "Cannot share a tree here" { +production shareInUnusedLetBinding +top::RSExpr ::= e::RSExpr +{ + top.errors1 = e.errors1; + forwards to + let e1::RSExpr = copy12(@e) + in if null(top.env1) then new(e) else base() + end; +} +} + +-- Not an ideal error message (the issue is the duplicate use of e1), but good enough. +wrongFlowCode "Cannot share a tree here" { +production duplicateShareLetBinding +top::RSExpr ::= e::RSExpr +{ + forwards to + let e1::RSExpr = copy12(@e) + in fork(e1, e1) + end; +} +} \ No newline at end of file From 061cf6dc1fd1a3bd357edee7890916fc3e76f1b6 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 7 May 2024 14:11:51 -0500 Subject: [PATCH 270/283] Add tests --- test/flow/References.sv | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/flow/References.sv b/test/flow/References.sv index 5f9a49796..4c6c1a3ca 100644 --- a/test/flow/References.sv +++ b/test/flow/References.sv @@ -98,3 +98,22 @@ Decorated RExpr<{env1}> with {env1} ::= warnCode "Duplicate equation for env1" { global decDuplicate::Decorated Expr with {env1, env2} = decorate zero() with {env1 = []; env2 = []; env1 = ["a"];}; } + +wrongFlowCode "Cannot share a tree here" { +function shareRet +Expr ::= +{ + local x::Expr = zero(); + return @x; +} +} + +wrongFlowCode "Cannot share a tree here" { +function shareNondec +Boolean ::= +{ + local x::Expr = zero(); + nondecorated y :: Expr = @x; + return true; +} +} From e7d763f45ca11d72a6092b81c60e697da2e6019a Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Thu, 9 May 2024 10:54:08 -0500 Subject: [PATCH 271/283] Fix spelling of file name ConvertablePrim -> ConvertiblePrim --- grammars/silver/core/{ConvertablePrim.sv => ConvertiblePrim.sv} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename grammars/silver/core/{ConvertablePrim.sv => ConvertiblePrim.sv} (100%) diff --git a/grammars/silver/core/ConvertablePrim.sv b/grammars/silver/core/ConvertiblePrim.sv similarity index 100% rename from grammars/silver/core/ConvertablePrim.sv rename to grammars/silver/core/ConvertiblePrim.sv From 415ac5f5b2d758f57803c0e707c774e6a4e3296a Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 20 May 2024 21:16:55 -0500 Subject: [PATCH 272/283] Preserve runtime uniqueness info in origin tracking manipulations of nodes --- .../silver/compiler/translation/java/core/ProductionDcl.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv index 968970a1e..d5519641f 100644 --- a/grammars/silver/compiler/translation/java/core/ProductionDcl.sv +++ b/grammars/silver/compiler/translation/java/core/ProductionDcl.sv @@ -378,7 +378,7 @@ ${makeTyVarDecls(3, namedSig.typerep.freeVariables)} } return new ${className}( ${implode(", ", - "oi" :: + "oi" :: "isUnique" :: namedSig.contextRefElems ++ map(dupChild, namedSig.inputElements) ++ map(copyAnno, namedSig.namedInputElements))}); @@ -388,7 +388,7 @@ ${makeTyVarDecls(3, namedSig.typerep.freeVariables)} public ${fnnt} updateOriginInfo(silver.core.NOriginInfo oi) { return new ${className}( ${implode(", ", - "oi" :: + "oi" :: "isUnique" :: namedSig.contextRefElems ++ map(copyChild, namedSig.inputElements) ++ map(copyAnno, namedSig.namedInputElements))}); From ae9ee4ee41fc92ced430223569bd711d63598ade Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 24 May 2024 21:51:38 -0500 Subject: [PATCH 273/283] Tweak to fetch-jars script to allow fetching latest locally-cached jars --- fetch-jars | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/fetch-jars b/fetch-jars index 629002200..2e100358d 100755 --- a/fetch-jars +++ b/fetch-jars @@ -20,8 +20,15 @@ done COMMIT_ARTIFACTS="https://foundry.remexre.xyz/commit-artifacts/" +[[ $* == *--local* ]] +LOCAL_JARS=$? + function has_jars { - wget --spider -q "$COMMIT_ARTIFACTS/$1" + if [[ $LOCAL_JARS -eq 0 ]]; then + [[ -d "JARS-BAK/$1" ]] + else + wget --spider -q "$COMMIT_ARTIFACTS/$1" + fi } rev="" @@ -34,7 +41,7 @@ fi # Get the hash of the latest commit on develop. # This always gives the latest commit regardless of if the repo is up to date, # and works in a Jenkins checkout. -DEVELOP=$(git ls-remote https://github.com/melt-umn/silver develop | cut -f1) +DEVELOP=$(git ls-remote https://github.com/melt-umn/silver develop | cut -f1 | head -n1) # Look for jars in the current commit and its parents. # First, check that we are inside a git repo. @@ -51,8 +58,18 @@ if [[ -z $rev ]] && git rev-parse --is-inside-work-tree 1> /dev/null 2> /dev/nul done fi +if [[ -z $rev ]]; then + echo "Failed to find jars for the specified revision or any of its ancestors." + exit 1 +fi + # Figure out how to obtain the jars from the revision we chose. -if [[ $* != *--unstable* && (-z $rev || $rev == "$DEVELOP") ]]; then +if [[ $* == *--local* ]]; then + echo "Fetching local jars..." + LOCAL_STORE="JARS-BAK/$rev" + REMOTE_STORE= + JARS_BAK= +elif [[ $* != *--unstable* && $* != *--local* && (-z $rev || $rev == "$DEVELOP") ]]; then echo "Fetching latest stable jars..." LOCAL_STORE=/web/research/melt.cs.umn.edu/downloads/silver-dev/jars REMOTE_STORE="https://melt.cs.umn.edu/downloads/silver-dev/jars" From b010c223ee9315cdffb51614f0d880bd7092c204 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 24 May 2024 22:12:11 -0500 Subject: [PATCH 274/283] Add check for inherited occurs-on constraints that the type is undecorated --- .../silver/compiler/analysis/typechecking/core/Context.sv | 4 +++- test/silver_features/OccursContext.sv | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/grammars/silver/compiler/analysis/typechecking/core/Context.sv b/grammars/silver/compiler/analysis/typechecking/core/Context.sv index db5c2e7c7..e8c5da12d 100644 --- a/grammars/silver/compiler/analysis/typechecking/core/Context.sv +++ b/grammars/silver/compiler/analysis/typechecking/core/Context.sv @@ -68,7 +68,9 @@ top::Context ::= attr::String args::[Type] atty::Type ntty::Type -- atty should never have free type variables if ntty does not, except in case of errors elsewhere. else {-if !null(atty.freeFlexibleVars) then error(s"got atty with free vars") - else-} if null(top.resolvedOccurs) + else-} if ntty.isDecorated + then [err(top.contextLoc, s"Could not find an instance for ${prettyContext(top)}; an undecorated type is expected here (arising from ${top.contextSource})")] + else if null(top.resolvedOccurs) then [err(top.contextLoc, s"Could not find an instance for ${prettyContext(top)} (arising from ${top.contextSource})")] else requiredContexts.contextErrors; diff --git a/test/silver_features/OccursContext.sv b/test/silver_features/OccursContext.sv index 17377bd89..9d189b4c1 100644 --- a/test/silver_features/OccursContext.sv +++ b/test/silver_features/OccursContext.sv @@ -200,6 +200,10 @@ equalityTest( end, "blah", String, silver_tests); +wrongCode "Could not find an instance for attribute silver_features:prodNameIn occurs on Decorated silver_features:OCThing with {}; an undecorated type is expected here (arising from the use of ocPolyWrap)" { +global ocPolyWrapDecorated::OCPolyWrap = ocPolyWrap(decorate ocThing() with {}); +} + nonterminal OCWrapDec with prodName; production ocWrapDec From c1fd725a4fe3ecba72921f4ae8c6a56f0eb9021a Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 24 May 2024 22:18:19 -0500 Subject: [PATCH 275/283] Fix bug if a tree is shared in a polymorphic decoration site where fewer inherited attributes are supplied --- runtime/java/src/common/DecoratedNode.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/runtime/java/src/common/DecoratedNode.java b/runtime/java/src/common/DecoratedNode.java index bc2dfe721..96d538757 100644 --- a/runtime/java/src/common/DecoratedNode.java +++ b/runtime/java/src/common/DecoratedNode.java @@ -232,8 +232,10 @@ public DecoratedNode decorate(final DecoratedNode parent, final Lazy[] inhs, fin } private void copyInhOverrides(final DecoratedNode parent, final Lazy[] inhs, final Lazy[] newInhs) { - assert inhs.length == newInhs.length; - for(int i = 0; i < inhs.length; i++) { + // Arrays can differ in length if a tree is shared in a polymorphic decoration site. + // The new inh array should never be larger than the original one. + assert inhs.length >= newInhs.length; + for(int i = 0; i < newInhs.length; i++) { if(newInhs[i] != null) { Lazy newInh = newInhs[i].withContext(parent); if(inhs[i] == null) { From b227166197b7f809267222c7981bcbeadf122698 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 24 May 2024 22:30:56 -0500 Subject: [PATCH 276/283] Fix arg parsing in fetch-jars script change --- fetch-jars | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/fetch-jars b/fetch-jars index 2e100358d..cab5cba39 100755 --- a/fetch-jars +++ b/fetch-jars @@ -2,10 +2,11 @@ set -eu -# Usage: ./fetch-jars [rev-name] [--unstable] [--copper] +# Usage: ./fetch-jars [rev-name] [--unstable] [--local] [--copper] # If a revision is not specified, the script fetches the latest jars from the current branch, # falling back to develop. # If --unstable is specified, always fetch from commit artifacts on foundry. +# If --local is specified, only fetch jars from the local cache. # If --copper is specified, only fetch the Copper jars. # Parse command line argumants. @@ -20,11 +21,9 @@ done COMMIT_ARTIFACTS="https://foundry.remexre.xyz/commit-artifacts/" -[[ $* == *--local* ]] -LOCAL_JARS=$? - +args=$* function has_jars { - if [[ $LOCAL_JARS -eq 0 ]]; then + if [[ $args == *--local* ]]; then [[ -d "JARS-BAK/$1" ]] else wget --spider -q "$COMMIT_ARTIFACTS/$1" From cdf72e587bd0963b1253b129548de1f52cc2cdef Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 24 May 2024 22:48:37 -0500 Subject: [PATCH 277/283] Fix broken fallback behavior when not fetching local jars --- fetch-jars | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fetch-jars b/fetch-jars index cab5cba39..f89c4e8ed 100755 --- a/fetch-jars +++ b/fetch-jars @@ -57,13 +57,13 @@ if [[ -z $rev ]] && git rev-parse --is-inside-work-tree 1> /dev/null 2> /dev/nul done fi -if [[ -z $rev ]]; then - echo "Failed to find jars for the specified revision or any of its ancestors." - exit 1 -fi - # Figure out how to obtain the jars from the revision we chose. if [[ $* == *--local* ]]; then + if [[ -z $rev ]]; then + echo "Failed to find local jars for the specified revision." + exit 1 + fi + echo "Fetching local jars..." LOCAL_STORE="JARS-BAK/$rev" REMOTE_STORE= From d5904cc2084b55034d2294a416d5f64448ef8fb9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jun 2024 18:56:13 +0000 Subject: [PATCH 278/283] Bump braces from 3.0.2 to 3.0.3 in /support/vs-code/silverlsp Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3. - [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: braces dependency-type: indirect ... Signed-off-by: dependabot[bot] --- support/vs-code/silverlsp/package-lock.json | 28 ++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/support/vs-code/silverlsp/package-lock.json b/support/vs-code/silverlsp/package-lock.json index 03b8a5d7f..b2fc0674b 100644 --- a/support/vs-code/silverlsp/package-lock.json +++ b/support/vs-code/silverlsp/package-lock.json @@ -747,12 +747,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -1561,9 +1561,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -4183,12 +4183,12 @@ } }, "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" } }, "browser-stdout": { @@ -4784,9 +4784,9 @@ } }, "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "requires": { "to-regex-range": "^5.0.1" From d7dc7290e52dd06f98d4f0720883782fdd675fb1 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 21 Jun 2024 22:52:52 -0700 Subject: [PATCH 279/283] Support referencing forwardParent --- .../silver/compiler/definition/core/Expr.sv | 12 ++++++++++++ .../compiler/definition/core/Terminals.sv | 1 + .../compiler/definition/flow/ast/Vertex.sv | 3 +++ .../compiler/definition/flow/ast/VertexType.sv | 14 ++++++++++++++ .../definition/flow/driver/ProductionGraph.sv | 18 ++++++++++++++++-- .../compiler/definition/flow/env/Expr.sv | 13 +++++++++++++ .../compiler/definition/flow/env/FlowEnv.sv | 2 ++ .../compiler/extension/implicit_monads/Expr.sv | 11 +++++++++++ .../compiler/translation/java/core/Expr.sv | 10 ++++++++++ .../translation/java/core/NamedSignature.sv | 1 + test/silver_features/TreeSharing.sv | 17 ++++++++++++++++- 11 files changed, 99 insertions(+), 3 deletions(-) diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index 1a7ecf802..9fe288323 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -266,6 +266,18 @@ top::Expr ::= q::'forward' forwards to baseExpr(qName("forward")); } +concrete production forwardParentReference +top::Expr ::= 'forwardParent' +{ + top.unparse = "forwardParent"; + + top.typerep = top.frame.signature.outputElement.typerep.asNtOrDecType; + top.errors <- + if !any(map((.elementShared), top.frame.signature.inputElements)) + then [errFromOrigin(top, "This production has no shared children and is not known to be the target of forwarding.")] + else []; +} + concrete production application top::Expr ::= e::Expr '(' es::AppExprs ',' anns::AnnoAppExprs ')' { diff --git a/grammars/silver/compiler/definition/core/Terminals.sv b/grammars/silver/compiler/definition/core/Terminals.sv index 5c9d6c830..01caed5fe 100644 --- a/grammars/silver/compiler/definition/core/Terminals.sv +++ b/grammars/silver/compiler/definition/core/Terminals.sv @@ -43,6 +43,7 @@ terminal End_kwd 'end' lexer classes {KEYWORD,RESERVED}; terminal Forwarding_kwd 'forwarding' lexer classes {KEYWORD,RESERVED}; terminal Forward_kwd 'forward' lexer classes {KEYWORD,RESERVED}; terminal Forwards_kwd 'forwards' lexer classes {KEYWORD,RESERVED}; +terminal ForwardParent_kwd 'forwardParent' lexer classes {KEYWORD,RESERVED}; terminal Function_kwd 'function' lexer classes {KEYWORD,RESERVED}; terminal Global_kwd 'global' lexer classes {KEYWORD,RESERVED}; terminal If_kwd 'if' lexer classes {KEYWORD,RESERVED}; diff --git a/grammars/silver/compiler/definition/flow/ast/Vertex.sv b/grammars/silver/compiler/definition/flow/ast/Vertex.sv index b647ea232..e67cbfbb4 100644 --- a/grammars/silver/compiler/definition/flow/ast/Vertex.sv +++ b/grammars/silver/compiler/definition/flow/ast/Vertex.sv @@ -129,3 +129,6 @@ fun forwardEqVertex FlowVertex ::= = localEqVertex("forward"); -- An attribute on the forward node for this production fun forwardSynVertex FlowVertex ::= attrName::String = localSynVertex("forward", attrName); fun forwardInhVertex FlowVertex ::= attrName::String = localInhVertex("forward", attrName); + +-- An attribute on the production that forwarded to this one +fun forwardParentSynVertex FlowVertex ::= attrName::String = localSynVertex("forwardParent", attrName); diff --git a/grammars/silver/compiler/definition/flow/ast/VertexType.sv b/grammars/silver/compiler/definition/flow/ast/VertexType.sv index e9814f015..5ea2aba09 100644 --- a/grammars/silver/compiler/definition/flow/ast/VertexType.sv +++ b/grammars/silver/compiler/definition/flow/ast/VertexType.sv @@ -109,6 +109,20 @@ top::VertexType ::= top.eqVertex = [forwardEqVertex_singleton]; } +abstract production forwardParentVertexType +top::VertexType ::= +{ + top.vertexName = "forwardParent"; + top.vertexPP = "forward parent"; + top.isInhDefVertex = false; + top.synVertex = forwardParentSynVertex; + top.inhVertex = lhsInhVertex; + -- The forward of the forward parent is the LHS of this production, which doesn't have a vertex! + -- This should never really be consulted in practice. + top.fwdVertex = localEqVertex("__lhs"); + top.eqVertex = []; +} + {-- - Represents the vertexes for anonymous vertex types somewhere within a production (e.g. 'decorate with' expressions). -} diff --git a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv index 1e5331f47..ca1273fad 100644 --- a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv @@ -156,7 +156,7 @@ ProductionGraph ::= dcl::ValueDclInfo flowEnv::FlowEnv realEnv::Env local inhs :: [String] = getInhAndInhOnTransAttrsOn(nt, realEnv); -- Does this production forward? local nonForwarding :: Boolean = null(lookupFwd(prod, flowEnv)); - + -- Normal edges! local normalEdges :: [(FlowVertex, FlowVertex)] = flatMap((.flowEdges), defs); @@ -196,7 +196,13 @@ ProductionGraph ::= dcl::ValueDclInfo flowEnv::FlowEnv realEnv::Env dcl.namedSignature.inputElements, sig.inputElements)) | nothing() -> [] - end; + end ++ + if any(map((.elementShared), dcl.namedSignature.inputElements)) + -- TODO: We could be more precise here by only considering the productions + -- that could have actually forwarded to this one. But that would require + -- introducing a new sort of stitch point. + then nonterminalStitchPoints(realEnv, nt, localVertexType("forwardParent")) + else []; local flowTypeVertexesOverall :: [FlowVertex] = (if nonForwarding then [] else [forwardEqVertex()]) ++ @@ -366,6 +372,14 @@ ProductionGraph ::= nt::String flowEnv::FlowEnv realEnv::Env return productionGraph("Phantom for " ++ nt, nt, flowTypeVertexes, initialGraph, suspectEdges, stitchPoints).transitiveClosure; } +{-- + - Constructs a graph for a dispatch signature. + - + - @param ns The dispatch signature + - @param flowEnv A full flow environment (need to find uses and impls of this sig) + - @param realEnv A full real environment (need to find out original signature and what inhs occur for stitch points) + - @return A fixed up graph. + -} function constructDispatchGraph ProductionGraph ::= ns::NamedSignature flowEnv::FlowEnv realEnv::Env { diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index 9b69cfe07..8ffa1c11d 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -151,6 +151,19 @@ top::Expr ::= @q::QName then just(forwardVertexType) else nothing(); } +aspect production forwardParentReference +top::Expr ::= 'forwardParent' +{ + production refSet::Maybe<[String]> = getMaxRefSet(top.finalType, top.env); + top.flowDeps <- + if top.finalType.isDecorated + then map(forwardVertexType.inhVertex, fromMaybe([], refSet)) + else []; + top.flowVertexInfo = + if top.finalType.isDecorated + then just(forwardVertexType) + else nothing(); +} -- The named signature of the applied production. -- Note that we don't project functions at the moment, since we don't build function flow graphs during inference. diff --git a/grammars/silver/compiler/definition/flow/env/FlowEnv.sv b/grammars/silver/compiler/definition/flow/env/FlowEnv.sv index 5f0e6c9c9..c26495d22 100644 --- a/grammars/silver/compiler/definition/flow/env/FlowEnv.sv +++ b/grammars/silver/compiler/definition/flow/env/FlowEnv.sv @@ -141,6 +141,7 @@ fun vertexHasInhEq Boolean ::= prodName::String vt::VertexType attrName::Strin -- but here we are remotely looking for equations that might not be the direct dependency of -- anything in the prod flow graph. | lhsVertexType_real() -> false -- Shouldn't ever be directly needed, since the LHS is never the dec site for another vertex. + | forwardParentVertexType() -> false -- Same as LHS - the thing that forwared to us. | forwardVertexType_real() -> false -- Same as LHS, but we can check this if e.g. forwarding to a child. end; @@ -164,6 +165,7 @@ fun countVertexEqs Integer ::= prodName::String vt::VertexType attrName::Strin | anonVertexType(fName) -> length(lookupLocalInh(prodName, fName, attrName, flowEnv)) | subtermVertexType(_, remoteProdName, sigName) -> 0 | lhsVertexType_real() -> length(lookupSyn(prodName, attrName, flowEnv)) + | forwardParentVertexType() -> 0 | forwardVertexType_real() -> length(lookupFwdInh(prodName, attrName, flowEnv)) end; diff --git a/grammars/silver/compiler/extension/implicit_monads/Expr.sv b/grammars/silver/compiler/extension/implicit_monads/Expr.sv index 7b18cea06..c435ba541 100644 --- a/grammars/silver/compiler/extension/implicit_monads/Expr.sv +++ b/grammars/silver/compiler/extension/implicit_monads/Expr.sv @@ -170,6 +170,17 @@ top::Expr ::= @q::QName top.monadRewritten = baseExpr(new(q)); } +aspect production forwardParentReference +top::Expr ::= 'forwardParent' +{ + top.merrors := []; + propagate mDownSubst, mUpSubst; + -- An LHS (and thus, forward parent) is *always* a decorable (nonterminal) type. + top.mtyperep = top.typerep; + top.monadicNames = []; + top.monadRewritten = top; +} + aspect production application top::Expr ::= e::Expr '(' es::AppExprs ',' anns::AnnoAppExprs ')' { diff --git a/grammars/silver/compiler/translation/java/core/Expr.sv b/grammars/silver/compiler/translation/java/core/Expr.sv index c62a713bc..dcafea70c 100644 --- a/grammars/silver/compiler/translation/java/core/Expr.sv +++ b/grammars/silver/compiler/translation/java/core/Expr.sv @@ -147,6 +147,16 @@ top::Expr ::= @q::QName top.lazyTranslation = wrapThunk(top.translation, top.frame.lazyApplication); } +aspect production forwardParentReference +top::Expr ::= 'forwardParent' +{ + top.translation = + if top.finalType.isDecorated + then "context.getForwardParent()" + else s"((${top.finalType.transType})context.getForwardParent().undecorate())"; + top.lazyTranslation = top.translation; -- Must have already been evaluated +} + aspect production productionReference top::Expr ::= @q::QName { diff --git a/grammars/silver/compiler/translation/java/core/NamedSignature.sv b/grammars/silver/compiler/translation/java/core/NamedSignature.sv index f3a79a659..17cc91a69 100644 --- a/grammars/silver/compiler/translation/java/core/NamedSignature.sv +++ b/grammars/silver/compiler/translation/java/core/NamedSignature.sv @@ -351,6 +351,7 @@ fun refAccessTranslation String ::= env::Env flowEnv::FlowEnv lhsNtName::String end | transAttrVertexType(_, transAttr) -> error("trans attr on non-lhs can't be a ref decoration site") | forwardVertexType_real() -> s"context.forward()" + | forwardParentVertexType() -> error("forward parent shouldn't be a ref decoration site") | anonVertexType(_) -> error("dec site projection shouldn't happen with anon decorate") | subtermVertexType(parent, prodName, sigName) -> -- prodName is either a production or dispatch signature name diff --git a/test/silver_features/TreeSharing.sv b/test/silver_features/TreeSharing.sv index d1977b44c..17c4c8526 100644 --- a/test/silver_features/TreeSharing.sv +++ b/test/silver_features/TreeSharing.sv @@ -81,7 +81,22 @@ top::UDExpr ::= @e::UDExpr top.errors2 = e2.errors2; } -global udTerm::UDExpr = udOp1(udOp2(udOp3(udOp4(udVar("foo"))))); +production udOp5 +top::UDExpr ::= e::UDExpr +{ + e.env1 = top.env1; + top.errors1 = e.errors1; + forwards to udOp5Impl(e); +} + +production udOp5Impl +top::UDExpr ::= @e::UDExpr +{ + e.env2 = forwardParent.env2; + top.errors2 = forwardParent.errors1 || e.errors2; +} + +global udTerm::UDExpr = udOp1(udOp2(udOp3(udOp4(udOp5(udVar("foo")))))); equalityTest(decorate udTerm with { env1 = ["foo"]; env2 = ["foo"]; }.errors1, false, Boolean, silver_tests); equalityTest(decorate udTerm with { env1 = ["foo"]; env2 = ["foo"]; }.errors2, false, Boolean, silver_tests); equalityTest(decorate udTerm with { env1 = ["foo"]; env2 = []; }.errors1, false, Boolean, silver_tests); From 478540b451b8861955222c4d68e73e91e2a9707c Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Fri, 21 Jun 2024 23:03:42 -0700 Subject: [PATCH 280/283] Tweak test case --- test/silver_features/TreeSharing.sv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/silver_features/TreeSharing.sv b/test/silver_features/TreeSharing.sv index 17c4c8526..4d48f7faa 100644 --- a/test/silver_features/TreeSharing.sv +++ b/test/silver_features/TreeSharing.sv @@ -93,7 +93,8 @@ production udOp5Impl top::UDExpr ::= @e::UDExpr { e.env2 = forwardParent.env2; - top.errors2 = forwardParent.errors1 || e.errors2; + top.errors1 = forwardParent.errors1; + top.errors2 = e.errors2; } global udTerm::UDExpr = udOp1(udOp2(udOp3(udOp4(udOp5(udVar("foo")))))); From f7c5d0505efa4f85726d51880b208e8d5125cb8d Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Wed, 26 Jun 2024 22:16:15 -0700 Subject: [PATCH 281/283] Add unary undecoration operator '^' --- .../silver/compiler/definition/core/Expr.sv | 26 ++++++++++++------- .../compiler/definition/core/Terminals.sv | 1 + test/silver_features/Types.sv | 4 +++ 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/grammars/silver/compiler/definition/core/Expr.sv b/grammars/silver/compiler/definition/core/Expr.sv index 1a7ecf802..32f0ea3d4 100644 --- a/grammars/silver/compiler/definition/core/Expr.sv +++ b/grammars/silver/compiler/definition/core/Expr.sv @@ -667,15 +667,6 @@ top::Expr ::= 'decorate' e::Expr 'with' '{' inh::ExprInhs '}' inh.allSuppliedInhs = inh.suppliedInhs; } -concrete production decorationSiteExpr -top::Expr ::= '@' e::Expr -{ - top.unparse = s"@${e.unparse}"; - - top.typerep = e.typerep.decoratedType; - e.isRoot = false; -} - abstract production exprInhsEmpty top::ExprInhs ::= { @@ -723,6 +714,23 @@ top::ExprLHSExpr ::= q::QNameAttrOccur q.attrFor = top.decoratingnt; } +concrete production decorationSiteExpr +top::Expr ::= '@' e::Expr +{ + top.unparse = s"@${e.unparse}"; + + top.typerep = e.typerep.decoratedType; + e.isRoot = false; +} + +concrete production undecExpr +top::Expr ::= '^' e::Expr +{ + top.unparse = s"^${e.unparse}"; + + forwards to Silver_Expr { silver:core:new($Expr{@e}) }; +} + concrete production trueConst top::Expr ::= 'true' { diff --git a/grammars/silver/compiler/definition/core/Terminals.sv b/grammars/silver/compiler/definition/core/Terminals.sv index 5c9d6c830..32c97dc4b 100644 --- a/grammars/silver/compiler/definition/core/Terminals.sv +++ b/grammars/silver/compiler/definition/core/Terminals.sv @@ -85,6 +85,7 @@ terminal Divide_t '/' lexer classes {OP}, precedence = 12, association = l terminal Modulus_t '%' lexer classes {OP}, precedence = 12, association = left; terminal ColonColon_t '::' lexer classes {OP}, precedence = 14, association = right; -- HasType AND cons. right due to cons. terminal DecSite_t '@' lexer classes {OP}, precedence = 20; +terminal Undec_t '^' lexer classes {OP}, precedence = 20; terminal LParen_t '(' precedence = 24; terminal RParen_t ')' precedence = 1, association = left; -- Precedence and association eeded for dangling else in action code. terminal LCurly_t '{' ; diff --git a/test/silver_features/Types.sv b/test/silver_features/Types.sv index 5207bd434..3dee814c2 100644 --- a/test/silver_features/Types.sv +++ b/test/silver_features/Types.sv @@ -269,6 +269,10 @@ wrongCode "{silver_features:env1, :env2} is not a subset of {silver_features:env global dBad :: [String] = getEnv1Cycle(decorate mkDExpr() with {env1 = [];}, decorate mkDExpr() with {env1 = []; env2 = [];}); } +global u1 :: DExpr = new(d1); +global u2 :: DExpr = ^d2; +global u3 :: DExpr = ^decorate mkDExpr() with {}; + function getEnv1ChainedAmb {env1} subset i1, i1 subset i2 => [String] ::= x::Decorated DExpr with i2 { From f0002aded42ef83889b783bcd5fcc5e72a39778a Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Mon, 30 Sep 2024 20:33:25 -0500 Subject: [PATCH 282/283] Fix vertex type for forwardParent reference --- grammars/silver/compiler/definition/flow/env/Expr.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grammars/silver/compiler/definition/flow/env/Expr.sv b/grammars/silver/compiler/definition/flow/env/Expr.sv index 8ffa1c11d..8e9ee3ef3 100644 --- a/grammars/silver/compiler/definition/flow/env/Expr.sv +++ b/grammars/silver/compiler/definition/flow/env/Expr.sv @@ -157,11 +157,11 @@ top::Expr ::= 'forwardParent' production refSet::Maybe<[String]> = getMaxRefSet(top.finalType, top.env); top.flowDeps <- if top.finalType.isDecorated - then map(forwardVertexType.inhVertex, fromMaybe([], refSet)) + then map(forwardParentVertexType().inhVertex, fromMaybe([], refSet)) else []; top.flowVertexInfo = if top.finalType.isDecorated - then just(forwardVertexType) + then just(forwardParentVertexType()) else nothing(); } From 9ba66a426d0b6210320c8c34860e89db3f075f37 Mon Sep 17 00:00:00 2001 From: Lucas Kramer Date: Tue, 1 Oct 2024 15:32:30 -0500 Subject: [PATCH 283/283] Fix MWDA bug with forwardParent --- .../silver/compiler/definition/flow/driver/ProductionGraph.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv index ca1273fad..bec111046 100644 --- a/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv +++ b/grammars/silver/compiler/definition/flow/driver/ProductionGraph.sv @@ -201,7 +201,7 @@ ProductionGraph ::= dcl::ValueDclInfo flowEnv::FlowEnv realEnv::Env -- TODO: We could be more precise here by only considering the productions -- that could have actually forwarded to this one. But that would require -- introducing a new sort of stitch point. - then nonterminalStitchPoints(realEnv, nt, localVertexType("forwardParent")) + then nonterminalStitchPoints(realEnv, nt, forwardParentVertexType()) else []; local flowTypeVertexesOverall :: [FlowVertex] =