Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file operator.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175openFmlibopenCommontypeassoc=|Left|Right|Notypet=int*assoc(* Invariant: The same precedence leads to the same assoc
i.e. the precedence is the key to the operator group which
are considered equivalent. *)letwhere=(10,Left)letcomma=(20,Right)letassign=(30,Right)letcolon=(40,Right)letarrow=(50,Right)letand_or=(70,Left)letnegation=(80,Right)letpush_arg=(100,Left)letpull_arg=(120,Right)letrelation=(140,No)letaddition_right=(159,Right)letaddition=(160,Left)letmultiplication=(180,Left)letexponentiation=(200,Right)letunknown=(300,Left)letapplication=(400,Left)(* Precedences:
expression parse requirement
--------------------------------------------------------------
\x := exp, 3 (\x := exp), 3 comma < assign
\x := exp: T \x := (exp: T) assign < colon
exp: A -> B exp: (A -> B) colon < arrow
all p q: p => q all p q: (p => q) colon < arrow
\x y := x => y \x y := (x => y) assign < arrow
Therefore:
comma < assign < colon < arrow
*)letmap:(int*assoc)String_map.t=letopenString_mapinempty|>add","comma|>add"->"arrow|>add"=>"arrow|>add":="assign|>add":"colon|>add"and"and_or|>add"or"and_or|>add"not"negation|>add"|>"push_arg|>add"<|"pull_arg|>add"="relation|>add"/="relation|>add"<"relation|>add">"relation|>add"<="relation|>add">="relation|>add"+:"addition_right|>add"+"addition|>add"-"addition|>add"*"multiplication|>add"mod"multiplication|>add"/"multiplication|>add"^"exponentiationletis_unary(op:string):bool=op="not"||op="-"letis_binary(op:string):bool=op<>"not"letis_keyword_operator(op:string):bool=op="and"||op="or"||op="not"||op="mod"letof_string(op:string):t=matchString_map.maybe_findopmapwith|None->unknown|Somed->dletcompare((prec1,_):t)((prec2,_):t):int=Stdlib.compareprec1prec2letprecedence=fstletassociativity=sndletis_left_leaning((prec1,assoc):t)((prec2,_):t):bool=prec1>prec2||(prec1=prec2&&assoc=Left)letis_right_leaning((prec1,assoc):t)((prec2,_):t):bool=prec1<prec2||(prec1=prec2&&assoc=Right)letneeds_parens(lower:toption)(is_left:bool)(upper:t):bool=matchlowerwith|None->false|Some(low_prec,low_assoc)->letprec,assoc=upperinassert(prec<>low_prec||low_assoc=assoc);prec>low_prec||(prec=low_prec(* because of the invariant lower and upper have the
same associativity. *)&&(matchassocwith|No->true|Left->notis_left|Right->is_left))