Add integers to AST. Find references in assignment statements.
This commit is contained in:
parent
bdc6dcda5b
commit
fa3093e61c
20
BACKLOG.md
20
BACKLOG.md
|
@ -36,4 +36,22 @@ in the call tree.
|
|||
}
|
||||
|
||||
|
||||
Write graphviz output.
|
||||
The above problem is sort of fixed by just writing DOT output as it
|
||||
takes care of cycles.
|
||||
|
||||
# Instance methods
|
||||
Instance methods are a common occurrence in Ruby code. However they
|
||||
aren't really resolved in a nice way. E.g.:
|
||||
|
||||
def f
|
||||
person.name
|
||||
end
|
||||
|
||||
Will produce:
|
||||
|
||||
{"f":["name"]}
|
||||
|
||||
Which is misleading. What we could do it try and find out what
|
||||
`person` is referring to and then "inline" it. For example. Assume
|
||||
that we have `"person": ["Person.new"]` in our references then we
|
||||
could add an entry for `f` like so: `"f": ["Person.name"]`.
|
||||
|
|
|
@ -35,6 +35,7 @@ dependencies:
|
|||
- temporary
|
||||
- text
|
||||
- hashable
|
||||
- scientific
|
||||
|
||||
default-extensions:
|
||||
- ConstraintKinds
|
||||
|
|
|
@ -20,16 +20,19 @@ module Data.Language.Ruby.AST
|
|||
, Ivar(..)
|
||||
, Atom(..)
|
||||
, Defs(..)
|
||||
, Self
|
||||
, Nil
|
||||
, Cbase
|
||||
, Self(..)
|
||||
, Nil(..)
|
||||
, Cbase(..)
|
||||
, Int(..)
|
||||
) where
|
||||
|
||||
import Data.Aeson (parseJSON, Value(Null,Object,Number,Bool), withArray)
|
||||
import Frelude hiding (String)
|
||||
import Prelude (Bounded)
|
||||
import Frelude hiding (String, Int)
|
||||
import qualified Frelude
|
||||
import qualified Data.Aeson.Types as Aeson
|
||||
import qualified Data.Vector as Vector
|
||||
import qualified Data.Scientific as Scientific
|
||||
|
||||
kebabCase :: Frelude.String -> Frelude.String
|
||||
kebabCase = Aeson.camelTo2 '-'
|
||||
|
@ -73,6 +76,7 @@ data Statement
|
|||
| StmtIvar Ivar
|
||||
| StmtSelf Self
|
||||
| StmtNil Nil
|
||||
| StmtInt Int
|
||||
| StmtCbase Cbase
|
||||
-- TODO Get rid of this
|
||||
| StmtAnything Anything
|
||||
|
@ -101,6 +105,7 @@ instance ToJSON Statement where
|
|||
"StmtIvar" -> "ivar"
|
||||
"StmtSelf" -> "self"
|
||||
"StmtNil" -> "nil"
|
||||
"StmtInt" -> "int"
|
||||
"StmtCbase" -> "cbase"
|
||||
x -> x
|
||||
|
||||
|
@ -121,6 +126,7 @@ instance FromJSON Statement where
|
|||
<|> (StmtIvar <$> parseJSON v)
|
||||
<|> (StmtSelf <$> parseJSON v)
|
||||
<|> (StmtNil <$> parseJSON v)
|
||||
<|> (StmtInt <$> parseJSON v)
|
||||
<|> (StmtCbase <$> parseJSON v)
|
||||
<|> (StmtAnything <$> parseJSON v)
|
||||
|
||||
|
@ -486,3 +492,29 @@ instance FromJSON Nil where
|
|||
parseJSON = \case
|
||||
Aeson.Null -> pure Nil
|
||||
_ -> empty
|
||||
|
||||
|
||||
newtype Int = Int Frelude.Int
|
||||
|
||||
deriving stock instance Show Int
|
||||
deriving newtype instance Ord Int
|
||||
deriving newtype instance Eq Int
|
||||
deriving stock instance Generic Int
|
||||
deriving newtype instance Enum Int
|
||||
deriving newtype instance Num Int
|
||||
deriving newtype instance Real Int
|
||||
deriving newtype instance Integral Int
|
||||
deriving newtype instance Bounded Int
|
||||
instance ToJSON Int where
|
||||
toEncoding = Aeson.genericToEncoding aesonOptions
|
||||
instance FromJSON Int where
|
||||
parseJSON = withArray "Int" $ \case
|
||||
[Aeson.String "int", atom] -> parseIntegral atom
|
||||
_ -> empty
|
||||
|
||||
parseIntegral :: forall f n . Alternative f => Bounded n => Integral n => Value -> f n
|
||||
parseIntegral = \case
|
||||
Aeson.Number s -> case Scientific.toBoundedInteger @n s of
|
||||
Nothing -> empty
|
||||
Just n -> pure $ fromIntegral n
|
||||
_ -> empty
|
||||
|
|
|
@ -138,8 +138,8 @@ instance Semigroup Node where
|
|||
(NodeModule n0, NodeModule n1) -> NodeModule $ n0 <> n1
|
||||
-- (NodeModule n0, NodeDef (FQN n1 f)) -> Context $ NodeDef $ FQN (n0 <> n1) f
|
||||
(NodeModule n0, NodeDef (FQN n1 f)) -> NodeDef $ FQN (n0 <> n1) f
|
||||
(NodeDef{}, NodeModule{}) -> error "Cannot append module to function context."
|
||||
-- (NodeDef{}, NodeDef{}) -> error "Cannot append function to function context."
|
||||
-- TODO: Problematic: Is a Node really a semigroup with this representation?
|
||||
(NodeDef{}, NodeModule{}) -> c1
|
||||
(NodeDef (FQN n0 _), NodeDef (FQN n1 a1)) -> NodeDef $ FQN (n0 <> n1) a1
|
||||
|
||||
class Monad m => MyMonad (m :: Type -> Type) where
|
||||
|
@ -250,6 +250,7 @@ instance References Ruby.Statement where
|
|||
Ruby.StmtSelf s -> entries s
|
||||
Ruby.StmtCbase s -> entries s
|
||||
Ruby.StmtNil n -> entries n
|
||||
Ruby.StmtInt n -> entries n
|
||||
Ruby.StmtAnything a -> entries a
|
||||
|
||||
instance References Ruby.Block where
|
||||
|
@ -268,7 +269,10 @@ instance References Ruby.Sym where
|
|||
instance References Ruby.Str where
|
||||
entries _ = pure ()
|
||||
instance References Ruby.Lvasgn where
|
||||
entries _ = pure ()
|
||||
entries (Ruby.Lvasgn _ b) = entries b
|
||||
-- We don't consider "local variables". We could do though and say
|
||||
-- e.g. the local variable is a `Node` with the same "context" as the
|
||||
-- caller.
|
||||
instance References Ruby.Lvar where
|
||||
entries _ = pure ()
|
||||
instance References Ruby.Ivar where
|
||||
|
@ -283,6 +287,8 @@ instance References Ruby.Array where
|
|||
entries Ruby.Array{statements} = traverse_ entries statements
|
||||
instance References Ruby.Anything where
|
||||
entries = const $ pure ()
|
||||
instance References Ruby.Int where
|
||||
entries = const $ pure ()
|
||||
|
||||
instance References Ruby.Const where
|
||||
entries con = application $ NodeModule $ constToNamespace con
|
||||
|
@ -344,7 +350,10 @@ statementToNamespace = go mempty
|
|||
Ruby.StmtSend{} -> acc
|
||||
Ruby.StmtIvar{} -> acc
|
||||
Ruby.StmtLvar{} -> acc
|
||||
_ -> error "Can only build namespaces from sequences of `const` statements"
|
||||
Ruby.StmtArray{} -> acc
|
||||
-- TODO: Catch-all. Is this what we want to do? See e.g. the
|
||||
-- note about instance methods in the backlog.
|
||||
_ -> acc
|
||||
|
||||
constToNamespace :: Ruby.Const -> Namespace
|
||||
constToNamespace Ruby.Const{context, atom} = statementToNamespace context <> [k]
|
||||
|
|
|
@ -17,7 +17,7 @@ main :: IO ()
|
|||
main = withCurrentDirectory "test" $ defaultMain $ testGroup "Unit tests" tests
|
||||
|
||||
tests :: [TestTree]
|
||||
tests = go <$> ["mod", "simple", "nested", "closest"]
|
||||
tests = go <$> ["mod", "simple", "nested", "closest", "assignment"]
|
||||
where
|
||||
go :: String -> TestTree
|
||||
go s = testCase s $ do
|
||||
|
|
5
test/tests/assignment.json
Normal file
5
test/tests/assignment.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"": [
|
||||
"A"
|
||||
]
|
||||
}
|
3
test/tests/assignment.rb
Normal file
3
test/tests/assignment.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
A
|
||||
|
||||
b = A
|
Loading…
Reference in a new issue