Module Pascal_ir


module Pascal_ir: sig  end
Abstract syntax tree with a Pascal looking-like structure.
Author(s): Samuel Mimram

exception Parse_error of (string * (int * int))
A parsing error occured. The arguments are the column and line numbers.

type pascal_type =
| Integer (*an integer*)
| Boolean (*a boolean*)
| Record of (string * pascal_type) list (*a record*)
| Array of (pascal_type * expression * expression) (*an array*)
| User_type of string (*a user type*)
| Unit (*unit (not used for now)*)
| Pointer of pascal_type (*a pointer*)
| Type_type (*a type*)
| Unknown_type (*no type yet*)
Types of values.

type nature =
| Varb (*a variable*)
| Cst (*a constant*)
| Funct (*a function*)
| Unknown_nature (*no nature yet*)
Nature.

type variable = {
   var_name : string; (*name of the variable*)
   mutable var_type : pascal_type; (*type of the variable*)
   mutable var_def : definition option; (*definition*)
   mutable var_nature : nature; (*nature*)
   var_pos : int * int; (*position in the source code*)
}
A reference to an identifier. var_by_name is only meaningful for procedures' and functions' arguments (yet) and should be set to false else.

type expression = {
   expr_val : expr; (*the actual expression*)
   mutable expr_type : pascal_type; (*type of the expression*)
   expr_pos : int * int; (*position in the source code (line, column)*)
}
A typed expression.

type expr =
| Lt of (expression * expression) (*less than*)
| Le of (expression * expression) (*less or equal*)
| Eq of (expression * expression) (*equal*)
| Neq of (expression * expression) (*not equal*)
| Uminus of expression (*unary minus*)
| Plus of (expression * expression) (*plus*)
| Minus of (expression * expression) (*minus*)
| Or of (expression * expression) (*logical or*)
| Mult of (expression * expression) (*times*)
| Div of (expression * expression) (*divided by*)
| Mod of (expression * expression) (*modulo*)
| And of (expression * expression) (*logical and*)
| Not of expression (*logical not*)
| Int of int (*an integer*)
| Bool of bool (*a boolean*)
| Var of (variable * expression list) (*a variable or a function call*)
| Arr of (expression * expression) (*an array*)
| Rec of (expression * string) (*a member of a structure*)
| Address_of of expression (*the address of a variable*)
| Bang of expression (*the value pointed by a variable*)
| New of pascal_type Pervasives.ref (*a new value of this type (malloc)*)
An expression.

type stt =
| Assign of (expression * expression) (*assignation of a value to a variable*)
| Proc of (variable * expression list) (*procedure call*)
| If of (expression * statement * statement) (*if ... then ... else ... (if there is no else then the second statement should be Noop)*)
| While of (expression * statement) (*while*)
| Compound of statement list (*begin ... end*)
| Return of expression (*return*)
| Delete of expression (*delete a value (free)*)
| Noop (*take some rest*)
A statement.

type statement = {
   stt_value : stt; (*the actual statement*)
   stt_pos : int * int; (*position in source code*)
   mutable stt_asm : (Asm_ir.variable_def list * Asm_ir.meta_instr) option; (*for 'if' and 'while'*)
}
A decorated statement.
type environment = (string * definition) list 
An environment (a list of names and their value).

type block = {
   mutable block_env : environment; (*the preliminary variables declarations*)
   mutable block_stts : statement list; (*the instructions*)
}
A block (i.e. a list of statements in an environment).

type func = {
   func_args : definition list; (*arguments*)
   func_value : block; (*code*)
   func_asm_def : Asm_ir.procedure; (*definition in the asm ir*)
   mutable func_used : bool; (*for dead-code elimination purposes*)
   mutable func_external : bool; (*is the procedure external (defined in bifton's standard library)*)
}
A procedure or a function.

type value =
| Constant of expression (*a constant expression*)
| Variable (*a varaiable containing a value (not passed by reference)*)
| Function of func (*a function*)
| Type of pascal_type (*a type*)
What an identifier can be.

type asm_value =
| Asm_var of Asm_ir.variable_def (*a variable*)
| Asm_proc of Asm_ir.procedure (*a procedure*)
| Asm_none (*no useful assembly is associated to this value*)
Definition in the assembly side.

type definition = {
   def_name : string; (*name*)
   mutable def_type : pascal_type; (*type*)
   def_nature : nature; (*nature*)
   mutable def_value : value; (*value*)
   def_pos : int * int; (*position in the source code*)
   mutable def_coord : int list; (*lexical position*)
   mutable def_asm : asm_value; (*translation into asm*)
   def_pass_by_ref : bool; (*should the value be passed by reference (for arguments of functions)?*)
}
An identifier definition.


Operations on environments.


exception Already_defined
A variable is being redefined.
val create_environment : unit -> environment
Create a new empty environment.
val fold_env : (string -> definition -> 'a -> 'a) ->
'a -> environment -> 'a
Fold a function throughout an environment.
val iter_env : (string -> definition -> unit) -> environment -> unit
Iter a function on all elements of an environment.
val env_of_def_list : definition list -> (string * definition) list
Get the environment corresponding to a list of variable definitions.
val add_def : environment ->
string -> definition -> (string * definition) list
Add a definition to an environment.
Raises Already_defined if a previous definition was already made with the same name.
val get_def : environment -> string -> definition
Get a the value associated to a name in an environment. Remark: don't forget that procedures and functions are binders and should therefore be added to the current environment.
Raises Not_found if no definition was made for that name.
val concat_env : bool ->
environment -> environment -> environment
Concatenate two environments. The first argument determines whereas the function should check for duplicate definitions or not.


Operations on programs.


val new_function : string ->
definition list ->
pascal_type ->
block -> int * int -> bool -> definition
Create a new function.
val string_of_type : pascal_type -> string
Get a human readable representation of a type.
type program = string * block 
A program.
val is_some : 'a option -> bool
Is a value equal to Some _?
val get_some : 'a option -> 'a
Get the value v in a value equal to Some v.
val eval_expr_int : expression -> int
Compute the value of a constant integer expression.
val eval_expr_bool : expression -> bool
Compute the value of a constant boolean expression.
val eval_expr : expression -> Asm_ir.value
Compute the value of a constant expression.
exception Asm_error of string
An error occured during the pascal-to-asm conversion.
val sizeof : pascal_type -> int
Get the size needed by a type (in bytes).
val asm_type : pascal_type -> Asm_ir.var_type
Get the asm type corresponding to a pascal type.
val check_block : block ->
environment list -> pascal_type -> unit
Do several checks on a block:
Raises Parse_error if an error was detected.

rettype : the type of the returned value
val opt_useless : 'a * block -> unit
Mark def_used of used procedures.
val define_glibb : 'a * block -> unit
Add the definitions of the our external glibb procedures.
val check : 'a * block -> unit
Check that the program is syntaxically and lexically correct.
val string_of_expression : expression -> string
Get a human readable representation of an expression.
val pretty_print : string * block -> string
Get a nice human-readable representation of a pascal ast.


Conversions to Asm_ir.


val is_constant : expression -> bool
Is an expression a constant?
val asm_of_proc : string ->
func ->
pascal_type -> int list -> Asm_ir.procedure list * Asm_ir.procedure
Get an asm-like AST corresponding to a pascal-like AST.
Returns a list of procedures incidently defined and the Asm_ir.procedure corresponding to the procedure.
val asm_of_prog : 'a * block -> Asm_ir.program
Get the asm IR of a program.