diff --git a/infer/src/llvm/examples/ret_var.ll b/infer/src/llvm/examples/ret_var.ll new file mode 100644 index 000000000..aca24c0c8 --- /dev/null +++ b/infer/src/llvm/examples/ret_var.ll @@ -0,0 +1,4 @@ +; Definition of main function +define i32 @main() { + ret i32 %0 +} diff --git a/infer/src/llvm/lAst.ml b/infer/src/llvm/lAst.ml index a04e66614..dd133ba40 100644 --- a/infer/src/llvm/lAst.ml +++ b/infer/src/llvm/lAst.ml @@ -9,9 +9,13 @@ (** Representation of LLVM constructs *) +type variable_id = + | Name of string + | Number of int + type variable = - | Global of string - | Local of string + | Global of variable_id + | Local of variable_id type constant = | Cint of int @@ -42,4 +46,8 @@ type func_def = FuncDef of variable * typ option * (typ * string) list * instr l type prog = Prog of func_def list let string_of_variable : variable -> string = function - | Global str | Local str -> str + | Global var_id | Local var_id -> + begin match var_id with + | Name str -> str + | Number i -> string_of_int i + end diff --git a/infer/src/llvm/lLexer.mll b/infer/src/llvm/lLexer.mll index a82c63211..8554c9ca8 100644 --- a/infer/src/llvm/lLexer.mll +++ b/infer/src/llvm/lLexer.mll @@ -20,6 +20,7 @@ let comment = ';' [^ '\n']* let nonzero_digit = ['1'-'9'] let digit = ['0'-'9'] let pos_int = nonzero_digit digit* +let nonneg_int = '0' | pos_int let intlit = '-'? digit+ let lower = ['a'-'z'] @@ -150,9 +151,11 @@ rule token = parse (*| "va_arg" { VA_ARG }*) (*| "landingpad" { LANDINGPAD }*) - (* identifiers *) - | '@' (id as str) { GLOBAL str } - | '%' (id as str) { LOCAL str } + (* IDENTIFIERS *) + | '@' (id as str) { NAMED_GLOBAL str } + | '%' (id as str) { NAMED_LOCAL str } + | '@' (nonneg_int as i) { NUMBERED_GLOBAL (int_of_string i) } + | '%' (nonneg_int as i) { NUMBERED_LOCAL (int_of_string i) } | id as str { IDENT str } | eof { EOF } diff --git a/infer/src/llvm/lParser.mly b/infer/src/llvm/lParser.mly index 0c80d909e..e55afd151 100644 --- a/infer/src/llvm/lParser.mly +++ b/infer/src/llvm/lParser.mly @@ -125,8 +125,10 @@ (*%token VA_ARG*) (*%token LANDINGPAD*) -%token GLOBAL -%token LOCAL +%token NAMED_GLOBAL +%token NAMED_LOCAL +%token NUMBERED_GLOBAL +%token NUMBERED_LOCAL %token IDENT %token EOF @@ -140,32 +142,32 @@ %% prog: - | defs=list(func_def) EOF { Prog defs } + | defs = list(func_def) EOF { Prog defs } func_def: - | DEFINE ret_tp=ret_typ name=variable LPAREN params=separated_list(COMMA, pair(typ, IDENT)) RPAREN instrs=block { + | DEFINE ret_tp = ret_typ name = variable 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 } + | tp = typ { Some tp } typ: - | tp=element_typ { tp } + | tp = element_typ { tp } (*| X86_MMX { () }*) - | tp=vector_typ { tp } - | LSQBRACK sz=SIZE X tp=element_typ RSQBRACK { Tarray (sz, tp) } (* array type *) + | tp = vector_typ { tp } + | LSQBRACK sz = SIZE X tp = element_typ RSQBRACK { Tarray (sz, tp) } (* array type *) | LABEL { Tlabel } | METADATA { Tmetadata } (* TODO structs *) vector_typ: - | LANGLE sz=SIZE X tp=element_typ RANGLE { Tvector (sz, tp) } + | LANGLE sz = SIZE X tp = element_typ RANGLE { Tvector (sz, tp) } element_typ: - | width=INT { Tint width } + | width = INT { Tint width } | floating_typ { Tfloat } - | tp=ptr_typ { Tptr tp } + | tp = ptr_typ { Tptr tp } floating_typ: | HALF { () } @@ -176,23 +178,23 @@ floating_typ: | PPC_FP128 { () } ptr_typ: - | tp=typ STAR { tp } + | tp = typ STAR { tp } block: - | LBRACE instrs=list(instr) RBRACE { instrs } + | LBRACE instrs = list(instr) RBRACE { instrs } instr: - | term=terminator { term } + | term = terminator { term } | variable EQUALS binop { Ret None } (* TODO *) - | var=variable EQUALS LOAD tp=ptr_typ ptr=variable { Load (var, tp, ptr) } - | STORE val_tp=typ value=operand COMMA ptr_tp=ptr_typ var=variable { Store (value, val_tp, var) } + | var = variable EQUALS LOAD tp = ptr_typ ptr = variable { Load (var, tp, ptr) } + | STORE val_tp = typ value = operand COMMA ptr_tp = ptr_typ var = variable { Store (value, val_tp, var) } (* don't yet know why val_tp and ptr_tp would be different *) terminator: - | RET tp=typ op=operand { Ret (Some (tp, op)) } + | RET tp = typ op = operand { Ret (Some (tp, op)) } | RET VOID { Ret None } - | BR LABEL lbl=variable { UncondBranch lbl } - | BR BIT op=operand COMMA LABEL lbl1=variable COMMA LABEL lbl2=variable { CondBranch (op, lbl1, lbl2) } + | BR LABEL lbl = variable { UncondBranch lbl } + | BR BIT op = operand COMMA LABEL lbl1 = variable COMMA LABEL lbl2 = variable { CondBranch (op, lbl1, lbl2) } (* | switch | indirectbr @@ -237,13 +239,15 @@ binop_args: (* below is fuzzy *) operand: - | var=variable { Var var } - | const=constant { Const const } + | var = variable { Var var } + | const = constant { Const const } variable: - | id=GLOBAL { Global id } - | id=LOCAL { Local id } + | name = NAMED_GLOBAL { Global (Name name) } + | name = NAMED_LOCAL { Local (Name name) } + | num = NUMBERED_GLOBAL { Global (Number num) } + | num = NUMBERED_LOCAL { Local (Number num) } constant: - | i=CONSTINT { Cint i } + | i = CONSTINT { Cint i } | NULL { Cnull }