parent
6bde9bda88
commit
fc0ca6b6db
@ -0,0 +1,19 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2015 - Facebook.
|
||||||
|
* All rights reserved.
|
||||||
|
*)
|
||||||
|
type prog = Prog of func_def list
|
||||||
|
and func_def = FuncDef of string * typ option * (typ * string) list * instr list
|
||||||
|
and typ =
|
||||||
|
| Tint of int
|
||||||
|
| Tfloat (* just one type for now *)
|
||||||
|
| Tptr of typ
|
||||||
|
| Tvector of int * typ
|
||||||
|
| Tarray of int * typ
|
||||||
|
and instr =
|
||||||
|
| Ret of (typ * value) option
|
||||||
|
and value =
|
||||||
|
| True
|
||||||
|
| False
|
||||||
|
| Intlit of int
|
||||||
|
| Null
|
@ -0,0 +1,151 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2015 - Facebook.
|
||||||
|
* All rights reserved.
|
||||||
|
*)
|
||||||
|
{
|
||||||
|
open Lexing
|
||||||
|
open Parser
|
||||||
|
|
||||||
|
exception LexingError of string
|
||||||
|
}
|
||||||
|
|
||||||
|
let space = [' ' '\t']
|
||||||
|
let newline = '\n'
|
||||||
|
let comment = ';' [^ '\n']*
|
||||||
|
|
||||||
|
let nonzero_digit = ['1'-'9']
|
||||||
|
let digit = ['0'-'9']
|
||||||
|
let pos_int = nonzero_digit digit*
|
||||||
|
let intlit = '-'? digit+
|
||||||
|
|
||||||
|
let lower = ['a'-'z']
|
||||||
|
let upper = ['A'-'Z']
|
||||||
|
let id_special_char = ['-' '$' '.' '_']
|
||||||
|
let id_char = lower | upper | id_special_char
|
||||||
|
let id = ['%' '@'] id_char (id_char | digit)*
|
||||||
|
|
||||||
|
rule token = parse
|
||||||
|
| space | comment { token lexbuf }
|
||||||
|
| newline { token lexbuf }
|
||||||
|
|
||||||
|
(* keywords *)
|
||||||
|
| "define" { DEFINE }
|
||||||
|
|
||||||
|
(* delimiters *)
|
||||||
|
| ',' { COMMA }
|
||||||
|
| '(' { LPAREN }
|
||||||
|
| ')' { RPAREN }
|
||||||
|
| '{' { LBRACE }
|
||||||
|
| '}' { RBRACE }
|
||||||
|
| '<' { LANGLE }
|
||||||
|
| '>' { RANGLE }
|
||||||
|
| '[' { LSQBRACK }
|
||||||
|
| ']' { RSQBRACK }
|
||||||
|
(* symbols *)
|
||||||
|
| '=' { EQUALS }
|
||||||
|
| '*' { STAR }
|
||||||
|
| ['x' 'X'] { X }
|
||||||
|
|
||||||
|
(* TYPES *)
|
||||||
|
| "void" { VOID }
|
||||||
|
| 'i' (pos_int as width) { INT (int_of_string width) }
|
||||||
|
| "half" { HALF }
|
||||||
|
| "float" { FLOAT }
|
||||||
|
| "double" { DOUBLE }
|
||||||
|
| "fp128" { FP128 }
|
||||||
|
| "x86_fp80" { X86_FP80 }
|
||||||
|
| "ppc_fp128" { PPC_FP128 }
|
||||||
|
| "x86_mmx" { X86_MMX }
|
||||||
|
| "label" { LABEL }
|
||||||
|
| "metadata" { METADATA }
|
||||||
|
|
||||||
|
| pos_int as size { SIZE (int_of_string size) }
|
||||||
|
(* CONSTANTS *)
|
||||||
|
| "true" { TRUE }
|
||||||
|
| "false" { FALSE }
|
||||||
|
| intlit as i { INTLIT (int_of_string i) }
|
||||||
|
(* floating point constants *)
|
||||||
|
| "null" { NULL }
|
||||||
|
|
||||||
|
(* INSTRUCTIONS *)
|
||||||
|
(* terminator instructions *)
|
||||||
|
| "ret" { RET }
|
||||||
|
| "br" { BR }
|
||||||
|
| "switch" { SWITCH }
|
||||||
|
| "indirectbr" { INDIRECTBR }
|
||||||
|
| "invoke" { INVOKE }
|
||||||
|
| "resume" { RESUME }
|
||||||
|
| "unreachable" { UNREACHABLE }
|
||||||
|
(* binary operations *)
|
||||||
|
| "add" { ADD }
|
||||||
|
| "fadd" { FADD }
|
||||||
|
| "sub" { SUB }
|
||||||
|
| "fsub" { FSUB }
|
||||||
|
| "mul" { MUL }
|
||||||
|
| "fmul" { FMUL }
|
||||||
|
| "udiv" { UDIV }
|
||||||
|
| "sdiv" { SDIV }
|
||||||
|
| "fdiv" { FDIV }
|
||||||
|
| "urem" { UREM }
|
||||||
|
| "srem" { SREM }
|
||||||
|
| "frem" { FREM }
|
||||||
|
(* arithmetic options *)
|
||||||
|
| "nuw" { NUW }
|
||||||
|
| "nsw" { NSW }
|
||||||
|
| "exact" { EXACT }
|
||||||
|
(* floating point options *)
|
||||||
|
| "nnan" { NNAN }
|
||||||
|
| "ninf" { NINF }
|
||||||
|
| "nsz" { NSZ }
|
||||||
|
| "arcp" { ARCP }
|
||||||
|
| "fast" { FAST }
|
||||||
|
(* bitwise binary operations *)
|
||||||
|
| "shl" { SHL }
|
||||||
|
| "lshr" { LSHR }
|
||||||
|
| "ashr" { ASHR }
|
||||||
|
| "and" { AND }
|
||||||
|
| "or" { OR }
|
||||||
|
| "xor" { XOR }
|
||||||
|
(* vector operations *)
|
||||||
|
| "extractelement" { EXTRACTELEMENT }
|
||||||
|
| "insertelement" { INSERTELEMENT }
|
||||||
|
| "shufflevector" { SHUFFLEVECTOR }
|
||||||
|
(* aggregate operations *)
|
||||||
|
| "extractvalue" { EXTRACTVALUE }
|
||||||
|
| "insertvalue" { INSERTVALUE }
|
||||||
|
(* memory access and addressing operations *)
|
||||||
|
| "alloca" { ALLOCA }
|
||||||
|
| "load" { LOAD }
|
||||||
|
| "store" { STORE }
|
||||||
|
| "fence" { FENCE }
|
||||||
|
| "cmpxchg" { CMPXCHG }
|
||||||
|
| "atomicrmw" { ATOMICRMW }
|
||||||
|
| "getelementptr" { GETELEMENTPTR }
|
||||||
|
(* conversion operations *)
|
||||||
|
| "trunc" { TRUNC } (* e.g. trunc ... to ... *)
|
||||||
|
| "zext" { ZEXT }
|
||||||
|
| "sext" { SEXT }
|
||||||
|
| "fptrunc" { FPTRUNC }
|
||||||
|
| "fpext" { FPEXT }
|
||||||
|
| "fptoui" { FPTOUI }
|
||||||
|
| "fptosi" { FPTOSI }
|
||||||
|
| "uitofp" { UITOFP }
|
||||||
|
| "sitofp" { SITOFP }
|
||||||
|
| "ptrtoint" { PTRTOINT }
|
||||||
|
| "inttoptr" { INTTOPTR }
|
||||||
|
| "bitcast" { BITCAST }
|
||||||
|
| "addrspacecast" { ADDRSPACECAST }
|
||||||
|
| "to" { TO } (* all conversion operations include this keyword *)
|
||||||
|
(* other operations *)
|
||||||
|
| "icmp" { ICMP }
|
||||||
|
| "fcmp" { FCMP }
|
||||||
|
| "phi" { PHI }
|
||||||
|
| "select" { SELECT }
|
||||||
|
| "call" { CALL }
|
||||||
|
| "va_arg" { VA_ARG }
|
||||||
|
| "landingpad" { LANDINGPAD }
|
||||||
|
|
||||||
|
(* identifiers - make this complete *)
|
||||||
|
| id as str { IDENT str }
|
||||||
|
|
||||||
|
| eof { EOF }
|
@ -0,0 +1,20 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2015 - Facebook.
|
||||||
|
* All rights reserved.
|
||||||
|
*)
|
||||||
|
open Lexing
|
||||||
|
open Printf
|
||||||
|
|
||||||
|
exception UsageError of string
|
||||||
|
|
||||||
|
let () = try
|
||||||
|
if Array.length Sys.argv < 2 then
|
||||||
|
raise (UsageError ("Missing source file as first command line argument."))
|
||||||
|
else
|
||||||
|
let filename = Sys.argv.(1) in
|
||||||
|
let lexbuf = Lexing.from_channel (open_in filename) in
|
||||||
|
let prog = Parser.prog Lexer.token lexbuf in
|
||||||
|
let pretty = Pretty.pretty_prog prog in
|
||||||
|
print_string pretty
|
||||||
|
with
|
||||||
|
| UsageError msg -> print_string ("Usage error: " ^ msg ^ "\n")
|
@ -0,0 +1,240 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2015 - Facebook.
|
||||||
|
* All rights reserved.
|
||||||
|
*)
|
||||||
|
%{
|
||||||
|
open Ast
|
||||||
|
%}
|
||||||
|
|
||||||
|
(* keywords *)
|
||||||
|
%token DEFINE
|
||||||
|
|
||||||
|
(* delimiters *)
|
||||||
|
%token COMMA
|
||||||
|
%token LPAREN
|
||||||
|
%token RPAREN
|
||||||
|
%token LBRACE
|
||||||
|
%token RBRACE
|
||||||
|
%token LANGLE
|
||||||
|
%token RANGLE
|
||||||
|
%token LSQBRACK
|
||||||
|
%token RSQBRACK
|
||||||
|
(* symbols *)
|
||||||
|
%token EQUALS
|
||||||
|
%token STAR
|
||||||
|
%token X
|
||||||
|
|
||||||
|
(* TYPES *)
|
||||||
|
%token VOID
|
||||||
|
%token <int> INT
|
||||||
|
%token HALF
|
||||||
|
%token FLOAT
|
||||||
|
%token DOUBLE
|
||||||
|
%token FP128
|
||||||
|
%token X86_FP80
|
||||||
|
%token PPC_FP128
|
||||||
|
%token X86_MMX
|
||||||
|
%token LABEL
|
||||||
|
%token METADATA
|
||||||
|
|
||||||
|
%token <int> SIZE
|
||||||
|
(* CONSTANTS *)
|
||||||
|
%token TRUE
|
||||||
|
%token FALSE
|
||||||
|
%token <int> INTLIT
|
||||||
|
%token NULL
|
||||||
|
|
||||||
|
(* INSTRUCTIONS *)
|
||||||
|
(* terminator instructions *)
|
||||||
|
%token RET
|
||||||
|
%token BR
|
||||||
|
%token SWITCH
|
||||||
|
%token INDIRECTBR
|
||||||
|
%token INVOKE
|
||||||
|
%token RESUME
|
||||||
|
%token UNREACHABLE
|
||||||
|
(* binary operations *)
|
||||||
|
%token ADD
|
||||||
|
%token FADD
|
||||||
|
%token SUB
|
||||||
|
%token FSUB
|
||||||
|
%token MUL
|
||||||
|
%token FMUL
|
||||||
|
%token UDIV
|
||||||
|
%token SDIV
|
||||||
|
%token FDIV
|
||||||
|
%token UREM
|
||||||
|
%token SREM
|
||||||
|
%token FREM
|
||||||
|
(* arithmetic options *)
|
||||||
|
%token NUW
|
||||||
|
%token NSW
|
||||||
|
%token EXACT
|
||||||
|
(* floating point options *)
|
||||||
|
%token NNAN
|
||||||
|
%token NINF
|
||||||
|
%token NSZ
|
||||||
|
%token ARCP
|
||||||
|
%token FAST
|
||||||
|
(* bitwise binary operations *)
|
||||||
|
%token SHL
|
||||||
|
%token LSHR
|
||||||
|
%token ASHR
|
||||||
|
%token AND
|
||||||
|
%token OR
|
||||||
|
%token XOR
|
||||||
|
(* vector operations *)
|
||||||
|
%token EXTRACTELEMENT
|
||||||
|
%token INSERTELEMENT
|
||||||
|
%token SHUFFLEVECTOR
|
||||||
|
(* aggregate operations *)
|
||||||
|
%token EXTRACTVALUE
|
||||||
|
%token INSERTVALUE
|
||||||
|
(* memory access and addressing operations *)
|
||||||
|
%token ALLOCA
|
||||||
|
%token LOAD
|
||||||
|
%token STORE
|
||||||
|
%token FENCE
|
||||||
|
%token CMPXCHG
|
||||||
|
%token ATOMICRMW
|
||||||
|
%token GETELEMENTPTR
|
||||||
|
(* conversion operations *)
|
||||||
|
%token TRUNC
|
||||||
|
%token ZEXT
|
||||||
|
%token SEXT
|
||||||
|
%token FPTRUNC
|
||||||
|
%token FPEXT
|
||||||
|
%token FPTOUI
|
||||||
|
%token FPTOSI
|
||||||
|
%token UITOFP
|
||||||
|
%token SITOFP
|
||||||
|
%token PTRTOINT
|
||||||
|
%token INTTOPTR
|
||||||
|
%token BITCAST
|
||||||
|
%token ADDRSPACECAST
|
||||||
|
%token TO
|
||||||
|
(* other operations *)
|
||||||
|
%token ICMP
|
||||||
|
%token FCMP
|
||||||
|
%token PHI
|
||||||
|
%token SELECT
|
||||||
|
%token CALL
|
||||||
|
%token VA_ARG
|
||||||
|
%token LANDINGPAD
|
||||||
|
|
||||||
|
%token <string> IDENT
|
||||||
|
|
||||||
|
%token EOF
|
||||||
|
|
||||||
|
%start prog
|
||||||
|
%type <Ast.prog> prog
|
||||||
|
%type <Ast.func_def> func_def
|
||||||
|
%type <Ast.typ option> ret_typ
|
||||||
|
%type <Ast.typ> typ
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
prog:
|
||||||
|
| defs=list(func_def) EOF { Prog defs }
|
||||||
|
|
||||||
|
func_def:
|
||||||
|
| DEFINE ret_tp=ret_typ name=IDENT LPAREN params=separated_list(COMMA, pair(typ, IDENT)) RPAREN instrs=block {
|
||||||
|
FuncDef (name, ret_tp, params, instrs) }
|
||||||
|
|
||||||
|
ret_typ:
|
||||||
|
| VOID { None }
|
||||||
|
| tp=typ { Some tp }
|
||||||
|
|
||||||
|
typ:
|
||||||
|
| tp=element_typ { tp }
|
||||||
|
(*| X86_MMX { () }*)
|
||||||
|
| tp=vector_typ { tp }
|
||||||
|
| LSQBRACK sz=SIZE X tp=element_typ RSQBRACK { Tarray (sz, tp) } (* array type *)
|
||||||
|
(*| LABEL { () }
|
||||||
|
| METADATA { () }*)
|
||||||
|
(* TODO structs *)
|
||||||
|
|
||||||
|
vector_typ:
|
||||||
|
| LANGLE sz=SIZE X tp=element_typ RANGLE { Tvector (sz, tp) }
|
||||||
|
|
||||||
|
element_typ:
|
||||||
|
| width=INT { Tint width }
|
||||||
|
| floating_typ { Tfloat }
|
||||||
|
| tp=ptr_typ { tp }
|
||||||
|
|
||||||
|
floating_typ:
|
||||||
|
| HALF { () }
|
||||||
|
| FLOAT { () }
|
||||||
|
| DOUBLE { () }
|
||||||
|
| FP128 { () }
|
||||||
|
| X86_FP80 { () }
|
||||||
|
| PPC_FP128 { () }
|
||||||
|
|
||||||
|
ptr_typ:
|
||||||
|
| tp=typ STAR { Tptr tp }
|
||||||
|
|
||||||
|
block:
|
||||||
|
| LBRACE instrs=list(instr) RBRACE { instrs }
|
||||||
|
|
||||||
|
instr:
|
||||||
|
| term=terminator { term }
|
||||||
|
| IDENT EQUALS binop { Ret None }
|
||||||
|
|
||||||
|
terminator:
|
||||||
|
| RET tp=typ v=value { Ret (Some (tp, v)) }
|
||||||
|
| RET VOID { Ret None }
|
||||||
|
(*
|
||||||
|
| switch
|
||||||
|
| indirectbr
|
||||||
|
| invoke
|
||||||
|
| resume
|
||||||
|
| unreachable
|
||||||
|
*)
|
||||||
|
|
||||||
|
binop:
|
||||||
|
| ADD arith_options binop_args { () }
|
||||||
|
| FADD fast_math_flags binop_args { () }
|
||||||
|
| SUB arith_options binop_args { () }
|
||||||
|
| FSUB fast_math_flags binop_args { () }
|
||||||
|
| MUL binop_args { () }
|
||||||
|
| FMUL fast_math_flags binop_args { () }
|
||||||
|
| UDIV option(EXACT) binop_args { () }
|
||||||
|
| SDIV option(EXACT) binop_args { () }
|
||||||
|
| FDIV fast_math_flags binop_args { () }
|
||||||
|
| UREM binop_args { () }
|
||||||
|
| SREM binop_args { () }
|
||||||
|
| FREM fast_math_flags binop_args { () }
|
||||||
|
(* bitwise *)
|
||||||
|
| SHL arith_options binop_args { () }
|
||||||
|
| LSHR option(EXACT) binop_args { () }
|
||||||
|
| ASHR option(EXACT) binop_args { () }
|
||||||
|
| AND binop_args { () }
|
||||||
|
| OR binop_args { () }
|
||||||
|
| XOR binop_args { () }
|
||||||
|
(* vector *)
|
||||||
|
| EXTRACTELEMENT vector_typ value COMMA typ IDENT { () }
|
||||||
|
| INSERTELEMENT vector_typ value COMMA typ element COMMA typ IDENT { () }
|
||||||
|
|
||||||
|
arith_options:
|
||||||
|
| option(NUW) option(NSW) { () }
|
||||||
|
|
||||||
|
fast_math_flags:
|
||||||
|
| option(NNAN) option(NINF) option(NSZ) option(ARCP) option(FAST) { () }
|
||||||
|
|
||||||
|
binop_args:
|
||||||
|
| typ operand COMMA operand { () }
|
||||||
|
|
||||||
|
(* below is fuzzy *)
|
||||||
|
|
||||||
|
operand:
|
||||||
|
(* variable *)
|
||||||
|
| v=value { v }
|
||||||
|
|
||||||
|
element:
|
||||||
|
| v=value { v }
|
||||||
|
|
||||||
|
value:
|
||||||
|
| TRUE { True }
|
||||||
|
| FALSE { False }
|
||||||
|
| i=INTLIT { Intlit i }
|
||||||
|
| NULL { Null }
|
@ -0,0 +1,39 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2015 - Facebook.
|
||||||
|
* All rights reserved.
|
||||||
|
*)
|
||||||
|
open Ast
|
||||||
|
|
||||||
|
let concatmap (sep : string) (f : 'a -> string) (l : 'a list) : string = String.concat sep (List.map f l)
|
||||||
|
|
||||||
|
let rec pretty_prog : prog -> string = function
|
||||||
|
Prog defs -> concatmap "" pretty_func_def defs
|
||||||
|
|
||||||
|
and pretty_func_def : func_def -> string = function
|
||||||
|
FuncDef (name, ret_tp, params, instrs) ->
|
||||||
|
"define " ^ pretty_ret_typ ret_tp ^ " " ^ name ^ "(" ^
|
||||||
|
concatmap ", " (fun (tp, id) -> pretty_typ tp ^ " " ^ id) params ^ ") {\n" ^
|
||||||
|
concatmap "" pretty_instr_ln instrs ^ "}\n"
|
||||||
|
|
||||||
|
and pretty_ret_typ : typ option -> string = function
|
||||||
|
| None -> "void"
|
||||||
|
| Some tp -> pretty_typ tp
|
||||||
|
|
||||||
|
and pretty_typ : typ -> string = function
|
||||||
|
| Tint width -> "i" ^ string_of_int width
|
||||||
|
| Tfloat (* just one type for now *) -> "float"
|
||||||
|
| Tptr tp -> pretty_typ tp ^ "*"
|
||||||
|
| Tvector (sz, tp) -> "<" ^ string_of_int sz ^ " x " ^ pretty_typ tp ^ ">"
|
||||||
|
| Tarray (sz, tp) -> "[" ^ string_of_int sz ^ " x " ^ pretty_typ tp ^ "]"
|
||||||
|
|
||||||
|
and pretty_instr_ln (i : instr) : string = pretty_instr i ^ "\n"
|
||||||
|
|
||||||
|
and pretty_instr : instr -> string = function
|
||||||
|
| Ret None -> "ret void"
|
||||||
|
| Ret (Some (tp, v)) -> "ret " ^ pretty_typ tp ^ " " ^ pretty_value v
|
||||||
|
|
||||||
|
and pretty_value : value -> string = function
|
||||||
|
| True -> "true"
|
||||||
|
| False -> "false"
|
||||||
|
| Intlit i -> string_of_int i
|
||||||
|
| Null -> "null"
|
Loading…
Reference in new issue