Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file asl_ast.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567(* generated by Ott 0.30 from: asl.ott *)typeid=stringtypetypeid=stringtypeintLit=stringtypebitsLit=stringtypemaskLit=stringtyperealLit=stringtypehexLit=stringtypei=int(** Location tracking *)typel=|Unknown|Intofstring*loption|Generatedofl|RangeofLexing.position*Lexing.positiontype'aannot=l*'aletpp_lexing_position(p:Lexing.position):string=Printf.sprintf"file \"%s\" line %d char %d"p.Lexing.pos_fnamep.Lexing.pos_lnum(p.Lexing.pos_cnum-p.Lexing.pos_bol)letrecpp_loc(l:l):string=matchlwith|Unknown->"no location information available"|Generatedl->Printf.sprintf"Generated: %s"(pp_locl)|Range(p1,p2)->ifString.equalp1.Lexing.pos_fnamep2.Lexing.pos_fnamethenbeginifp1.Lexing.pos_lnum=p2.Lexing.pos_lnumthenPrintf.sprintf"file \"%s\" line %d char %d - %d"p1.Lexing.pos_fnamep1.Lexing.pos_lnum(p1.Lexing.pos_cnum-p1.Lexing.pos_bol)(p2.Lexing.pos_cnum-p2.Lexing.pos_bol)elsePrintf.sprintf"file \"%s\" line %d char %d - line %d char %d"p1.Lexing.pos_fnamep1.Lexing.pos_lnum(p1.Lexing.pos_cnum-p1.Lexing.pos_bol)p2.Lexing.pos_lnum(p2.Lexing.pos_cnum-p2.Lexing.pos_bol)endelsebeginPrintf.sprintf"file \"%s\" line %d char %d - file \"%s\" line %d char %d"p1.Lexing.pos_fnamep1.Lexing.pos_lnum(p1.Lexing.pos_cnum-p1.Lexing.pos_bol)p2.Lexing.pos_fnamep2.Lexing.pos_lnum(p2.Lexing.pos_cnum-p2.Lexing.pos_bol)end|Int(s,lo)->Printf.sprintf"%s %s"s(matchlowithSomel->pp_locl|None->"none")(** Parsing exceptions (1/2) *)exceptionParse_error_locnofl*string(** Identifiers used for variable names, function names, etc.
There are two kinds of identifier:
- Ident is generated by the parser - it is just a string
- FIdent is generated by the disambiguation part of the typechecker and
includes a unique label to distinguish different entities with
the same name in the source syntax.
*)typeident=|Identofstring|FIdentofstring*intletpprint_ident(x:ident):string=(matchxwith|Ident(s)->s|FIdent(s,t)->s^"."^string_of_intt)letaddTag(x:ident)(tag:int):ident=(matchxwith|Ident(s)->FIdent(s,tag)|FIdent(_,_)->failwith"addTag")letstripTag(x:ident):ident=(matchxwith|Ident(s)|FIdent(s,_)->Ident(s))letname_of_FIdent(x:ident):string=(matchxwith|Ident(_)->failwith"name_of_FIdent"|FIdent(s,_)->s)letaddQualifier(p:string)(x:ident):ident=(matchxwith|Ident(s)->Ident(p^"."^s)|FIdent(_,_)->failwith"addQualifier")letaddPrefix(p:string)(x:ident):ident=(matchxwith|Ident(q)->Ident(p^"."^q)|FIdent(_,_)->failwith"addQualifier")letaddSuffix(x:ident)(s:string):ident=(matchxwith|Ident(p)->Ident(p^"."^s)|FIdent(_,_)->failwith"addQualifier")letgenericTyvar(i:int):ident=letv="$"^string_of_intiinIdentvletisGenericTyvar(x:ident):bool=(matchxwith|Ident(s)->s.[0]='$'|FIdent(_,_)->failwith"addQualifier")moduleId=structtypet=identletcompare(x:ident)(y:ident):int=(match(x,y)with|(Identx,Identy)->String.comparexy|(FIdent(x,i),FIdent(y,j))->letcx=String.comparexyinifcx<>0thencxelsecompareij|(Ident_,FIdent(_,_))->-1|(FIdent(_,_),Ident_)->1)end(** Type Identifiers *)moduleStringSet=Set.Make(String)lettypeIdents=refStringSet.emptyletaddTypeIdent(x:ident):unit=begin(* ignore (Printf.printf "New type identifier %s\n" (pprint_ident x)); *)typeIdents:=StringSet.add(pprint_identx)!typeIdentsendletisTypeIdent(x:string):bool=StringSet.memx!typeIdentstypebinop=Binop_Eq|Binop_NtEq|Binop_Gt|Binop_GtEq|Binop_Lt|Binop_LtEq|Binop_Plus|Binop_Minus|Binop_Multiply|Binop_Divide|Binop_Power|Binop_Quot|Binop_Rem|Binop_Div|Binop_Mod|Binop_ShiftL|Binop_ShiftR|Binop_BoolAnd|Binop_BoolOr|Binop_BoolIff|Binop_BoolImplies|Binop_BitOr|Binop_BitEor|Binop_BitAnd|Binop_Append|Binop_Concat|Binop_DUMMYtypeunop=Unop_Negate|Unop_BoolNot|Unop_BitsNottypeixtype=Index_Enumofident|Index_Rangeofexpr*exprandty=Type_Constructorofident|Type_Bitsofexpr|Type_Appofident*(expr)list|Type_OfExprofexpr|Type_RegisterofintLit*(slicelist*ident)list|Type_Arrayofixtype*ty|Type_Tupleof(ty)listandpattern=Pat_LitIntofintLit|Pat_LitHexofhexLit|Pat_LitBitsofbitsLit|Pat_LitMaskofmaskLit|Pat_Constofident|Pat_Wildcard|Pat_Tupleof(pattern)list|Pat_Setof(pattern)list|Pat_Rangeofexpr*expr|Pat_Singleofexprandexpr=Expr_Ifofexpr*expr*(e_elsif)list*expr|Expr_Binopofexpr*binop*expr|Expr_Unopofunop*expr(* unary operator *)|Expr_Fieldofexpr*ident(* field selection *)|Expr_Fieldsofexpr*(ident)list(* multiple field selection *)|Expr_Slicesofexpr*(slice)list(* bitslice *)|Expr_Inofexpr*pattern(* pattern match *)|Expr_Varofident|Expr_Parensofexpr|Expr_Tupleof(expr)list(* tuple *)|Expr_Unknownofty|Expr_ImpDefofty*stringoption|Expr_TApplyofident*(expr)list*(expr)list(* spice for desugaring function call with explicit type parameters *)|Expr_Arrayofexpr*expr(* spice for desugaring array accesses *)|Expr_LitIntofintLit(* literal decimal integer *)|Expr_LitHexofhexLit(* literal hexadecimal integer *)|Expr_LitRealofrealLit(* literal real *)|Expr_LitBitsofbitsLit(* literal bitvector *)|Expr_LitMaskofmaskLit(* literal bitmask *)|Expr_LitStringofstring(* literal string *)ande_elsif=E_Elsif_Condofexpr*exprandslice=Slice_Singleofexpr|Slice_HiLoofexpr*expr|Slice_LoWdofexpr*exprtypedirection=Direction_Up|Direction_Downtypelexpr=LExpr_Wildcard|LExpr_Varofident|LExpr_Fieldoflexpr*ident|LExpr_Fieldsoflexpr*(ident)list|LExpr_Slicesoflexpr*(slice)list|LExpr_BitTupleof(lexpr)list|LExpr_Tupleof(lexpr)list|LExpr_Arrayoflexpr*expr(* spice for desugaring array assignment *)|LExpr_Writeofident*(expr)list*(expr)list(* spice for desugaring setter procedure call *)|LExpr_ReadWriteofident*ident*(expr)list*(expr)list(* spice for desugaring read-modify-write function+procedure call *)typestmt=Stmt_VarDeclsNoInitofty*(ident)list*l|Stmt_VarDeclofty*ident*expr*l|Stmt_ConstDeclofty*ident*expr*l|Stmt_Assignoflexpr*expr*l|Stmt_FunReturnofexpr*l(* function return *)|Stmt_ProcReturnofl(* procedure return *)|Stmt_Assertofexpr*l(* assertion *)|Stmt_Unpredofl(* underspecified behaviour *)|Stmt_ConstrainedUnpredofl|Stmt_ImpDefofident*l(* underspecified behaviour *)|Stmt_Undefinedofl|Stmt_ExceptionTakenofl|Stmt_Dep_Unpredofl(* DEPRECATED *)|Stmt_Dep_ImpDefofstring*l(* DEPRECATED *)|Stmt_Dep_Undefinedofl(* DEPRECATED *)|Stmt_Seeofexpr*l|Stmt_Throwofident*l|Stmt_DecodeExecuteofident*expr*l(* decode and execute instruction *)|Stmt_TCallofident*(expr)list*(expr)list*l(* spice for procedure call with explicit type parameters *)|Stmt_Ifofexpr*stmtlist*(s_elsif)list*stmtlist*l|Stmt_Caseofexpr*(alt)list*(stmtlist)option*l|Stmt_Forofident*expr*direction*expr*stmtlist*l|Stmt_Whileofexpr*stmtlist*l|Stmt_Repeatofstmtlist*expr*l|Stmt_Tryofstmtlist*ident*(catcher)list*(stmtlist)option*lands_elsif=S_Elsif_Condofexpr*stmtlistandalt=Alt_Altof(pattern)list*exproption*stmtlistandcatcher=Catcher_Guardedofexpr*stmtlisttypeinstr_field=IField_Fieldofident*int*inttypeopcode_value=Opcode_BitsofbitsLit|Opcode_MaskofmaskLittypedecode_pattern=DecoderPattern_BitsofbitsLit|DecoderPattern_MaskofmaskLit|DecoderPattern_Wildcardofident(* todo: wildcard should be underscore *)|DecoderPattern_Notofdecode_patterntypedecode_slice=DecoderSlice_Sliceofint*int|DecoderSlice_FieldNameofident|DecoderSlice_Concatof(ident)listtypesformal=Formal_Inofty*ident|Formal_InOutofty*identtypeencoding=Encoding_Blockofident*ident*(instr_field)list*opcode_value*expr*((int*bitsLit))list*stmtlist*ltypedecode_case=DecoderCase_Caseof(decode_slice)list*(decode_alt)list*landdecode_alt=DecoderAlt_Altof(decode_pattern)list*decode_bodyanddecode_body=DecoderBody_UNPREDofl|DecoderBody_UNALLOCofl|DecoderBody_NOPofl|DecoderBody_Encodingofident*l|DecoderBody_Decoderof(instr_field)list*decode_case*ltypemapfield=MapField_Fieldofident*patterntypedeclaration=Decl_BuiltinTypeofident*l|Decl_Forwardofident*l|Decl_Recordofident*(ty*ident)list*l|Decl_Typedefofident*ty*l|Decl_Enumofident*(ident)list*l|Decl_Varofty*ident*l|Decl_Constofty*ident*expr*l|Decl_BuiltinFunctionofty*ident*(ty*ident)list*l|Decl_FunTypeofty*ident*(ty*ident)list*l|Decl_FunDefnofty*ident*(ty*ident)list*stmtlist*l|Decl_ProcTypeofident*(ty*ident)list*l|Decl_ProcDefnofident*(ty*ident)list*stmtlist*l|Decl_VarGetterTypeofty*ident*l|Decl_VarGetterDefnofty*ident*stmtlist*l|Decl_ArrayGetterTypeofty*ident*(ty*ident)list*l|Decl_ArrayGetterDefnofty*ident*(ty*ident)list*stmtlist*l|Decl_VarSetterTypeofident*ty*ident*l|Decl_VarSetterDefnofident*ty*ident*stmtlist*l|Decl_ArraySetterTypeofident*(sformal)list*ty*ident*l|Decl_ArraySetterDefnofident*(sformal)list*ty*ident*stmtlist*l|Decl_InstructionDefnofident*(encoding)list*(stmtlist)option*bool*stmtlist*l|Decl_DecoderDefnofident*decode_case*l|Decl_Operator1ofunop*(ident)list*l|Decl_Operator2ofbinop*(ident)list*l|Decl_NewEventDefnofident*(ty*ident)list*l|Decl_EventClauseofident*stmtlist*l|Decl_NewMapDefnofty*ident*(ty*ident)list*stmtlist*l|Decl_MapClauseofident*(mapfield)list*exproption*stmtlist*l|Decl_Configofty*ident*expr*ltypeleadingblank=LeadingBlank|LeadingNothingtypefactor=Factor_BinOpofbinop*exprtypeimpdef_command=CLI_Impdefofstring*exprletassociativeOperators:binoplist=[Binop_Plus;Binop_Multiply;Binop_BoolAnd;Binop_BoolOr;Binop_BitOr;Binop_BitEor;Binop_BitAnd;Binop_Concat;Binop_Append](* boolean operators bind least tightly *)letbooleanOperators:binoplist=[Binop_BoolAnd;Binop_BoolOr;Binop_BoolIff;Binop_BoolImplies](* comparision operators bind less tightly than arithmetic, etc. *)letcomparisionOperators:binoplist=[Binop_Eq;Binop_NtEq;Binop_Gt;Binop_GtEq;Binop_Lt;Binop_LtEq](* arithmetic and similar operations bind more tightly than comparisions and &&/|| *)letmiscOperators:binoplist=[Binop_Plus;Binop_Minus;Binop_Multiply;Binop_Divide;Binop_Power;Binop_Quot;Binop_Rem;Binop_Div;Binop_Mod;Binop_ShiftL;Binop_ShiftR;Binop_BitOr;Binop_BitEor;Binop_BitAnd;Binop_Concat]letisAssociative(x:binop):bool=List.memxassociativeOperatorsletisBoolean(x:binop):bool=List.memxbooleanOperatorsletisComparision(x:binop):bool=List.memxcomparisionOperatorsletisMisc(x:binop):bool=List.memxmiscOperators(* Is operator x higher priority than y
* (Binop_DUMMY acts as the lowest priority operation - see below)
*)lethigherPriorityThan(x:binop)(y:binop):booloption=ify=Binop_DUMMYthenSome(true)elseifx=Binop_Power&&y=Binop_MultiplythenSome(true)elseifx=Binop_Power&&y=Binop_DividethenSome(true)elseifx=Binop_Power&&y=Binop_PlusthenSome(true)elseifx=Binop_Power&&y=Binop_MinusthenSome(true)elseifx=Binop_Multiply&&y=Binop_PlusthenSome(true)elseifx=Binop_Multiply&&y=Binop_MinusthenSome(true)elseifx=Binop_Plus&&y=Binop_MinusthenSome(true)elseifisMiscx&&isBooleanythenSome(true)elseifisMiscx&&isComparisionythenSome(true)elseifisComparisionx&&isBooleanythenSome(true)elseifx=Binop_DUMMYthenSome(false)elseify=Binop_Power&&x=Binop_MultiplythenSome(false)elseify=Binop_Power&&x=Binop_DividethenSome(false)elseify=Binop_Power&&x=Binop_PlusthenSome(false)elseify=Binop_Power&&x=Binop_MinusthenSome(false)elseify=Binop_Multiply&&x=Binop_PlusthenSome(false)elseify=Binop_Multiply&&x=Binop_MinusthenSome(false)elseifisMiscy&&isBooleanxthenSome(false)elseifisMiscy&&isComparisionxthenSome(false)elseifisComparisiony&&isBooleanxthenSome(false)(* The following rules might be a mistake - though they do seem
* to match common usage.
*)elseifx=Binop_Minus&&y=Binop_PlusthenSome(true)elseifx=Binop_Minus&&y=Binop_MinusthenSome(true)elseNone(** Parsing exceptions (2/2) *)exceptionPrecedenceErrorofl*binop*binop(* Support function for parsing expression trees of the form
*
* ... op x op_1 y_1 op_2 y_2 ... op_n y_n
*
* Consumes input until it finds an operator y_i of lower precedence
* than op returning
*
* 1) an expression representing "x op_1 ... y_i-1"
* 2) the remainder if the input "op_i y_i ... op_n y_n"
*
* As in Dijkstra's "Shunting Yard" algorithm, we work left to right across
* the expression comparing the next two operators:
* - op1 > op2 => (x op1 y1) op2 ...
* - op1 < op2 => x op1 (y1 op2 ...) ...
* - op1 = op2 => (x op1 y1) op2 ... if op1 is associative
* - _ => error
*)letrecbuildExpr(op:binop)(x:expr)(ys:factorlist)(loc:l):(expr*factorlist)=(matchyswith|[]->(x,[])|(Factor_BinOp(op1,y1)::ys1)->(matchhigherPriorityThanopop1with|Some(false)->(matchys1with|(Factor_BinOp(op2,_)::_)->(matchhigherPriorityThanop1op2with|Some(true)->buildExprop(Expr_Binop(x,op1,y1))ys1loc|Some(false)->let(r,rs)=buildExprop1y1ys1locinbuildExprop(Expr_Binop(x,op1,r))rsloc|None->ifop1=op2&&isAssociative(op1)thenbuildExprop(Expr_Binop(x,op1,y1))ys1locelseraise(PrecedenceError(loc,op1,op2)))|[]->(Expr_Binop(x,op1,y1),[]))|_->(x,ys)))(* Construct an expression tree based on precedence rules
*
* Given parser output of the form x op_1 y_1 op_2 y_2 ...op_n y_n,
* construct a tree based on the relative priorities of op1, ... opn.
* If any adjacent operators op_i, op_i+1 are unordered, report
* a parsing ambiguity.
*
* We use a recursive variant on Dijkstra's Shunting Yard algorithm to
* parse a list of operator-expression pairs into an expression tree
* based on operator precedences
* All operators are treated as left-associative
*)letbuildExpression(x:expr)(fs:factorlist)(loc:l):expr=(matchbuildExprBinop_DUMMYxfslocwith|(e,[])->e|(_,_)->raise(Parse_error_locn(loc,"Impossible: unable to resolve precedence")))