diff --git a/syntax/text/parser3/src/Luna/Pass/Parsing/Parser.hs b/syntax/text/parser3/src/Luna/Pass/Parsing/Parser.hs index a26aa9d9d58d..62deb606caee 100644 --- a/syntax/text/parser3/src/Luna/Pass/Parsing/Parser.hs +++ b/syntax/text/parser3/src/Luna/Pass/Parsing/Parser.hs @@ -297,6 +297,7 @@ buildIR = \(Spanned cs ast) -> addCodeSpan cs =<< case ast of Ast.InfixApp l f r -> do let tok = Ast.unspan f + dot = tok == Ast.Operator Name.acc specialOp = case tok of Ast.Operator op -> if | op == Name.assign -> Just IR.unify' @@ -305,22 +306,46 @@ buildIR = \(Spanned cs ast) -> addCodeSpan cs =<< case ast of | otherwise -> Nothing _ -> Nothing realNumber = - let dot = tok == Ast.Operator Name.acc - isNumber ast = case Ast.unspan ast of + let isNumber ast = case Ast.unspan ast of Ast.Number _ -> True _ -> False lIsNum = isNumber l rIsNum = isNumber r in dot && lIsNum && rIsNum + -- The old parser translates a .foo.bar to application + -- between Var "a" and AccSection ["foo", "bar"], a core + -- constructor of form AccSection { path :: Vec16 Name }. + -- The constructor is deprecated, as it supports only named + -- sections and discards information about code spans. + -- The real solution should be implemented in passes, + -- probably in desugaring, as this situation is very similar + -- to wildcard handling. + -- See luna/luna#301 for more info + hackAccSection left op = do + let noHack = do + r' <- buildIR $! Ast.prependAsOffset f r + op left r' + if dot then do + Layer.read @IR.Model left >>= \case + Uni.AccSection accSec' -> do + case Ast.unspan r of + Ast.Var r' -> do + oldSection <- Mutable.toList accSec' + newSection <- Mutable.fromList + (oldSection <> [r']) + IR.accSection' newSection + _ -> noHack + _ -> noHack + else noHack + case specialOp of Just op -> do if realNumber then do buildRealIR l r else do l' <- buildIR l - r' <- buildIR $! Ast.prependAsOffset f r - op l' r' + hackAccSection l' op Nothing -> do f' <- buildIR f l' <- buildIR l diff --git a/syntax/text/parser3/test/spec/Luna/Test/Source/Text/ParserSpec.hs b/syntax/text/parser3/test/spec/Luna/Test/Source/Text/ParserSpec.hs index 0c9ad8d41e36..381fa9befd02 100644 --- a/syntax/text/parser3/test/spec/Luna/Test/Source/Text/ParserSpec.hs +++ b/syntax/text/parser3/test/spec/Luna/Test/Source/Text/ParserSpec.hs @@ -81,10 +81,16 @@ unitSpec :: Spec unitSpec = describe "unit" $ do it "empty" $ e_x "" "" +accSectionSpec :: Spec +accSectionSpec = describe "acc section" $ do + ite "[1,2,3].each .succ.pred" "[1, 2, 3] . each .succ.pred" + ite "[1,2,3].each .succ.pred.foo" "[1, 2, 3] . each .succ.pred.foo" + ite "[1,2,3].each .succ.pred.foo.bar" "[1, 2, 3] . each .succ.pred.foo.bar" + debugSpec :: Spec debugSpec = xdescribe "error" $ it "debug" $ do - let input = [qqStr|.asText|] + let input = [qqStr|a .succ.pred.foo|] putStrLn "\n\n" pprint $ PP.evalVersion1With Macro.unit (convert input) @@ -102,5 +108,6 @@ spec = do functionDefSpec caseSpec unitSpec + accSectionSpec debugSpec