2019-10-11 14:28:19 +00:00
|
|
|
* Introduction
|
|
|
|
Write a static analyzer for ruby.
|
|
|
|
|
|
|
|
Used an existing parser for ruby called `ruby-parse`.
|
|
|
|
|
|
|
|
`ruby-parse` can generate an AST in JSON format.
|
|
|
|
|
|
|
|
This made the task of writing a ruby parser simpler: Haskell comes
|
|
|
|
with a great JSON parser. So we just have to specify how to convert
|
|
|
|
from the AST defined by `ruby-parse` to our own AST.
|
|
|
|
|
|
|
|
* Implementation
|
|
|
|
** ADTs
|
|
|
|
*** Purpose
|
|
|
|
Defining an Abstract Syntax Tree (AST) for Ruby using Algebraic Data
|
|
|
|
Types (ADTs).
|
|
|
|
|
|
|
|
*** Example
|
|
|
|
-- Value represents any JSON data (object, string, number, null, array)
|
|
|
|
Args = Value
|
|
|
|
Name = Value
|
|
|
|
Block = [Definition]
|
|
|
|
Definition = Module | Function | Send
|
|
|
|
Namespace = [Name]
|
|
|
|
Send = {args : Args, namespace : Namespace, name :: Name}
|
|
|
|
Module = {name : Name, block : Block}
|
|
|
|
Function = {name : Name, args : Args, block :: Block}
|
|
|
|
|
|
|
|
*** Live coding
|
|
|
|
|
|
|
|
Define `Function`
|
|
|
|
** Higher-order types
|
|
|
|
Missing a good example here.
|
|
|
|
|
|
|
|
** Type classes
|
|
|
|
*** Purpose
|
|
|
|
Be able to concert unstructured JSON data into our ADT.
|
|
|
|
|
|
|
|
*** Example
|
|
|
|
Consider the class
|
|
|
|
|
|
|
|
class FromJSON a where
|
|
|
|
parseJSON :: Value -> Parser a
|
|
|
|
|
|
|
|
It's saying that `a` is convertible from json if there is a function
|
|
|
|
`parseJSON` that takes a (json) `Value` and returns a `Parser a`.
|
|
|
|
`Parser a` can be thought of as a procedure for generating a value of
|
|
|
|
type `a`.
|
|
|
|
|
|
|
|
So for instance. The monomorphic type `Parser Function` is a
|
|
|
|
procedure that generates a value of type `Function`:
|
|
|
|
*** Live coding
|
|
|
|
Define an instance for `FromJSON` for `Function`.
|
2019-10-11 14:55:48 +00:00
|
|
|
|
|
|
|
Define an instance for `FromJSON` for `Definition`.
|