Copyright© 2019 Elias Castegren and Kiko Fernandez-Reyes
LicenseMIT
Stabilityexperimental
Portabilityportable
Safe HaskellSafe

Reader.AST

Contents

Description

This module includes functionality for creating an Abstract Syntax Tree (AST), as well as helper functions for checking different aspects of the AST.

Synopsis

AST declarations

Declaration for the Abstract Syntax Tree of the language. This section contains the type, class, methods, fields and expressions represented as an AST. The AST is produced by a parser. For more information on building parsers, we recommend to read megaparsec.

type Name = String Source #

isConstructorName :: [Char] -> Bool Source #

Check if a name is a constructor name

data Type Source #

Representation of types

Constructors

ClassType Name 
IntType 
BoolType 
Arrow 

Fields

UnitType 
Instances
Eq Type Source # 
Instance details

Defined in Reader.AST

Methods

(==) :: Type -> Type -> Bool

(/=) :: Type -> Type -> Bool

Show Type Source # 
Instance details

Defined in Reader.AST

Methods

showsPrec :: Int -> Type -> ShowS

show :: Type -> String

showList :: [Type] -> ShowS

Typecheckable Type Source # 
Instance details

Defined in Reader.Typechecker

newtype Program Source #

The representation of a program in the form of an AST node.

Constructors

Program [ClassDef]

Programs are simply a list of class definitions (ClassDef)

Instances
Show Program Source # 
Instance details

Defined in Reader.AST

Methods

showsPrec :: Int -> Program -> ShowS

show :: Program -> String

showList :: [Program] -> ShowS

Typecheckable Program Source # 
Instance details

Defined in Reader.Typechecker

data ClassDef Source #

A representation of a class in the form of an AST node. As an example:

class Foo:
  val x: Int
  var y: Bool
  def main(): Int
    42

the code above, after parsing, would generate the following AST:

ClassDef {cname = "Foo"
         ,fields = [FieldDef {fname = "x"
                             ,ftype = IntType
                             ,fmod = Val}]
         ,methods = [MethodDef {mname = "main"
                               ,mparams = []
                               ,mtype = IntType
                               ,mbody = [IntLit {etype = Nothing, ival = 42}]
                               }]}

Constructors

ClassDef 

Fields

Instances
Show ClassDef Source # 
Instance details

Defined in Reader.AST

Methods

showsPrec :: Int -> ClassDef -> ShowS

show :: ClassDef -> String

showList :: [ClassDef] -> ShowS

Typecheckable ClassDef Source # 
Instance details

Defined in Reader.Typechecker

data Mod Source #

Field qualifiers in a class. It is thought for a made up syntax such as:

class Foo:
  val x: Int
  var y: Bool

This indicates that the variable x is immutable, and y can be mutated.

Constructors

Var

Indicates that the field can be mutated

Val

Indicates that the field is immutable

Instances
Eq Mod Source # 
Instance details

Defined in Reader.AST

Methods

(==) :: Mod -> Mod -> Bool

(/=) :: Mod -> Mod -> Bool

Show Mod Source # 
Instance details

Defined in Reader.AST

Methods

showsPrec :: Int -> Mod -> ShowS

show :: Mod -> String

showList :: [Mod] -> ShowS

data FieldDef Source #

Representation of a field declaration in the form of an AST node. As an example, the following code:

class Foo:
  val x: Int

could be parsed to the following field representation:

FieldDef {fname = "x"
         ,ftype = IntType
         ,fmod = Val}

Constructors

FieldDef 

Fields

Instances
Show FieldDef Source # 
Instance details

Defined in Reader.AST

Methods

showsPrec :: Int -> FieldDef -> ShowS

show :: FieldDef -> String

showList :: [FieldDef] -> ShowS

Typecheckable FieldDef Source # 
Instance details

Defined in Reader.Typechecker

isValField :: FieldDef -> Bool Source #

Helper function to check whether a FieldDef is immutable.

isVarField :: FieldDef -> Bool Source #

Helper function to check whether a FieldDef is mutable.

data Param Source #

Representation of parameters in the form of an AST.

Constructors

Param 

Fields

Instances
Show Param Source # 
Instance details

Defined in Reader.AST

Methods

showsPrec :: Int -> Param -> ShowS

show :: Param -> String

showList :: [Param] -> ShowS

Typecheckable Param Source # 
Instance details

Defined in Reader.Typechecker

data MethodDef Source #

Representation of a method declaration in the form of an AST. For example:

class Foo:
  def main(): Int
    42

the code above, after parsing, would generate the following AST:

ClassDef {cname = "Foo"
         ,fields = []
         ,methods = [MethodDef {mname = "main"
                               ,mparams = []
                               ,mtype = IntType
                               ,mbody = [IntLit {etype = Nothing, ival = 42}]
                               }]}

Constructors

MethodDef 

Fields

Instances
Show MethodDef Source # 
Instance details

Defined in Reader.AST

Methods

showsPrec :: Int -> MethodDef -> ShowS

show :: MethodDef -> String

showList :: [MethodDef] -> ShowS

Typecheckable MethodDef Source # 
Instance details

Defined in Reader.Typechecker

commaSep :: Show t => [t] -> String Source #

Takes a list of things that can be shown, and creates a comma separated string.

data Op Source #

Representation of integer operations

Constructors

Add 
Sub 
Mul 
Div 
Instances
Eq Op Source # 
Instance details

Defined in Reader.AST

Methods

(==) :: Op -> Op -> Bool

(/=) :: Op -> Op -> Bool

Show Op Source # 
Instance details

Defined in Reader.AST

Methods

showsPrec :: Int -> Op -> ShowS

show :: Op -> String

showList :: [Op] -> ShowS

data Expr Source #

Representation of expressions in the form of an AST node. The language is expression-based, so there are no statements. As an example, the following identity function:

let id = \x: Int -> x
in id 42

generates this Expr:

Let {etype = Nothing
    ,name = "id"
    ,val = Lambda {etype = Nothing
                  ,params = [Param "x" IntType]
                  ,body =   FunctionCall {etype = Nothing
                                         ,target = VarAccess Nothing "id"
                                         ,args = [IntLit Nothing 42]}
                  }
    ,body  :: Expr p1
    }

Constructors

BoolLit

Representation of a boolean literal

Fields

IntLit

Representation of an integer literal

Fields

Null

Representation of a null expression

Fields

Lambda

Representation of a null expression

Fields

VarAccess

Representation of a variable access

Fields

FieldAccess 

Fields

  • etype :: Maybe Type

    Type of the expression

  • target :: Expr

    The target in a field access, e.g., x.foo, then x is the target.

  • name :: Name

    Variable name

Assignment 

Fields

MethodCall 

Fields

  • etype :: Maybe Type

    Type of the expression

  • target :: Expr

    The target in a field access, e.g., x.foo, then x is the target.

  • name :: Name

    Variable name

  • args :: [Expr]

    The arguments of the method call

FunctionCall 

Fields

  • etype :: Maybe Type

    Type of the expression

  • target :: Expr

    The target in a field access, e.g., x.foo, then x is the target.

  • args :: [Expr]

    The arguments of the method call

If 

Fields

  • etype :: Maybe Type

    Type of the expression

  • cond :: Expr

    The condition in the if-else expression

  • thn :: Expr

    The body of the then branch

  • els :: Expr

    The body of the else branch

Let 

Fields

  • etype :: Maybe Type

    Type of the expression

  • name :: Name

    Variable name

  • val :: Expr

    Expression that will bound variable name with value val

  • body :: Expr

    The body of the lambda abstraction

BinOp 

Fields

  • etype :: Maybe Type

    Type of the expression

  • op :: Op

    Binary operation

  • lhs :: Expr

    Left-hand side expression

  • rhs :: Expr

    Left-hand side expression

New

It is useful to decouple the type of the expression from the type of the instantiated class. This distinction becomes important whenever we have subtyping, e.g., an interface Animal where `Animal x = new Dog`

Fields

  • etype :: Maybe Type

    Type of the expression

  • ty :: Type

    The class that one instantiates, e.g., `new C`

  • args :: [Expr]

    The arguments of the method call

Cast 

Fields

  • etype :: Maybe Type

    Type of the expression

  • body :: Expr

    The body of the lambda abstraction

  • ty :: Type

    The class that one instantiates, e.g., `new C`

Instances
Show Expr Source # 
Instance details

Defined in Reader.AST

Methods

showsPrec :: Int -> Expr -> ShowS

show :: Expr -> String

showList :: [Expr] -> ShowS

Typecheckable Expr Source # 
Instance details

Defined in Reader.Typechecker

Helper functions

The helper functions of this section operate on AST nodes to check for different properties. As an example, to check whether an expression is a field, instead of having to pattern match in all places, i.e.,

exampleFunction :: Expr -> Bool
exampleFunction expr =
  -- does some stuff
  ...
  case expr of
    FieldAccess expr -> True
    _                -> False

we define the isFieldAccess helper function, which checks whether a given expression is a FieldAccess:

exampleFunction :: Expr -> Bool
exampleFunction expr =
  -- does some stuff
  ...
  isFieldAccess expr

thisName :: Name Source #

Constant for the name this, commonly used in object-oriented languages.

isArrowType :: Type -> Bool Source #

Checks whether a Type is a function (arrow) type

isFieldAccess :: Expr -> Bool Source #

Checks whether an expression is a FieldAccess.

isVarAccess :: Expr -> Bool Source #

Checks whether an expression is a VarAccess.

isThisAccess :: Expr -> Bool Source #

Checks whether an expression is a VarAccess of this.

isLVal :: Expr -> Bool Source #

Checks whether an expression is an lval.

isClassType :: Type -> Bool Source #

Helper function to check whether a Type is a class

getType :: Expr -> Type Source #

Helper function to extract the type from an expression.

setType :: Type -> Expr -> Expr Source #

Sets the type of an expression e to t.