(* This is the definition of the abstract syntax for Located Pseudo-Pascal (LPP). This language is identical to Pseudo-Pascal, except abstract syntax trees carry source code locations. These locations are useful for printing accurate error messages when typechecking. *) (* All identifiers carry locations. *) type identifier = string Location.t (* Expressions carry locations at every node. *) type expression = raw_expression Location.t (* Expressions. *) and raw_expression = (* Constants. *) EConst of constant (* Global or local variable access. *) EGetVar of identifier (* Unary operator applications. *) EUnOp of unop * expression (* Binary operator applications. *) EBinOp of MIPSOps.binop * expression * expression (* Function call. *) EFunCall of Primitive.callee Location.t * expression list (* Array read. Parameters are an array and an integer index. *) EArrayGet of expression * expression (* Array allocation. Parameters are the desired element type and the desired number of elements. *) EArrayAlloc of typ * expression (* Constants. *) and constant = (* Boolean constants. *) ConstBool of bool (* Integer constants. *) ConstInt of int32 (* Unary integer arithmetic operators. *) and unop = UOpNeg (* Conditions are expressions that produce a Boolean result. Their syntax allows the use of the Boolean connectives [not], [and], and [or], which are not available as part of the syntax of expressions. This somewhat nonstandard design is intended to eliminate some redundancy in the compiler. Conditions are used in the [if] and [while] instructions. The [and] or [or] connectives are special in that their right-hand side is not evaluated if the value of the left-hand side determines the value of the whole. *) and condition = (* Boolean expression. *) CExpression of expression (* Boolean connectives. *) CNot of condition CAnd of condition * condition COr of condition * condition (* Instructions. *) and instruction = (* Procedure call. *) IProcCall of Primitive.callee Location.t * expression list (* Local or global variable update. *) ISetVar of identifier * expression (* Array write. Parameters are an array, an integer index, and a new element value. *) IArraySet of expression * expression * expression (* Sequence. *) ISeq of instruction list (* Conditional. *) IIf of condition * instruction * instruction (* Loop. *) IWhile of condition * instruction (* Types. *) and typ = TypInt TypBool TypArray of typ (* Function definitions. *) and procedure = { (* A list of typed formal arguments. *) formals: (identifier * typ) list; (* A typed result, present for functions and absent for procedures. By convention, functions return a result by writing into a local variable whose name is that of the function. *) result: typ option; (* A list of typed local variables. *) locals: (identifier * typ) list; (* The body of the function. *) body: instruction } (* Programs. *) and program = { (* A set of typed global variables. *) globals: (identifier * typ) list; (* A set of named function or procedure definitions. *) defs: (identifier * procedure) list; (* The program body. *) main: instruction }