I was writing a simple parser function that expects an item in a stream, and returns an int, but for some reason the compiler keeps expecting a float for reasons I can't comprehend; especially considering that the code is actually example code from the llvm ocaml tutorial.
I've tried type casting both variables to ints, and just generally fiddling around with the syntax, but the function is so simple I can't figure out what's actually wrong. I know that one can, for a normal function, specify the type with let: type->type but I don't know how that would work with a parser function.
here's the function:
let parse_binary_precedence = parser
| [< 'Token.Number n >] -> int_of_float n
| [< >] -> 30
in
Here's the greater context of where it is used in case that is also part of the problem (although, I don't think it is):
let parse_binary_precedence = parser
| [< 'Token.Number n >] -> (int_of_float n)
| [< >] -> 30
in
parser
| [< (prefix, kind)=parse_operator;
'Token.Kwd op ?? "expected operator";
prec = parse_binary_precedence;
'Token.Kwd '(' ?? "expected '(' in operator prototype";
args = parse_first_arg [];
'Token.Kwd ')' ?? "expected ')' in operator protoype" >] ->
I currently am just getting the standard
File "parser.ml", line 108, characters 49-50:
Error: This expression has type int but an expression was expected of type
float
type error.
Does anybody know why this is expecting a float? How do I make the function expect an int?
EDIT:
I realize now that i've phrased it poorly now, but I realize that the context of the program is what decides the type of the function, I was asking about what within the program was making it assume that the function returned an int. It seems that it is outside of the scope of what i posted, so I'm updating my post with the code relating to everything shown.
Here is the full set of the relevant code. apologies for not including this to begin with.
token.ml:
type token =
(*primary*)
| Ident of string | Number of int
(*control*)
| If | Else | For
(*user ops*)
| Binary | Unary
parser.ml
let parse_prototype =
let rec parse_args accumulator = parser
| [< 'Token.Kwd ','; 'Token.Ident id; e=parse_args (id :: accumulator) >] -> e
| [< >] -> accumulator
in
let parse_first_arg accumulator = parser
| [< 'Token.Ident id; e=parse_args (id::accumulator) >] -> e
| [< >] -> accumulator
in
let parse_operator = parser
| [< 'Token.Binary >] -> "binary", 2
| [< 'Token.Unary >] -> "unary", 1
in
let parse_binary_precedence = parser
| [< 'Token.Number n >] -> (int_of_float n) (*line 108*)
| [< >] -> 30
in
parser
| [< 'Token.Ident id;
'Token.Kwd '(' ?? "expected '(' in prototype";
args= parse_first_arg [];
'Token.Kwd ')' ?? "expected closing ')' in prototype " >] ->
Ast.Prototype (id, Array.of_list (List.rev args))
| [< (prefix, kind)=parse_operator;
'Token.Kwd op ?? "expected operator";
prec = parse_binary_precedence;
'Token.Kwd '(' ?? "expected '(' in operator prototype";
args = parse_first_arg [];
'Token.Kwd ')' ?? "expected ')' in operator protoype" >] ->
let name = prefix ^ (String.make 1 op) in
let args = Array.of_list (List.rev args) in
(*verify right number of args for op*)
if Array.length args != kind then
raise (Stream.Error "invalid number of operands in op def")
else
if kind == 1 then
Ast.Prototype (name, args)
else
Ast.BinOpPrototype (name, args, prec)
| [< >] ->
raise (Stream.Error "expected func name in prototype")
ast.ml
type proto =
| Prototype of string * string array
| BinOpPrototype of string * string array * int
(int_of_float n) (*line 108*)is indeed line 108, then the only explanation is that in yourtoken.mltheNumberconstructor is defined asNumber of intnotNumber of float, thereforenis having type int, and you can't applyint_of_float nto a value of typeint. Just removeint_of_floatand leavenintact, or fix theToken.Numberconstructor` - ivg